diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/ipa | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/ipa')
39 files changed, 2333 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/ipa/20090113-1.C b/gcc/testsuite/g++.dg/ipa/20090113-1.C new file mode 100644 index 000000000..3f371257e --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/20090113-1.C @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +struct S1 { + S1() { } +}; + +struct S2 { + int n; + S1* p; + void f() { + p = new S1[n = 1]; + } +}; + +struct S3 { + S2 s2; + void g() { + s2.f(); + } +}; + +void h() { + S3().g(); +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-1.C b/gcc/testsuite/g++.dg/ipa/devirt-1.C new file mode 100644 index 000000000..de0f665c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-1.C @@ -0,0 +1,62 @@ +/* Verify that simple virtual calls are converted to direct calls by ipa-cp. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ + +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); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + if (middleman (&b, get_input ()) != 3) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-2.C b/gcc/testsuite/g++.dg/ipa/devirt-2.C new file mode 100644 index 000000000..d3181e4c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-2.C @@ -0,0 +1,62 @@ +/* Verify that simple virtual calls using this pointer are converted + to direct calls by ipa-cp. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + virtual int foo (int i); + int middleman (int i) + { + return foo (i); + } +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + int i; + for (i = 0; i < get_input(); i++) + if (b.middleman (get_input ()) != 3) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::foo" "cp" } } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-3.C b/gcc/testsuite/g++.dg/ipa/devirt-3.C new file mode 100644 index 000000000..2d7bb0ab0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-3.C @@ -0,0 +1,63 @@ +/* Verify that simple virtual calls on an object refrence are + converted to simple calls by ipa-cp. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ + +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); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static int middleman (class A &obj, int i) +{ + return obj.foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + if (middleman (b, get_input ()) != 3) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-4.C b/gcc/testsuite/g++.dg/ipa/devirt-4.C new file mode 100644 index 000000000..72c883b3f --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-4.C @@ -0,0 +1,68 @@ +/* Verify that ipa-co can convert virtual calls to direct ones even + when a typecast to an ancestor is involved along the way. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ + +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); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +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; + if (middleman_2 (&b, get_input ()) != 3) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-5.C b/gcc/testsuite/g++.dg/ipa/devirt-5.C new file mode 100644 index 000000000..575bc0271 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-5.C @@ -0,0 +1,79 @@ +/* Verify that ipa-cp can convert simple virtual calls to a direct + ones even when a typecast to an ancestor is involved along the way + and that ancestor is not the first one with virtual functions. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline -fdump-ipa-cp -fdump-tree-optimized" } */ + +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 B : public Distraction, public A +{ +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; + + if (middleman_2 (&b, get_input ()) != 3) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::foo" "cp" } } */ +/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "optimized"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-6.C b/gcc/testsuite/g++.dg/ipa/devirt-6.C new file mode 100644 index 000000000..e9a5d7093 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-6.C @@ -0,0 +1,38 @@ +/* Verify that we either do not do any devirtualization or correctly + spot that foo changes the dynamic type of the passed object. */ + +/* { dg-do run } */ +/* { dg-options "-O3" } */ + +extern "C" void abort (void); +extern "C" void *malloc(__SIZE_TYPE__); + +inline void* operator new(__SIZE_TYPE__, void* __p) throw() { return __p;} + +int x; + +class A { +public: + virtual ~A() { } +}; + +class B : public A { +public: + virtual ~B() { if (x == 1) abort (); x = 1; } +}; + +void __attribute__((noinline,noclone)) foo (void *p) +{ + B *b = reinterpret_cast<B *>(p); + b->~B(); + new (p) A; +} + +int main() +{ + void *p = __builtin_malloc (sizeof (B)); + new (p) B; + foo(p); + reinterpret_cast<A *>(p)->~A(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-1.C b/gcc/testsuite/g++.dg/ipa/devirt-c-1.C new file mode 100644 index 000000000..df2230d4c --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-1.C @@ -0,0 +1,71 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + A(); + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +A::A () +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +static void bah () +{ + class B b; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-2.C b/gcc/testsuite/g++.dg/ipa/devirt-c-2.C new file mode 100644 index 000000000..d37fe50cd --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-2.C @@ -0,0 +1,79 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ + +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; + A(); + virtual int foo (int i); +}; + +class B : public Distraction, public A +{ +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 (class A *obj, int i) +{ + return obj->foo (i); +} + +A::A() +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +static void bah () +{ + class B b; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-3.C b/gcc/testsuite/g++.dg/ipa/devirt-c-3.C new file mode 100644 index 000000000..c8791f79e --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-3.C @@ -0,0 +1,80 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline" } */ + +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; + A(); + virtual int foo (int i); +}; + +class B : public Distraction, public A +{ +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 __attribute__ ((noinline)) +middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +inline __attribute__ ((always_inline)) A::A() +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +static void bah () +{ + class B b; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-4.C b/gcc/testsuite/g++.dg/ipa/devirt-c-4.C new file mode 100644 index 000000000..56d41e496 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-4.C @@ -0,0 +1,110 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline" } */ + +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; + A(); + virtual int foo (int i); +}; + +class B : public Distraction, public A +{ +public: + B(); + virtual int foo (int i); +}; + +class C : public B +{ +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 C::foo (int i) +{ + return i + 3; +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +static int __attribute__ ((noinline)) +middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +static void __attribute__ ((noinline)) +sth2 (A *a) +{ + if (a->foo (get_input ()) != 3) + abort (); +} + +inline void __attribute__ ((always_inline)) sth1 (B *b) +{ + sth2 (b); +} + +inline __attribute__ ((always_inline)) A::A() +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +B::B() : Distraction(), A() +{ + sth1 (this); +} + +static void bah () +{ + class C c; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-5.C b/gcc/testsuite/g++.dg/ipa/devirt-c-5.C new file mode 100644 index 000000000..637d7d4be --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-5.C @@ -0,0 +1,79 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ + +extern "C" void abort (void); + +class B; + +class A +{ +public: + int data; + A(); + A(B *b); + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +A::A () +{ +} + +A::A (B *b) +{ + if (middleman (b, get_input ()) != 3) + abort (); +} + +static void bah () +{ + B b; + A a(&b); +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-6.C b/gcc/testsuite/g++.dg/ipa/devirt-c-6.C new file mode 100644 index 000000000..f9b8b6954 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-6.C @@ -0,0 +1,72 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under construction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + A(); + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static inline int __attribute__ ((always_inline)) +middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +__attribute__ ((noinline)) A::A () +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +static void bah () +{ + class B b; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/devirt-d-1.C b/gcc/testsuite/g++.dg/ipa/devirt-d-1.C new file mode 100644 index 000000000..3897a7782 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-d-1.C @@ -0,0 +1,71 @@ +/* Verify that ipa-cp correctly detects the dynamic type of an object + under destruction when doing devirtualization. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-inline" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + ~A(); + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +static int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +A::~A () +{ + if (middleman (this, get_input ()) != 2) + abort (); +} + +static void bah () +{ + class B b; +} + +int main (int argc, char *argv[]) +{ + int i; + + for (i = 0; i < 10; i++) + bah (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/iinline-1.C b/gcc/testsuite/g++.dg/ipa/iinline-1.C new file mode 100644 index 000000000..9f9989322 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/iinline-1.C @@ -0,0 +1,49 @@ +/* Verify that simple indirect calls are inlined even without early + inlining.. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining" } */ +/* { dg-add-options bind_pic_locally } */ + +extern void non_existent (const char *, int); + +class String +{ +private: + const char *data; + +public: + String (const char *d) : data(d) + {} + + int funcOne (int delim) const; + int printStuffTwice (int delim) const; +}; + + +int String::funcOne (int delim) const +{ + int i; + for (i = 0; i < delim; i++) + non_existent(data, i); + + return 1; +} + +int docalling (int (String::* f)(int delim) const) +{ + String S ("muhehehe"); + + return (S.*f)(4); +} + +int main (int argc, char *argv[]) +{ + int i = 0; + while (i < 1000) + i += docalling (&String::funcOne); + non_existent ("done", i); + return 0; +} + +/* { dg-final { scan-ipa-dump "String::funcOne\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/iinline-2.C b/gcc/testsuite/g++.dg/ipa/iinline-2.C new file mode 100644 index 000000000..670a5dd95 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/iinline-2.C @@ -0,0 +1,61 @@ +/* Verify that simple indirect calls are inlined even without early + inlining.. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining" } */ +/* { dg-add-options bind_pic_locally } */ + +extern void non_existent (const char *, int); + +class String +{ +private: + const char *data; + +public: + String (const char *d) : data(d) + {} + + int funcOne (int delim) const; + int printStuffTwice (int delim) const; +}; + + +int String::funcOne (int delim) const +{ + int i; + for (i = 0; i < delim; i++) + non_existent(data, i); + + return 1; +} + +extern int global; + +int docalling (int c, int (String::* f)(int delim) const) +{ + String S ("muhehehe"); + + if (c > 2) + global = 3; + else + global = 5; + + return (S.*f)(4); +} + +int __attribute__ ((noinline,noclone)) get_input (void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + int i = 0; + while (i < 1000) + i += docalling (get_input (), &String::funcOne); + non_existent ("done", i); + return 0; +} + +/* { dg-final { scan-ipa-dump "String::funcOne\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/iinline-3.C b/gcc/testsuite/g++.dg/ipa/iinline-3.C new file mode 100644 index 000000000..3daee9a86 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/iinline-3.C @@ -0,0 +1,64 @@ +/* Verify that we do not indirect-inline using member pointer + parameters which have been modified. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining" } */ +/* { dg-add-options bind_pic_locally } */ + +extern "C" void abort (void); + +class String +{ +private: + const char *data; + +public: + String (const char *d) : data(d) + {} + + int funcOne (int stuff) const; + int funcTwo (int stuff) const; +}; + + +int String::funcOne (int stuff) const +{ + return stuff + 1; +} + +int String::funcTwo (int stuff) const +{ + return stuff + 100; +} + +int (String::* gmp)(int stuff) const = &String::funcTwo; + +int docalling_1 (int (String::* f)(int stuff) const) +{ + String S ("muhehehe"); + + return (S.*f)(4); +} + +int docalling (int a, int (String::* f)(int stuff) const) +{ + if (a < 200) + f = gmp; + + return docalling_1 (f); +} + +int __attribute__ ((noinline,noclone)) get_input (void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + int i = 0; + while (i < 10) + i += docalling (get_input (), &String::funcOne); + + if (i != 104) + abort(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-1.C b/gcc/testsuite/g++.dg/ipa/ivinline-1.C new file mode 100644 index 000000000..fc63e6085 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-1.C @@ -0,0 +1,64 @@ +/* Verify that simple virtual calls are inlined even without early + inlining. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +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); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + int i; + + for (i = 0; i < get_input (); i++) + if (middleman (&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" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-2.C b/gcc/testsuite/g++.dg/ipa/ivinline-2.C new file mode 100644 index 000000000..f99330361 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-2.C @@ -0,0 +1,63 @@ +/* Verify that simple virtual calls using this pointer are inlined + even without early inlining.. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + virtual int foo (int i); + int middleman (int i) + { + return foo (i); + } +}; + +class B : public A +{ +public: + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + int i; + + for (i = 0; i < get_input (); i++) + if (b.middleman (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" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-3.C b/gcc/testsuite/g++.dg/ipa/ivinline-3.C new file mode 100644 index 000000000..d9a47f860 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-3.C @@ -0,0 +1,64 @@ +/* Verify that simple virtual calls on an object refrence are inlined + even without early inlining. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +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); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +int middleman (class A &obj, int i) +{ + return obj.foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + int i; + + for (i = 0; i < get_input (); i++) + if (middleman (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" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-4.C b/gcc/testsuite/g++.dg/ipa/ivinline-4.C new file mode 100644 index 000000000..93cbe0c7d --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-4.C @@ -0,0 +1,70 @@ +/* Verify that simple virtual calls are inlined even without early + inlining, even when a typecast to an ancestor is involved along the + way. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +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); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +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" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-5.C b/gcc/testsuite/g++.dg/ipa/ivinline-5.C new file mode 100644 index 000000000..91e8f4e3e --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-5.C @@ -0,0 +1,55 @@ +/* Verify that virtual call inlining does not pick a wrong method when + there is a user defined ancestor in an object. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + virtual int foo (int i); +}; + +class B : public A +{ +public: + class A confusion; + virtual int foo (int i); +}; + +int A::foo (int i) +{ + return i + 1; +} + +int B::foo (int i) +{ + return i + 2; +} + +int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + int i, j = get_input (); + + for (i = 0; i < j; i++) + if ((middleman (&b, j) + 100 * middleman (&b.confusion, j)) != 203) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "A::foo\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-7.C b/gcc/testsuite/g++.dg/ipa/ivinline-7.C new file mode 100644 index 000000000..5f3596d8d --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-7.C @@ -0,0 +1,79 @@ +/* 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 is not the first one with virtual functions. */ +/* { 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 B : public Distraction, public A +{ +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" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-8.C b/gcc/testsuite/g++.dg/ipa/ivinline-8.C new file mode 100644 index 000000000..3bdf4c15b --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/ivinline-8.C @@ -0,0 +1,77 @@ +/* Verify that virtual calls are inlined (ithout early inlining) even + when their caller is itself indirectly inlined. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ + +extern "C" void abort (void); + +class A +{ +public: + int data; + virtual int bar (int i); + virtual int foo (int i); +}; + +class B : public A +{ +public: + virtual int bar (int i); + virtual int foo (int i); +}; + +class C : public A +{ +public: + virtual int foo (int i); +}; + +int A::bar (int i) +{ + return i + 100 * i; +} + +int A::foo (int i) +{ + return bar (i) + 1; +} + +int B::bar (int i) +{ + return i + 100 * (i + 2); +} + +int B::foo (int i) +{ + return bar (i) + 2; +} + +int C::foo (int i) +{ + return i + 3; +} + +int middleman (class A *obj, int i) +{ + return obj->foo (i); +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + class B b; + int i; + + for (i = 0; i < get_input (); i++) + if (middleman (&b, get_input ()) != 303) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { scan-ipa-dump "B::bar\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ 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 000000000..429b6f4f0 --- /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" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/pr43695.C b/gcc/testsuite/g++.dg/ipa/pr43695.C new file mode 100644 index 000000000..a01478324 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr43695.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fipa-cp -fipa-cp-clone" } */ + +extern void baz(int) __attribute__ ((noreturn)); + +struct S { + ~S(); +}; + +__attribute__ ((noreturn, noinline)) +void bar(int i) +{ + baz(i); +} + +void foo() +{ + S s; + bar(0); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr43812.C b/gcc/testsuite/g++.dg/ipa/pr43812.C new file mode 100644 index 000000000..cc46eed65 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr43812.C @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fwhole-program -fipa-cp" } */ + +typedef float scoord_t; +typedef scoord_t sdist_t; +typedef sdist_t dist_t; +template<typename T> class TRay { }; +typedef TRay<dist_t> Ray; +class BBox { }; +class RenderContext { }; +class RefCounted { +public: + void deref () const { + if (--ref_count <= 0) { + delete this; + } + } + mutable int ref_count; +}; +template<class T> class Ref { +public: + ~Ref () { + if (obj) obj->deref (); + } + T *obj; +}; +class Material : public RefCounted { }; +class Surface { +public: + virtual ~Surface () { } + class IsecInfo { }; + virtual const IsecInfo *intersect (Ray &ray, RenderContext &context) const; + Ref<const Material> material; +}; +class LocalSurface : public Surface { + virtual BBox bbox () const; +}; +BBox LocalSurface::bbox () const { } diff --git a/gcc/testsuite/g++.dg/ipa/pr44372.C b/gcc/testsuite/g++.dg/ipa/pr44372.C new file mode 100644 index 000000000..22aa747e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr44372.C @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fipa-cp -fipa-cp-clone" } */ + +template < typename > class S3; + +struct S1 +{ + struct + { + int i[10]; + } s0; + S1 () : s0 () + { } + template < typename T > S1 (S3 < T > s3, int) + { + f (s3); + } +}; + +struct S2 +{ + template < typename T > S2 s (S3 < T > s3) + { + S1 (s3, 0); + } + S2 (int i) : j (i) + { } + int j; + S1 s1[10]; +}; + +template < typename > struct S3 +{ + S3 () + { + S2 (0).s (*this); + } +}; + +static inline void +f (S3 < int > s3) +{ + extern bool m; + if (m) + S2 (0).s (s3); +} + +S3 < int >s3; diff --git a/gcc/testsuite/g++.dg/ipa/pr45565.C b/gcc/testsuite/g++.dg/ipa/pr45565.C new file mode 100644 index 000000000..c04de12e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr45565.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// { dg-options "-O -fno-toplevel-reorder -fno-inline -fipa-cp -fipa-cp-clone -fkeep-inline-functions" } + +template < typename Derived > struct AnyMatrixBase +{ +}; + +struct Matrix Random (); + +struct Matrix:AnyMatrixBase < Matrix > +{ + void bar () + { + throw; + } + void foo (Matrix other) + { + bar (); + Matrix (AnyMatrixBase < Matrix > (Random ())); + } + template + < typename OtherDerived > Matrix (AnyMatrixBase < OtherDerived > other) + { + foo (other); + } +}; + +Matrix x (Random ()); + diff --git a/gcc/testsuite/g++.dg/ipa/pr45572-1.C b/gcc/testsuite/g++.dg/ipa/pr45572-1.C new file mode 100644 index 000000000..82f347052 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr45572-1.C @@ -0,0 +1,64 @@ +// { dg-do compile } +// { dg-options "-finline-small-functions -findirect-inlining -finline-functions -O" } + +extern "C" { +typedef long unsigned int size_t; +typedef long int __ssize_t; +typedef struct _IO_FILE FILE; +typedef struct +{ +} __mbstate_t; +extern __inline __attribute__ ((__gnu_inline__)) int +fgetc_unlocked (FILE *__fp) +{ +} +extern __inline __attribute__ ((__gnu_inline__)) int +putc_unlocked (int __c, FILE *__stream) +{ +} +extern __inline __attribute__ ((__gnu_inline__)) __ssize_t +getline (char **__lineptr, size_t *__n, FILE *__stream) +{ +} +extern __inline __attribute__ ((__gnu_inline__)) int +ferror_unlocked (FILE *__stream) throw () +{ +} +} +typedef struct +{} __mpf_struct; +typedef __mpf_struct mpf_t[1]; +typedef const __mpf_struct *mpf_srcptr; +typedef __mpf_struct *mpf_ptr; +extern "C" { + void __gmpf_add (mpf_ptr, mpf_srcptr, mpf_srcptr); +} +class _knumber +{ + public: + enum NumType {SpecialType, IntegerType, FractionType, FloatType}; + virtual NumType type(void) const = 0; + virtual _knumber * add(_knumber const & arg2) const = 0; + virtual operator long int(void) const = 0; +}; +class _knumfloat : public _knumber +{ + _knumfloat(double num = 1.0) + ; + virtual NumType type(void) const ; + virtual _knumber * add(_knumber const & arg2) const; + virtual operator long int (void) const; + mpf_t _mpf; +}; +_knumber *_knumfloat::add(_knumber const & arg2) const +{ + if (arg2.type() == SpecialType) + return arg2.add(*this); +{ + _knumfloat tmp_num(arg2); + return tmp_num.add(*this); + } + _knumfloat * tmp_num = new _knumfloat(); + __gmpf_add(tmp_num->_mpf, _mpf, + dynamic_cast<_knumfloat const &>(arg2)._mpf); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr45572-2.C b/gcc/testsuite/g++.dg/ipa/pr45572-2.C new file mode 100644 index 000000000..8b583d9c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr45572-2.C @@ -0,0 +1,39 @@ +// { dg-do compile } +// { dg-options "-finline-small-functions -findirect-inlining -finline-function+ +typedef struct +{} __mpf_struct; +typedef __mpf_struct mpf_t[1]; +typedef const __mpf_struct *mpf_srcptr; +typedef __mpf_struct *mpf_ptr; +extern "C" { + void __gmpf_add (mpf_ptr, mpf_srcptr, mpf_srcptr); +} +class _knumber +{ + public: + enum NumType {SpecialType, IntegerType, FractionType, FloatType}; + virtual NumType type(void) const = 0; + virtual _knumber * add(_knumber const & arg2) const = 0; + virtual operator long int(void) const = 0; +}; +class _knumfloat : public _knumber +{ + _knumfloat(double num = 1.0) + ; + virtual NumType type(void) const ; + virtual _knumber * add(_knumber const & arg2) const; + virtual operator long int (void) const; + mpf_t _mpf; +}; +_knumber *_knumfloat::add(_knumber const & arg2) const +{ + if (arg2.type() == SpecialType) + return arg2.add(*this); +{ + _knumfloat tmp_num(arg2); + return tmp_num.add(*this); + } + _knumfloat * tmp_num = new _knumfloat(); + __gmpf_add(tmp_num->_mpf, _mpf, + dynamic_cast<_knumfloat const &>(arg2)._mpf); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr45875.C b/gcc/testsuite/g++.dg/ipa/pr45875.C new file mode 100644 index 000000000..34f02e300 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr45875.C @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-early-inlining -fno-ipa-cp" } */ + +extern "C" void abort (void); + +class A +{ +public: + virtual int foo (int i); +}; + +class B +{ +public: + class A confusion; +}; + +int A::foo (int i) +{ + return i + 1; +} + +int __attribute__ ((noinline,noclone)) get_input(void) +{ + return 1; +} + +static int middleman_a (class A *obj, int i) +{ + return obj->foo (i); +} + +static int middleman_b (class B *obj, int i) +{ + return middleman_a (&obj->confusion, i); +} + + +int main (int argc, char *argv[]) +{ + class B b; + int i, j = get_input (); + + for (i = 0; i < j; i++) + if (middleman_b (&b, j) != 2) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr46053.C b/gcc/testsuite/g++.dg/ipa/pr46053.C new file mode 100644 index 000000000..7be6fc3a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr46053.C @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O -fipa-cp -fno-early-inlining" } */ + +extern "C" void abort (); + +struct A +{ + virtual void foo () = 0; +}; + +struct B : A +{ + virtual void foo () = 0; +}; + +struct C : A +{ +}; + +struct D : C, B +{ + int i; + D () : i(0xaaaa) {} + virtual void foo () + { + if (i != 0xaaaa) + abort(); + } +}; + +static inline void bar (B &b) +{ + b.foo (); +} + +int main() +{ + D d; + bar (d); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr46287-1.C b/gcc/testsuite/g++.dg/ipa/pr46287-1.C new file mode 100644 index 000000000..0755529bd --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr46287-1.C @@ -0,0 +1,67 @@ +// Check that indirect calls to thunks do not lead to errors. +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort (); + +class A +{ +public: + virtual void foo () {abort();} +}; + +class B : public A +{ +public: + int z; + virtual void foo () {abort();} +}; + +class C : public A +{ +public: + void *a[32]; + unsigned long b; + long c[32]; + + virtual void foo () {abort();} +}; + +class D : public C, public B +{ +public: + D () : C(), B() + { + int i; + for (i = 0; i < 32; i++) + { + a[i] = (void *) 0; + c[i] = 0; + } + b = 0xaaaa; + } + + virtual void foo (); +}; + +inline void D::foo() +{ + if (b != 0xaaaa) + abort(); +} + +static inline void bar (B &b) +{ + + b.foo (); +} + +int main() +{ + int i; + D d; + + for (i = 0; i < 5000; i++) + bar (d); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr46287-2.C b/gcc/testsuite/g++.dg/ipa/pr46287-2.C new file mode 100644 index 000000000..272852bad --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr46287-2.C @@ -0,0 +1,68 @@ +// Check that indirect calls to thunks do not lead to errors. +// { dg-do run } +// { dg-options "-O -finline -finline-small-functions -finline-functions" } + + +extern "C" void abort (); + +class A +{ +public: + virtual void foo () {abort();} +}; + +class B : public A +{ +public: + int z; + virtual void foo () {abort();} +}; + +class C : public A +{ +public: + void *a[32]; + unsigned long b; + long c[32]; + + virtual void foo () {abort();} +}; + +class D : public C, public B +{ +public: + D () : C(), B() + { + int i; + for (i = 0; i < 32; i++) + { + a[i] = (void *) 0; + c[i] = 0; + } + b = 0xaaaa; + } + + virtual void foo (); +}; + +void D::foo() +{ + if (b != 0xaaaa) + abort(); +} + +static inline void bar (B &b) +{ + + b.foo (); +} + +int main() +{ + int i; + D d; + + for (i = 0; i < 5000; i++) + bar (d); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr46287-3.C b/gcc/testsuite/g++.dg/ipa/pr46287-3.C new file mode 100644 index 000000000..5f291ce1f --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr46287-3.C @@ -0,0 +1,67 @@ +// Check that indirect calls to thunks do not lead to errors. +// { dg-do run } +// { dg-options "-O -fipa-cp" } + +extern "C" void abort (); + +class A +{ +public: + virtual void foo () {abort();} +}; + +class B : public A +{ +public: + int z; + virtual void foo () {abort();} +}; + +class C : public A +{ +public: + void *a[32]; + unsigned long b; + long c[32]; + + virtual void foo () {abort();} +}; + +class D : public C, public B +{ +public: + D () : C(), B() + { + int i; + for (i = 0; i < 32; i++) + { + a[i] = (void *) 0; + c[i] = 0; + } + b = 0xaaaa; + } + + virtual void foo (); +}; + +void D::foo() +{ + if (b != 0xaaaa) + abort(); +} + +static void bar (B &b) +{ + + b.foo (); +} + +int main() +{ + int i; + D d; + + for (i = 0; i < 5000; i++) + bar (d); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr46984.C b/gcc/testsuite/g++.dg/ipa/pr46984.C new file mode 100644 index 000000000..464ceb14a --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr46984.C @@ -0,0 +1,63 @@ +// { dg-options "-O -fipa-cp -fno-early-inlining -flto" } +// { dg-do run } +// { dg-require-effective-target lto } + +extern "C" void abort (); + +class A +{ +public: + virtual void foo () {abort();} +}; + +class B : public A +{ +public: + int z; + virtual void foo () {abort();} +}; + +class C : public A +{ +public: + void *a[32]; + unsigned long b; + long c[32]; + + virtual void foo () {abort();} +}; + +class D : public C, public B +{ +public: + D () : C(), B() + { + int i; + for (i = 0; i < 32; i++) + { + a[i] = (void *) 0; + c[i] = 0; + } + b = 0xaaaa; + } + + virtual void foo (); +}; + +void D::foo() +{ + if (b != 0xaaaa) + abort(); +} + +static inline void bar (B &b) +{ + b.foo (); +} + +int main() +{ + D d; + bar (d); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr51759.C b/gcc/testsuite/g++.dg/ipa/pr51759.C new file mode 100644 index 000000000..accfaf2dc --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr51759.C @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern "C" void abort (void); +struct S +{ + void __attribute__((noinline)) set(unsigned val) + { + data = val; + if (data != val) + abort (); + } + int pad0; + unsigned pad1 : 8; + unsigned data : 24; + int pad2; +}; +int main() +{ + S s; + s.pad2 = -1; + s.set(0); + if (s.pad2 != -1) + abort (); +} + diff --git a/gcc/testsuite/g++.dg/ipa/pr55264.C b/gcc/testsuite/g++.dg/ipa/pr55264.C new file mode 100644 index 000000000..cf54d6ae2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr55264.C @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-early-inlining -fno-weak" } */ + +struct S +{ + S(); + virtual inline void foo () + { + foo(); + } +}; + +void +B () +{ + S().foo (); +} |