diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-04-08 00:23:17 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-04-08 00:23:17 +0000 |
commit | 56c7ac5035e4cd1f1fc0a287c3caa13401c5eb79 (patch) | |
tree | 3ef1d1fe5119557d99bb8f5e136d6c7e4c99d847 /gcc/expr.c | |
parent | 7445ae81814148555bebbc0604fc0ee9c311a80c (diff) | |
download | gcc-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.c | 27 |
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': |