summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/ipa
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/ipa
downloadcbb-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')
-rw-r--r--gcc/testsuite/g++.dg/ipa/20090113-1.C25
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-1.C62
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-2.C62
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-3.C63
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-4.C68
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-5.C79
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-6.C38
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-c-1.C71
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-c-2.C79
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-c-3.C80
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-c-4.C110
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-c-5.C79
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-c-6.C72
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-d-1.C71
-rw-r--r--gcc/testsuite/g++.dg/ipa/iinline-1.C49
-rw-r--r--gcc/testsuite/g++.dg/ipa/iinline-2.C61
-rw-r--r--gcc/testsuite/g++.dg/ipa/iinline-3.C64
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-1.C64
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-2.C63
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-3.C64
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-4.C70
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-5.C55
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-7.C79
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-8.C77
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-9.C93
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr43695.C20
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr43812.C38
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr44372.C48
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr45565.C29
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr45572-1.C64
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr45572-2.C39
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr45875.C48
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr46053.C41
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr46287-1.C67
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr46287-2.C68
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr46287-3.C67
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr46984.C63
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr51759.C26
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr55264.C17
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 ();
+}