diff options
author | Martin Jambor <mjambor@suse.cz> | 2010-11-02 16:22:52 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2010-11-02 16:22:52 +0100 |
commit | 4c2030661e0a9bce68786f72e4d0da1be5caf3a5 (patch) | |
tree | 6b301cc7b78e84ad831cce83f66b80281b61bc17 | |
parent | 7a2b3e20767d3d11776e4c5bbb12d751e7ba748f (diff) | |
download | gcc-4c2030661e0a9bce68786f72e4d0da1be5caf3a5.zip gcc-4c2030661e0a9bce68786f72e4d0da1be5caf3a5.tar.gz gcc-4c2030661e0a9bce68786f72e4d0da1be5caf3a5.tar.bz2 |
re PR middle-end/46120 (g++.dg/ipa/ivinline-?.C)
2010-11-02 Martin Jambor <mjambor@suse.cz>
PR middle-end/46120
* tree.c (get_binfo_at_offset): Bail out on artificial
fields. Identify primary bases according to their offsets.
* testsuite/g++.dg/ipa/ivinline-9.C: New test.
From-SVN: r166192
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/ivinline-9.C | 93 | ||||
-rw-r--r-- | gcc/tree.c | 40 |
4 files changed, 125 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c946683..a347b05 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2010-11-02 Martin Jambor <mjambor@suse.cz> + PR middle-end/46120 + * tree.c (get_binfo_at_offset): Bail out on artificial + fields. Identify primary bases according to their offsets. + +2010-11-02 Martin Jambor <mjambor@suse.cz> + PR tree-optimization/45875 * gimple-fold.c (get_first_base_binfo_with_virtuals): Removed. (gimple_get_relevant_ref_binfo): Detect primary bases according to diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aa80464..471b009 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2010-11-02 Martin Jambor <mjambor@suse.cz> + PR middle-end/46120 + * g++.dg/ipa/ivinline-9.C: New test. + +2010-11-02 Martin Jambor <mjambor@suse.cz> + PR tree-optimization/45875 * g++.dg/torture/pr45875.C: New test. diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-9.C b/gcc/testsuite/g++.dg/ipa/ivinline-9.C new file mode 100644 index 0000000..429b6f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-9.C @@ -0,0 +1,93 @@ +/* Verify that simple virtual calls are inlined even without early + inlining, even when a typecast to an ancestor is involved along the + way and that ancestor itself has an ancestor wich is not the + primary base class. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +extern "C" void abort (void); + +class Distraction +{ +public: + float f; + double d; + Distraction () + { + f = 8.3; + d = 10.2; + } + virtual float bar (float z); +}; + +class A +{ +public: + int data; + virtual int foo (int i); +}; +/* +class D2 +{ +public: + virtual float baz (float z) + { + abort(); + } +}; +*/ +class A2 : public Distraction, public A +{ + int i2; +}; + +class B : public A2 +{ +public: + virtual int foo (int i); +}; + +float Distraction::bar (float z) +{ + f += z; + return f/2; +} + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +static int middleman_1 (class A *obj, int i) +{ + return obj->foo (i); +} + +static int middleman_2 (class B *obj, int i) +{ + return middleman_1 (obj, i); +} + +int main (int argc, char *argv[]) +{ + class B b; + int i; + + for (i = 0; i < get_input (); i++) + if (middleman_2 (&b, get_input ()) != 3) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ @@ -10906,16 +10906,17 @@ lhd_gcc_personality (void) tree get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type) { - tree type; + tree type = TREE_TYPE (binfo); - type = TREE_TYPE (binfo); - while (offset > 0) + while (true) { - tree base_binfo, found_binfo; HOST_WIDE_INT pos, size; tree fld; int i; + gcc_checking_assert (offset >= 0); + if (type == expected_type) + return binfo; if (TREE_CODE (type) != RECORD_TYPE) return NULL_TREE; @@ -10929,27 +10930,28 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type) if (pos <= offset && (pos + size) > offset) break; } - if (!fld) + if (!fld || !DECL_ARTIFICIAL (fld)) return NULL_TREE; - found_binfo = NULL_TREE; - for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - if (TREE_TYPE (base_binfo) == TREE_TYPE (fld)) - { - found_binfo = base_binfo; - break; - } - - if (!found_binfo) - return NULL_TREE; + /* Offset 0 indicates the primary base, whose vtable contents are + represented in the binfo for the derived class. */ + if (offset != 0) + { + tree base_binfo, found_binfo = NULL_TREE; + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + if (TREE_TYPE (base_binfo) == TREE_TYPE (fld)) + { + found_binfo = base_binfo; + break; + } + if (!found_binfo) + return NULL_TREE; + binfo = found_binfo; + } type = TREE_TYPE (fld); - binfo = found_binfo; offset -= pos; } - if (type != expected_type) - return NULL_TREE; - return binfo; } /* Returns true if X is a typedef decl. */ |