diff options
author | Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de> | 2003-04-08 00:23:17 +0000 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2003-04-07 17:23:17 -0700 |
commit | f8d4be5756bdb8b65f6efb03ea4988deca9270b9 (patch) | |
tree | 3ef1d1fe5119557d99bb8f5e136d6c7e4c99d847 /gcc/expr.c | |
parent | 12031a6266adb08e438317f56b538cc1230de1e9 (diff) | |
download | gcc-f8d4be5756bdb8b65f6efb03ea4988deca9270b9.zip gcc-f8d4be5756bdb8b65f6efb03ea4988deca9270b9.tar.gz gcc-f8d4be5756bdb8b65f6efb03ea4988deca9270b9.tar.bz2 |
re PR c/9516 (Internal error when using a big array)
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.
Co-Authored-By: Richard Henderson <rth@redhat.com>
From-SVN: r65363
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 27 |
1 files changed, 18 insertions, 9 deletions
@@ -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': |