diff options
author | Richard Biener <rguenther@suse.de> | 2019-03-14 09:24:21 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-03-14 09:24:21 +0000 |
commit | ea9d9d749c3203e9fb01267fabecad93b7f1c06c (patch) | |
tree | 8ae68e5a87de5cfccd05b9746dad560357dfe764 /gcc | |
parent | f54e63dfa34c4c9922a4cb35d2f8c28c92135b8c (diff) | |
download | gcc-ea9d9d749c3203e9fb01267fabecad93b7f1c06c.zip gcc-ea9d9d749c3203e9fb01267fabecad93b7f1c06c.tar.gz gcc-ea9d9d749c3203e9fb01267fabecad93b7f1c06c.tar.bz2 |
re PR c++/89698 (Run-time error due to optimization of field access after cast at -Os/-O2 and higher)
2019-03-14 Richard Biener <rguenther@suse.de>
PR middle-end/89698
* fold-const.c (operand_equal_p): For INDIRECT_REF check
that the access types are similar.
* g++.dg/torture/pr89698.C: New testcase.
From-SVN: r269677
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr89698.C | 28 |
4 files changed, 49 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c3a6b9..2d2495c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-03-14 Richard Biener <rguenther@suse.de> + + PR middle-end/89698 + * fold-const.c (operand_equal_p): For INDIRECT_REF check + that the access types are similar. + 2019-03-14 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/89703 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 571566a..dbc9679 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3220,10 +3220,16 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) switch (TREE_CODE (arg0)) { case INDIRECT_REF: - if (!(flags & OEP_ADDRESS_OF) - && (TYPE_ALIGN (TREE_TYPE (arg0)) - != TYPE_ALIGN (TREE_TYPE (arg1)))) - return 0; + if (!(flags & OEP_ADDRESS_OF)) + { + if (TYPE_ALIGN (TREE_TYPE (arg0)) + != TYPE_ALIGN (TREE_TYPE (arg1))) + return 0; + /* Verify that the access types are compatible. */ + if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0)) + != TYPE_MAIN_VARIANT (TREE_TYPE (arg1))) + return 0; + } flags &= ~OEP_ADDRESS_OF; return OP_SAME (0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index db45dc4..b0f9efa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-03-14 Richard Biener <rguenther@suse.de> + + PR middle-end/89698 + * g++.dg/torture/pr89698.C: New testcase. + 2019-03-14 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/89703 diff --git a/gcc/testsuite/g++.dg/torture/pr89698.C b/gcc/testsuite/g++.dg/torture/pr89698.C new file mode 100644 index 0000000..fbeb797 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr89698.C @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +extern "C" void abort (void); + +class A { + virtual void f(){}; +public: + int x; + A(int in): x(in) {}; +}; + +class B: public A { +public: + int y; + B(int in):A(in-1), y(in) {}; +}; + +int test(void) +{ + int res; + B b(2); + A* bp = &b; + void* vp = dynamic_cast<void*>(bp); + if (((A*)vp)->x == 1 && ((B*)vp)->y == 2) + return 1; + return 0; +} +int main() { if (test() != 1) abort (); return 0; } |