From 86d2a13ec923d90b00bea6df41d48c39a226a6cf Mon Sep 17 00:00:00 2001 From: jamborm Date: Fri, 13 Apr 2012 17:57:21 +0000 Subject: [PATCH] 2012-04-13 Martin Jambor PR middle-end/52939 * gimple-fold.c (gimple_get_virt_method_for_binfo): Bail out if fold_ctor_reference returns a zero constant. * testsuite/g++.dg/ipa/pr52939.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186428 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++ gcc/gimple-fold.c | 2 +- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/ipa/pr52939.C | 58 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr52939.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3a691e..e04d1be 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-04-13 Martin Jambor + + PR middle-end/52939 + * gimple-fold.c (gimple_get_virt_method_for_binfo): Bail out if + fold_ctor_reference returns a zero constant. + 2012-04-13 Enkovich Ilya * config.gcc: Add i386/gnu-user-common.h before all diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 0ea5d56..049da57 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -3087,7 +3087,7 @@ gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo) offset += token * size; fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), DECL_INITIAL (v), offset, size); - if (!fn) + if (!fn || integer_zerop (fn)) return NULL_TREE; gcc_assert (TREE_CODE (fn) == ADDR_EXPR || TREE_CODE (fn) == FDESC_EXPR); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b39e623..556d2f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-04-13 Martin Jambor + + PR middle-end/52939 + * g++.dg/ipa/pr52939.C: New test. + 2012-04-13 Tom de Vries * gcc.dg/pr52734.c: New test. diff --git a/gcc/testsuite/g++.dg/ipa/pr52939.C b/gcc/testsuite/g++.dg/ipa/pr52939.C new file mode 100644 index 0000000..e120827 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr52939.C @@ -0,0 +1,58 @@ +/* Verify that we do not ICE on invalid devirtualizations (which might + be OK at run-time because never executed). */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int foo (int i); + virtual int bar (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int B::bar (int i) +{ + return i + 3; +} + +static int middleman (class A *obj, int i) +{ + class B *b = (class B *) obj; + + if (i != 1) + return b->bar (i); + else + return i; +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class A o; + if (middleman (&o, get_input ()) != 1) + abort (); + return 0; +} -- 2.7.4