summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-08 00:23:17 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-08 00:23:17 +0000
commit56c7ac5035e4cd1f1fc0a287c3caa13401c5eb79 (patch)
tree3ef1d1fe5119557d99bb8f5e136d6c7e4c99d847 /gcc/expr.c
parent7445ae81814148555bebbc0604fc0ee9c311a80c (diff)
downloadgcc-56c7ac5035e4cd1f1fc0a287c3caa13401c5eb79.tar.gz
PR c/9516
* expr.c (safe_from_p): Rearrange to avoid deep recursion in favour of looping and tail recursion for TREE_LIST and binops. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65363 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index e9d0ee52c92..075de49f819 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6093,22 +6093,31 @@ safe_from_p (x, exp, top_p)
case 'x':
if (TREE_CODE (exp) == TREE_LIST)
- return ((TREE_VALUE (exp) == 0
- || safe_from_p (x, TREE_VALUE (exp), 0))
- && (TREE_CHAIN (exp) == 0
- || safe_from_p (x, TREE_CHAIN (exp), 0)));
+ {
+ while (1)
+ {
+ if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
+ return 0;
+ exp = TREE_CHAIN (exp);
+ if (!exp)
+ return 1;
+ if (TREE_CODE (exp) != TREE_LIST)
+ return safe_from_p (x, exp, 0);
+ }
+ }
else if (TREE_CODE (exp) == ERROR_MARK)
return 1; /* An already-visited SAVE_EXPR? */
else
return 0;
- case '1':
- return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
-
case '2':
case '<':
- return (safe_from_p (x, TREE_OPERAND (exp, 0), 0)
- && safe_from_p (x, TREE_OPERAND (exp, 1), 0));
+ if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
+ return 0;
+ /* FALLTHRU */
+
+ case '1':
+ return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
case 'e':
case 'r':