diff options
author | Andrew Hsieh <andrewhsieh@google.com> | 2013-06-20 23:01:37 -0700 |
---|---|---|
committer | Andrew Hsieh <andrewhsieh@google.com> | 2013-06-20 23:01:37 -0700 |
commit | 8716d1d7b8498baa4c48fdc04d8ebabf4baa4352 (patch) | |
tree | 694ac6cd3a989b12a49b7d17940a0c83fa53da15 /gcc-4.7 | |
parent | 01b34967a57ca33621130d36e007214b93bdfeaa (diff) | |
download | toolchain_gcc-8716d1d7b8498baa4c48fdc04d8ebabf4baa4352.tar.gz toolchain_gcc-8716d1d7b8498baa4c48fdc04d8ebabf4baa4352.tar.bz2 toolchain_gcc-8716d1d7b8498baa4c48fdc04d8ebabf4baa4352.zip |
Fix segfault on const init to object address
See b.android.com/56508 and
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54986
Backport the fix in r193189
2012-11-05 Eric Botcazou <ebotcazou@adacore.com>
PR tree-optimization/54986
* gimple-fold.c (canonicalize_constructor_val): Strip again all no-op
conversions on entry but add them back on exit if needed.
Change-Id: Ibedd829e7780ff78e7b90219ebb7c425f7d2fc01
Diffstat (limited to 'gcc-4.7')
-rw-r--r-- | gcc-4.7/ChangeLog.backported | 7 | ||||
-rw-r--r-- | gcc-4.7/gcc/gimple-fold.c | 9 | ||||
-rw-r--r-- | gcc-4.7/gcc/testsuite/g++.dg/torture/20121105-1.C | 42 |
3 files changed, 56 insertions, 2 deletions
diff --git a/gcc-4.7/ChangeLog.backported b/gcc-4.7/ChangeLog.backported index b6519d034..442d9436d 100644 --- a/gcc-4.7/ChangeLog.backported +++ b/gcc-4.7/ChangeLog.backported @@ -1,3 +1,10 @@ +http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193189 +2012-11-05 Eric Botcazou <ebotcazou@adacore.com> + + PR tree-optimization/54986 + * gimple-fold.c (canonicalize_constructor_val): Strip again all no-op + conversions on entry but add them back on exit if needed. + http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191571 2012-09-17 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc-4.7/gcc/gimple-fold.c b/gcc-4.7/gcc/gimple-fold.c index 5980854d9..5e4bd23db 100644 --- a/gcc-4.7/gcc/gimple-fold.c +++ b/gcc-4.7/gcc/gimple-fold.c @@ -115,7 +115,8 @@ can_refer_decl_in_current_unit_p (tree decl) tree canonicalize_constructor_val (tree cval) { - STRIP_USELESS_TYPE_CONVERSION (cval); + tree orig_cval = cval; + STRIP_NOPS (cval); if (TREE_CODE (cval) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST) { @@ -146,8 +147,12 @@ canonicalize_constructor_val (tree cval) /* Fixup types in global initializers. */ if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0))) cval = build_fold_addr_expr (TREE_OPERAND (cval, 0)); + + if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval))) + cval = fold_convert (TREE_TYPE (orig_cval), cval); + return cval; } - return cval; + return orig_cval; } /* If SYM is a constant variable with known value, return the value. diff --git a/gcc-4.7/gcc/testsuite/g++.dg/torture/20121105-1.C b/gcc-4.7/gcc/testsuite/g++.dg/torture/20121105-1.C new file mode 100644 index 000000000..03323421a --- /dev/null +++ b/gcc-4.7/gcc/testsuite/g++.dg/torture/20121105-1.C @@ -0,0 +1,42 @@ +// PR tree-optimization/54986 +// Reported by Remi Vanicat <vanicat@debian.org> +// Reduced testcase by Markus Trippelsdorf <markus@trippelsdorf.de> + +struct A; +struct B +{ + int *_ptr; + bool operator==(B *p1) + { + return p1->_ptr; + } +}; +struct C { + A* ref_SYMBptr(); +}; +struct A +{ + B sommet; +}; +typedef C *gen_op_context; +struct D +{ + D(gen_op_context) {} +}; + +D c(0); +const long d = (long)&c; +B *const e = (B *)&d; + +static bool +fn1(C& p1) +{ + return p1.ref_SYMBptr()->sommet == e; +} + +void +fn2() +{ + C b; + fn1(b); +} |