diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2002-10-22 08:56:49 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2002-10-22 08:56:49 +0000 |
commit | 8fe734a3fed78612103e1821e70871b0250c764e (patch) | |
tree | 5e13f69e6f6f8ad205d8b0dc140b72e03198749e | |
parent | 6a0a6ac4c168206195185ec63130685ce7d7d61a (diff) | |
download | gcc-8fe734a3fed78612103e1821e70871b0250c764e.zip gcc-8fe734a3fed78612103e1821e70871b0250c764e.tar.gz gcc-8fe734a3fed78612103e1821e70871b0250c764e.tar.bz2 |
re PR c++/7209 (Faulty array dereferencing)
PR c++/7209
* fold_const.c (fold_binary_op_with_conditional_arg): Always
build compound_expr if we used save_expr.
testsuite:
* g++.dg/expr/cond1.C: New test.
From-SVN: r58405
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/cond1.C | 28 |
4 files changed, 51 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c1656be..2d85ff9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-10-22 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/7209 + * fold_const.c (fold_binary_op_with_conditional_arg): Always + build compound_expr if we used save_expr. + 2002-10-22 Alan Modra <amodra@bigpond.net.au> * output.h (SECTION_NOTYPE): Define. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6da2d91..5f5e25f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4430,6 +4430,7 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p) /* And these are the types of the expressions. */ tree lhs_type = type; tree rhs_type = type; + int save = 0; if (cond_first_p) { @@ -4488,11 +4489,12 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p) if an arm is a COND_EXPR since we get exponential behavior in that case. */ - if (TREE_CODE (arg) != SAVE_EXPR && ! TREE_CONSTANT (arg) - && (*lang_hooks.decls.global_bindings_p) () == 0 - && ((TREE_CODE (arg) != VAR_DECL - && TREE_CODE (arg) != PARM_DECL) - || TREE_SIDE_EFFECTS (arg))) + if (TREE_CODE (arg) == SAVE_EXPR) + save = 1; + else if (!TREE_CONSTANT (arg) + && (*lang_hooks.decls.global_bindings_p) () == 0 + && ((TREE_CODE (arg) != VAR_DECL && TREE_CODE (arg) != PARM_DECL) + || TREE_SIDE_EFFECTS (arg))) { if (TREE_CODE (true_value) != COND_EXPR) lhs = fold (build (lhs_code, lhs_type, *true_lhs, *true_rhs)); @@ -4502,7 +4504,11 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p) if ((lhs == 0 || ! TREE_CONSTANT (lhs)) && (rhs == 0 || !TREE_CONSTANT (rhs))) - arg = save_expr (arg), lhs = rhs = 0; + { + arg = save_expr (arg); + lhs = rhs = 0; + save = 1; + } } if (lhs == 0) @@ -4512,7 +4518,7 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p) test = fold (build (COND_EXPR, type, test, lhs, rhs)); - if (TREE_CODE (arg) == SAVE_EXPR) + if (save) return build (COMPOUND_EXPR, type, convert (void_type_node, arg), strip_compound_expr (test, arg)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 314b222..78e7417 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-10-22 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/expr/cond1.C: New test. + 2002-10-21 Mark Mitchell <mark@codesourcery.com> * g++.dg/abi/vbase13.C: New test. diff --git a/gcc/testsuite/g++.dg/expr/cond1.C b/gcc/testsuite/g++.dg/expr/cond1.C new file mode 100644 index 0000000..8fb3c0f --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/cond1.C @@ -0,0 +1,28 @@ +// { dg-do run } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 17 Oct 2002 <nathan@codesourcery.com> + +// PR 7209. We didn't SAVE_EXPR in the right place + +char a[2][1][16]={ + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}}; + +int f() {return 0;} + +char * Foo (int d) +{ + char *c1; + + c1=a[d==0 ? 0 : 1][f()]; + + return c1; +} + +int main () +{ + if (Foo (0) != (void *)a) + return 1; + return 0; +} |