diff options
Diffstat (limited to 'gcc/testsuite/g++.dg/opt')
250 files changed, 9765 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/opt/20050511-1.C b/gcc/testsuite/g++.dg/opt/20050511-1.C new file mode 100644 index 000000000..a8929030a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/20050511-1.C @@ -0,0 +1,70 @@ +/* { dg-do run } */ +/* { dg-options "-w" } */ +/* { dg-options "-O3 -w" { target powerpc*-*-* } } */ +#include <stdio.h> +#include <stdlib.h> + +// The VxWorks kernel headers define their own UINT32 +#if defined __vxworks && !defined __RTP__ +#define UINT32 my_UINT32 +#endif + +typedef signed short SINT16 ; +typedef unsigned long UINT32 ; +typedef unsigned int UINT ; + +class A +{ +public: + union + { + SINT16 xy[2]; + UINT32 abXY; + }; + bool operator==(const A& other) const {return abXY == other.abXY;} + bool operator!=(const A& other) const {return abXY != other.abXY;} +}; + +template <int size> struct pArray { unsigned char u08[16*(((size*1)+15)/16)] __attribute__ ((aligned(16))); }; + +struct B +{ + union { + A mvL[2]; + pArray<1> xyz; + }; +} ; + +typedef struct +{ + UINT w; + B b; + +}C; + + +UINT32 bar (const C * sPtr) +{ + UINT w = sPtr->w; + A a; + + a.xy[0] = sPtr->b.mvL[w].xy[0]<<2; + a.xy[1] = sPtr->b.mvL[w].xy[1]<<2; + + if (a.xy[0] != ((SINT16) 0xffff << 2)) + abort (); +} + +int main() +{ + A a; + C c; + a.xy[0] = 0xffff; + a.xy[1] = 0xffff; + c.w=0; + c.b.mvL[0].xy[0] = a.xy[0]; + c.b.mvL[0].xy[1] = a.xy[1]; + + bar (&c); +} + diff --git a/gcc/testsuite/g++.dg/opt/alias1.C b/gcc/testsuite/g++.dg/opt/alias1.C new file mode 100644 index 000000000..4836c5be0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/alias1.C @@ -0,0 +1,25 @@ +// Test that type punning using an anonymous union works with strict aliasing. +// { dg-do run } +// { dg-options "-O2 -fstrict-aliasing" } + +extern "C" void abort (); + +void f (long i) +{ + union + { + long ui; + float uf[20]; + }; + + ui = i; + if (uf[0] != 42.0) + abort (); +} + +int main () +{ + union U { long i; float f[20]; } u; + u.f[0] = 42.0; + f (u.i); +} diff --git a/gcc/testsuite/g++.dg/opt/alias2.C b/gcc/testsuite/g++.dg/opt/alias2.C new file mode 100644 index 000000000..0b4122471 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/alias2.C @@ -0,0 +1,74 @@ +// { dg-do run } +// { dg-options "-O2" } + +extern "C" int printf (const char*, ...); + +struct _Deque_iterator { + int _M_cur; + int x[2]; + int* _M_node; + + _Deque_iterator() : _M_cur(0), _M_node(0) {} + _Deque_iterator(const _Deque_iterator& __x) + : _M_cur(__x._M_cur), + _M_node(__x._M_node) {} +}; + +class _Deque_base +{ +public: + int yy; + + _Deque_base() + : _M_start() + { _M_initialize_map(); } + ~_Deque_base(); + + void _M_initialize_map(); + _Deque_iterator _M_start; +}; + + +_Deque_base::~_Deque_base() { + printf ("bb %x %x\n", this, *_M_start._M_node); +} + +void +_Deque_base::_M_initialize_map() +{ + yy = 0x123; + printf ("aa %x %x\n", this, yy); + + _M_start._M_node = &yy; + _M_start._M_cur = yy; +} + + +class deque : protected _Deque_base +{ +public: + deque () {} + deque(const deque& __x) {} + ~deque() { + _Deque_iterator i = _M_start; + } +}; + + + +class GeometryAddress { +public: + GeometryAddress(deque addressStack) {} +}; + +void yyy (const GeometryAddress& gb) +{ +} + +deque temp1; + +int main() +{ + yyy (GeometryAddress (temp1)); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/alias3.C b/gcc/testsuite/g++.dg/opt/alias3.C new file mode 100644 index 000000000..dc8accd4f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/alias3.C @@ -0,0 +1,45 @@ +// { dg-options "-O2" } + +// Contributed by Nathan Sidwell 22 Dec 2003 <nathan@codesourcery.com> +// Origin: rsandifo@redhat.com + +// PR c++/13387. Alias sets were incorrect + +struct C { + C(short *p = 0, int i = 0) : ptr (p), index (i) {} + short operator*() { return ptr[index]; } + short *ptr; + int index; +}; + +C f1 (C) __attribute__ ((noinline)); +C f1 (C x) +{ + return x; +} + +void f2 (short)__attribute__ ((noinline));; +short s; + +void f2 (short s_) +{ + s = s_; +} + +C g (C x)__attribute__ ((noinline)); +C g (C x) +{ + x = f1 (x); + f2 (*x); + return x; +} + +int main () +{ + short p[2] = { 0x1234, 0x5678 }; + C x (p, 1); + + g (x); + + return s != p[1]; +} diff --git a/gcc/testsuite/g++.dg/opt/alias4.C b/gcc/testsuite/g++.dg/opt/alias4.C new file mode 100644 index 000000000..6965b8c73 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/alias4.C @@ -0,0 +1,56 @@ +// PR c++/27768 +// Alias grouping was losing some may_aliases, causing us to think +// the store to w.p was dead. + +// { dg-do run } +// { dg-options "-O2" } + +int N = 1; + +struct VA +{ + int *p, *q, *r; + + VA() : p(), q() {} + VA(const VA&) : p(), q() {} + ~VA() { if (p) --N; } +}; + +inline void foo(VA, VA, VA) {} + +struct VB +{ + VA va; + + VB() {} + + VB(const VB&) + { + va.p = new int(va.q - va.p); + va.r = va.p + (va.q - va.p); + foo(va, va, va); + } +}; + +struct VC : VB { char c; }; +struct V : VC {}; + +struct WA +{ + struct X {}; + X **p, **q, **r; + + WA() : p() {} + ~WA() { if (p) --N; } +}; + +struct W : WA {}; + +int main() +{ + { + V v, u(v); + W w; + } + return N; +} diff --git a/gcc/testsuite/g++.dg/opt/anchor1.C b/gcc/testsuite/g++.dg/opt/anchor1.C new file mode 100644 index 000000000..e24b0a4fe --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/anchor1.C @@ -0,0 +1,59 @@ +// { dg-do run } +// { dg-options "-O2" } + +// The size of the construction vtable for YFont in YCoreFont was not +// updated to reflect its actual size. On targets with section anchor +// support, the vtable for YCoreFont was laid out immediately after +// that, but the compiler thought it was about 40 bytes closer to the +// anchor than it actually was. + +extern "C" void abort (void); + +class refcounted { +public: + int __refcount; + +public: + refcounted(): __refcount(0) {}; + virtual ~refcounted() {} +}; + +class YFont : public virtual refcounted { +public: + virtual ~YFont() {} + + virtual int ascent() const = 0; +}; + +struct XFontStruct { +}; + +class YCoreFont : public YFont { +public: + YCoreFont(char const * name); + virtual ~YCoreFont(); + + virtual int ascent() const { return 2; } + +private: + XFontStruct * fFont; +}; + +YCoreFont::YCoreFont(char const * name) { +} + +YCoreFont::~YCoreFont() { +} + +int foo(YCoreFont *ycf) +{ + return ycf->ascent (); +} + +int main() +{ + YCoreFont ycf(""); + if (foo(&ycf) != 2) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/anonunion1.C b/gcc/testsuite/g++.dg/opt/anonunion1.C new file mode 100644 index 000000000..445ebaa7c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/anonunion1.C @@ -0,0 +1,25 @@ +// PR c++/5748 +// This testcase ICEd because used flag from the anon union variables +// was not propagated back to the anon union itself, causing addressof +// not to be replaced with stack slot. +// { dg-do compile } +// { dg-options "-O2" } + +struct A { + A (); + ~A (); + int foo (); + int bar (void *x, int y); +}; + +int A::foo() +{ + union { + int a; + int b; + }; + + if (bar (&a, sizeof (int)) != 32) + return 16; + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/array1.C b/gcc/testsuite/g++.dg/opt/array1.C new file mode 100644 index 000000000..c63ed22c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/array1.C @@ -0,0 +1,20 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Nov 2004 <nathan@codesourcery.com> + +// PR 18672:ICE gimplifying incomplete array type. +// Origin: Magnus Fromreide <gcc@magfr.user.lysator.liu.se> + +struct A; + +struct D { + static A ary[]; +}; +extern A ary[]; + +void Foo (A const *); + +void Bar () +{ + Foo (D::ary); + Foo (::ary); +} diff --git a/gcc/testsuite/g++.dg/opt/array2.C b/gcc/testsuite/g++.dg/opt/array2.C new file mode 100644 index 000000000..b40b052d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/array2.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +struct JArray +{ + int data[1]; +}; +void *copyIntoByteArray (struct JArray *dest, __SIZE_TYPE__ offset) +{ + void *pdest = dest->data + offset; + return pdest; +} diff --git a/gcc/testsuite/g++.dg/opt/asm1.C b/gcc/testsuite/g++.dg/opt/asm1.C new file mode 100644 index 000000000..333533526 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/asm1.C @@ -0,0 +1,9 @@ +// PR c++/6747 +// { dg-do compile } +// { dg-options "-O" } + +void foo() +{ + union { double d; char c[sizeof(double)]; } tmp; + __asm__ ("" : "=m" (tmp.d)); // { dg-bogus "not directly addressable" "double sized union element should be addressible" { xfail xstormy16-*-* } } +} diff --git a/gcc/testsuite/g++.dg/opt/asm2.C b/gcc/testsuite/g++.dg/opt/asm2.C new file mode 100644 index 000000000..4e3244169 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/asm2.C @@ -0,0 +1,11 @@ +/* PR inline-asm/15740 */ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +void foo(void) +{ + int a, b; + a = 1; + b = a + 1; + asm ("" : : "m" (a)); +} diff --git a/gcc/testsuite/g++.dg/opt/bitfield1.C b/gcc/testsuite/g++.dg/opt/bitfield1.C new file mode 100644 index 000000000..496999613 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/bitfield1.C @@ -0,0 +1,18 @@ +// PR c++/26534 +// { dg-do run } +// { dg-options "-w -O2" } + +struct X +{ + unsigned a:4; +}; + +unsigned i; + +int main() +{ + struct X x = { 63u }; + i = x.a; + if (i != 15) + return 1; +} diff --git a/gcc/testsuite/g++.dg/opt/bool1.C b/gcc/testsuite/g++.dg/opt/bool1.C new file mode 100644 index 000000000..78cdebe32 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/bool1.C @@ -0,0 +1,25 @@ +// PR opt/13869 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); + +int test () +{ + bool my_bool = true; + for (int i = 0; i < 10; ++i) + { + if (!my_bool) + ; + else + my_bool = false; + }; + return my_bool; +} + +int main () +{ + if (test ()) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/builtins1.C b/gcc/testsuite/g++.dg/opt/builtins1.C new file mode 100644 index 000000000..8311436b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/builtins1.C @@ -0,0 +1,14 @@ +// PR c++/14791 +// Test if builtins with FILE * arguments work +// { dg-options "-O2 -Wformat" } + +typedef struct _FILE FILE; +FILE *stderr; +extern "C" int printf (__const char *__restrict, ...); +extern "C" int fprintf (FILE *__restrict, __const char *__restrict, ...); + +int main () +{ + printf ("%d\n", 1, 1); // { dg-warning "too many arguments for format" } + fprintf (stderr, "%d\n", 1, 1); // { dg-warning "too many arguments for format" } +} diff --git a/gcc/testsuite/g++.dg/opt/call1.C b/gcc/testsuite/g++.dg/opt/call1.C new file mode 100644 index 000000000..642e02408 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/call1.C @@ -0,0 +1,21 @@ +// { dg-options "-O2" } + +void a (void (*f)()) +{ + f(); +} + +struct RunState +{ + static void runcallback() { } + static void wait() + { + a (runcallback); + } +}; + +int main() +{ + RunState::wait(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/cfg1.C b/gcc/testsuite/g++.dg/opt/cfg1.C new file mode 100644 index 000000000..dbc81fe9b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg1.C @@ -0,0 +1,36 @@ +// PR optimization/11083 +// Origin: <nick@ilm.com> +// Reduced testcase by Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// The compiler used to keep unreachable basic blocks after dead edges +// had been purged, which fooled the LCM code of the GCSE pass. + +// { dg-do compile } +// { dg-options "-O2 -fnon-call-exceptions" } + +extern void *memmove (void *, const void *, unsigned int) throw (); + +struct S { + int *q; + + S(int *i) : q(i) {} +}; + +struct X { + int *p; + + void foo(S first, S last) { + try { memmove(0, 0, last.q - first.q); } + catch(...) { throw; } + } + + void bar (const X& x); +}; + +void X::bar (const X& x) +{ + const unsigned int xlen = S(x.p).q - S(x.p).q; + + if (xlen > 0) + foo(S(x.p), S(x.p)); +} diff --git a/gcc/testsuite/g++.dg/opt/cfg2.C b/gcc/testsuite/g++.dg/opt/cfg2.C new file mode 100644 index 000000000..229f4bc3a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg2.C @@ -0,0 +1,38 @@ +// PR optimization/12215 +// Origin: <nick@ilm.com> +// Reduced testcase by Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// This used to fail because the CSE pass destroyed the CFG in presence +// of trapping loads, which led to the deletion of basic blocks. + +// { dg-do compile } +// { dg-options "-O2 -fno-gcse -fnon-call-exceptions" } + + +struct B { + ~B() throw() {} +}; + +struct X { + X(const char*, const B&); + ~X() {} +}; + +bool m(); +void f(int &i, float &arg0); + +void g (const char **argv) { + float val; + int i = 1; + + try { + while ( i < 1 ) + { + X arg(argv[i], B()); + if (m()) + throw(0); + + f(i, val); + } + } catch (...) {} +} diff --git a/gcc/testsuite/g++.dg/opt/cfg3.C b/gcc/testsuite/g++.dg/opt/cfg3.C new file mode 100644 index 000000000..123c2f515 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg3.C @@ -0,0 +1,61 @@ +// PR optimization/11646 +// Origin: <nick@ilm.com> + +// This used to fail because the compiler inadvertently cleared +// the EDGE_ABNORMAL flag on a EDGE_EH edge and didn't delete +// unreachable blocks after CSE. + +// { dg-do compile } +// { dg-options "-O -fgcse -fnon-call-exceptions" } + +struct C +{ + int i; +}; + +struct allocator +{ + ~allocator() throw() {} +}; + +struct _Vector_alloc_base +{ + _Vector_alloc_base(const allocator& __a) {} + allocator _M_data_allocator; + struct C *_M_start, *_M_end_of_storage; + void _M_deallocate(struct C* __p, unsigned int __n) {} +}; + +struct _Vector_base : _Vector_alloc_base +{ + _Vector_base(const allocator& __a) : _Vector_alloc_base(__a) { } + ~_Vector_base() { _M_deallocate(0, _M_end_of_storage - _M_start); } +}; + +struct vector : _Vector_base +{ + vector(const allocator& __a = allocator()) : _Vector_base(__a) {} + struct C& operator[](unsigned int __n) { return *_M_start; } +}; + +struct A +{ + float l() const; + A operator-(const A &) const; + const A& operator=(float) const; +}; + +struct B +{ + float d(); +}; + +float f(const A& a, B& b) +{ + vector vc; + int index = vc[0].i; + A aa; + float d = (aa - a).l(); + if (d > b.d()) aa = 0; + return b.d(); +} diff --git a/gcc/testsuite/g++.dg/opt/cfg4.C b/gcc/testsuite/g++.dg/opt/cfg4.C new file mode 100644 index 000000000..94522ed41 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg4.C @@ -0,0 +1,45 @@ +// PR optimization/13067 +// Origin: <bryner@brianryner.com> + +// This used to fail on the tree-ssa because of "out-of-ssa" +// We might have a valid variable, but not a valid value when trying to find +// useless statements created by out-of-ssa translation. In this case +// val will be set to null, then later dereferenced. Bad. + +// { dg-do compile } +// { dg-options "-Os" } + + + +struct Iterator +{ + Iterator operator++(); +}; + +void GetChar(char* aChar); + +void foo(char aChar) +{ + char quote; + Iterator end; + + while (1) { + if (aChar == '"') + GetChar(&aChar); + + switch (aChar) { + case 'a': + ++end; + if (quote) { + if (quote == aChar) { + quote = 0; + } + } else { + quote = aChar; + } + } + } +} + + + diff --git a/gcc/testsuite/g++.dg/opt/cfg5.C b/gcc/testsuite/g++.dg/opt/cfg5.C new file mode 100644 index 000000000..a4bc8eea9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg5.C @@ -0,0 +1,40 @@ +/* PR rtl-optimization/34035 */ +/* Origin: Janis Johnson <janis@gcc.gnu.org> */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fnon-call-exceptions -ffast-math -fno-gcse" } */ + +class One { +public: + One () { e[0] = e[1] = 0.0; } + double e[2]; +}; + +template <class T> +class Two { +public: + Two(); +private: + T *data; + int arraySize; +}; + +template <class T> +Two<T>::Two() { + data = new T[arraySize]; +} + +class Three { +protected: + Two<One> data; +}; + +class Four : public Three { +public: + Four (); + void Foo (int n); +}; + +Four :: Four (){ + Foo (1); +} diff --git a/gcc/testsuite/g++.dg/opt/cleanup1.C b/gcc/testsuite/g++.dg/opt/cleanup1.C new file mode 100644 index 000000000..e7c00dc20 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cleanup1.C @@ -0,0 +1,171 @@ +// PR middle-end/6247 +// This testcase was miscompiled on IA-32 because a single stack slot +// was used for 2 different variables at the same time. +// The function H::h1 was miscompiled. +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); +extern "C" void exit (int); + +struct A +{ + A () { a = 1; } + void a1 () { a++; } + bool a2 () { return !--a; } + unsigned int a; +}; + +struct B : public A +{ + B () : b (0) { a1 (); } + void b1 (); + const char *b; +}; + +struct C +{ + C (); + C (const C &); + ~C () { if (c->a2 ()) { if (c == c0) c0 = 0; c->b1 (); } } + C &operator= (const C &); + static C c1 (const char *x, int y = -1); + C (int, bool); + void a2 (); + B *c; + static B *c0; +}; + +B *C::c0 = __null; + +template <class T> struct D +{ + D (const T& t) : d (t) {} + D () {} + D<T> *next, *prev; + T d; +}; + +template<class T> struct E +{ + D<T> *e; + E () : e (0) {} + E (D<T> *p) : e (p) {} + E (const E<T>& x) : e (x.e) {} + const T& operator* () const { return e->d; } + T& operator* () { return e->d; } + bool operator== (const E<T>& x) const { return e == x.e; } + bool operator!= (const E<T>& x) const { return e != x.e; } + E<T> operator++ (int) { E<T> x = *this; e = e->next; return x; } +}; + +template <class T> struct F : public A +{ + F () { f = new D<T>; f->next = f->prev = f; f0 = 0; } + ~F () {} + D<T> *f; + unsigned int f0; + + F (const F<T>& x) : A () + { + f = new D<T>; f->next = f->prev = f; f0 = 0; + E<T> b (x.f->next); + E<T> e (x.f); + E<T> i (f); + while (b != e) + f1 (i, *b++); + } + + E<T> f1 (E<T> x, const T& y) + { + D<T> *p = new D<T> (y); + p->next = x.e; + p->prev = x.e->prev; + x.e->prev->next = p; + x.e->prev = p; + f0++; + return p; + } +}; + +template <class T> struct G +{ + E<T> g1 () { g3 (); return E<T> (g->f); } + E<T> g2 (const T& x) { g3 (); return g->f1 (g1 (), x); } + void g3 () { if (g->a > 1) { g->a2 (); g = new F<T> (*g); } } + F<T>* g; +}; + +struct H +{ + virtual ~H () {}; + virtual void h1 (); + struct I + { + I () {} + I (C r, C p) : i1 (r), i2 (p) {} + C i1, i2; + }; + G<I> h; +}; + +void H::h1 () +{ + h.g2 (I (C::c1 ("s1"), C::c1 ("t"))); + h.g2 (I (C::c1 ("s2"), C::c1 ("t"))); + h.g2 (I (C::c1 ("s3"), C::c1 ("t"))); +} + +void B::b1 () +{ +} + +C C::c1 (const char *x, int y) +{ + C z; + + if (y != -1) + abort (); + z.c = new B; + z.c->b = x; + return z; +} + +C::C () : c (__null) +{ +} + +C::C (const C &x) +{ + c = x.c; + c->a1 (); +} + +int main () +{ + H h; + h.h.g = new F<H::I> (); + h.h1 (); + if (h.h.g->f0 != 3) + abort (); + D<H::I> *p; + int i; + for (i = 0, p = h.h.g->f; i < 4; i++, p = p->next) + { + if (i == 0 && (p->d.i1.c != __null || p->d.i2.c != __null)) + abort (); + if (i > 0 + && (p->d.i1.c->b[0] != 's' + || p->d.i1.c->b[1] != '0' + i + || p->d.i1.c->b[2] != '\0' + || __builtin_strcmp (p->d.i2.c->b, "t"))) + abort (); + if (p->prev->next != p) + abort (); + if (p->next->prev != p) + abort (); + if (i == 3 && p->next != h.h.g->f) + abort (); + } + exit (0); +} diff --git a/gcc/testsuite/g++.dg/opt/combine.C b/gcc/testsuite/g++.dg/opt/combine.C new file mode 100644 index 000000000..d01ae78a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/combine.C @@ -0,0 +1,73 @@ +// { dg-do assemble { target fpic } } +// { dg-options "-O2 -fweb -fPIC -fvisibility=hidden" } +// { dg-require-visibility "" } + +class QBasicAtomicInt +{ +public: + volatile int _q_value; + inline operator int () const {return _q_value;} +}; +class QVariant; +class QScriptContext; +class QScriptEngine; +class QScriptValue +{ +public: + QVariant toVariant () const; +}; +class QScriptDebuggerBackendPrivate +{ + static QScriptValue trace (QScriptContext *context); +}; +template <typename T> struct QMetaTypeId { }; +template <typename T> struct QMetaTypeId2 +{ + static inline int qt_metatype_id () + { + return QMetaTypeId<T>::qt_metatype_id () ; + } +}; +template <typename T> inline int qMetaTypeId (T * = 0) +{ + return QMetaTypeId2<T>::qt_metatype_id () ; +} +class QVariant { }; +template<typename T> inline T qvariant_cast (const QVariant &v) +{ + const int vid = qMetaTypeId<T> ((0)) ; +}; +class QScriptContext +{ +public: + QScriptValue callee () const; +}; +class QScriptEngine +{ +public: + static bool convertV2 (const QScriptValue &value , int type , void *ptr) ; +}; +inline bool qscriptvalue_cast_helper (const QScriptValue &value , int type , void *ptr) +{ + return QScriptEngine::convertV2 (value, type, ptr) ; +} +template<typename T> T qscriptvalue_cast (const QScriptValue &value) +{ + T t; + const int id = qMetaTypeId<T> () ; + if ( qscriptvalue_cast_helper (value, id, &t)) + return qvariant_cast<T> (value.toVariant ()) ; +} +template <> struct QMetaTypeId< QScriptDebuggerBackendPrivate* > +{ + static int qt_metatype_id () + { + static QBasicAtomicInt metatype_id = { (0) }; + return metatype_id; + } +}; +QScriptValue QScriptDebuggerBackendPrivate::trace (QScriptContext *context) +{ + QScriptValue data = context->callee () ; + QScriptDebuggerBackendPrivate *self = qscriptvalue_cast<QScriptDebuggerBackendPrivate*> (data) ; +} diff --git a/gcc/testsuite/g++.dg/opt/complex1.C b/gcc/testsuite/g++.dg/opt/complex1.C new file mode 100644 index 000000000..0066c26c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/complex1.C @@ -0,0 +1,9 @@ +// PR tree-opt/21994 +// { dg-do compile } +// { dg-options "-O2" } + +_Complex float f(void); +_Complex float g(void) throw() +{ + return f(); +} diff --git a/gcc/testsuite/g++.dg/opt/complex2.C b/gcc/testsuite/g++.dg/opt/complex2.C new file mode 100644 index 000000000..53fc7e98e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/complex2.C @@ -0,0 +1,24 @@ +// PR 22022 +// { dg-do compile } +// { dg-options "-O2" } + +_Complex float f(); +_Complex float g(); +_Complex float h()throw(); +void i(_Complex float)throw(); + +void j(void) +{ + _Complex float x = h(); + try + { + try + { + x = f(); + }catch (...) + { + x = g(); + } + }catch(...){} + i(x); +} diff --git a/gcc/testsuite/g++.dg/opt/complex3.C b/gcc/testsuite/g++.dg/opt/complex3.C new file mode 100644 index 000000000..9a3fdf3f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/complex3.C @@ -0,0 +1,24 @@ +// PR 22022 +// { dg-do compile } +// { dg-options "-O2" } + +_Complex float f(); +_Complex float g(); +_Complex float h()throw(); +void i(float)throw(); + +float j(void) +{ + _Complex float x = h(); + try + { + try + { + x = f(); + }catch (...) + { + x += g(); + } + }catch(...){} + i(__builtin_crealf(x)+__builtin_cimagf(x)); +} diff --git a/gcc/testsuite/g++.dg/opt/complex4.C b/gcc/testsuite/g++.dg/opt/complex4.C new file mode 100644 index 000000000..d6a0be2cf --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/complex4.C @@ -0,0 +1,16 @@ +// PR 24362 +// { dg-do compile } +// { dg-options "-O2" } + +typedef __complex__ double cdouble; +cdouble elt_zero(); +const cdouble *pointer(); + +cdouble trace(void) +{ + cdouble output = elt_zero(); + const cdouble *data = pointer(); + output += data[1]; + return output; +} + diff --git a/gcc/testsuite/g++.dg/opt/complex5.C b/gcc/testsuite/g++.dg/opt/complex5.C new file mode 100644 index 000000000..0da0738b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/complex5.C @@ -0,0 +1,16 @@ +// PR 24365 +// { dg-do compile } +// { dg-options "-O2" } + +typedef __complex__ double cdouble; +inline cdouble to_complex(double r) { + cdouble z; + __real__ z = r; + return z; +} +cdouble elt_zero() { + cdouble a = to_complex(0.0); + a+=1.0; + return a; +} + diff --git a/gcc/testsuite/g++.dg/opt/complex6.C b/gcc/testsuite/g++.dg/opt/complex6.C new file mode 100644 index 000000000..bedb3ed5f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/complex6.C @@ -0,0 +1,14 @@ +// PR 30168 +// { dg-do compile } +// { dg-options "-O2" } + +struct aaa +{ + aaa(_Complex float __z) ; + _Complex float _M_value; +}; +aaa::aaa(_Complex float __z) +{ + __z*=2.0f; + _M_value = __z; +} diff --git a/gcc/testsuite/g++.dg/opt/compound1.C b/gcc/testsuite/g++.dg/opt/compound1.C new file mode 100644 index 000000000..cf81e6980 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/compound1.C @@ -0,0 +1,11 @@ +// PR c++/33709 +// { dg-do compile } +// { dg-options "-O2" } + +class S { + virtual void foo (); +}; +struct T { + S *s; + void bar (unsigned x) { s = (new S[1]) - x; } +}; diff --git a/gcc/testsuite/g++.dg/opt/cond1.C b/gcc/testsuite/g++.dg/opt/cond1.C new file mode 100644 index 000000000..ae8fa4d45 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cond1.C @@ -0,0 +1,24 @@ +// { dg-do run } +// { dg-options "-O2" } + +struct D { int x; }; +struct W +{ + W () {} + D & operator * () { return d; } + D d; +}; + +int +foo (int y) +{ + W m; + (*m).x = (y > 1 ? y : 0); + return (*m).x; +} + +int +main () +{ + return (foo (6) != 6); +} diff --git a/gcc/testsuite/g++.dg/opt/conj1.C b/gcc/testsuite/g++.dg/opt/conj1.C new file mode 100644 index 000000000..b578abbdf --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/conj1.C @@ -0,0 +1,18 @@ +// PR target/5740 +// This testcase ICEd on SPARC -m64 because emit_group_load tried +// to move a DFmode register into DImode register directly. +// { dg-do compile } +// { dg-options "-O2" } + +struct C +{ + C (double y, double z) { __real__ x = y; __imag__ x = z; } + double r () const { return __real__ x; } + double i () const { return __imag__ x; } + __complex__ double x; +}; + +C conj (const C& z) +{ + return C (z.r (), -z.i ()); +} diff --git a/gcc/testsuite/g++.dg/opt/conj2.C b/gcc/testsuite/g++.dg/opt/conj2.C new file mode 100644 index 000000000..25e832a02 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/conj2.C @@ -0,0 +1,23 @@ +// PR target/6043 +// This testcase ICEd on IA-64 because emit_group_store +// did not handle loading CONCAT from register group +// { dg-do compile } + +struct C +{ + C (double y, double z) { __real__ x = y; __imag__ x = z; } + double r () const { return __real__ x; } + double i () const { return __imag__ x; } + __complex__ double x; +}; + +inline C conj (const C& x) +{ + return C (x.r (), - x.i ()); +} + +void foo (void) +{ + C x (1.0, 1.0); + conj (x); +} diff --git a/gcc/testsuite/g++.dg/opt/const1.C b/gcc/testsuite/g++.dg/opt/const1.C new file mode 100644 index 000000000..834cfd5e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/const1.C @@ -0,0 +1,129 @@ +// This testcase was miscompiled on IA-64 to read from unitialized memory +// and dereference it. +// { dg-do run } +// { dg-options "-O2" } + +struct A +{ + A () { a = 1; } + void a1 () { a++; } + bool a2 () { return !--a; } + unsigned int a; +}; + +struct B {}; + +template <class T> struct C +{ + C () {} + C (const T& t) : c (t) {} + C<T> *next, *prev; + T c; +}; + +template <class T> struct D +{ + C<T> *d; + D () : d (0) {} + D (C<T> *x) : d (x) {} + D (const D<T>& x) : d (x.d) {} + bool operator!= (const D<T>& x) const { return d != x.d; } + const T& operator* () const { return d->c; } + D<T> operator++ (int) { D<T> t = *this; d = d->next; return t; } +}; + +template <class T> struct E +{ + C<T> *e; + E () : e (0) {} + E (C<T> *p) : e (p) {} + E (const E<T>& x) : e (x.e) {} + E (const D<T>& x) : e (x.e) {} + bool operator!= (const E<T>& x) const { return e != x.e; } + const T& operator* () const { return e->c; } + E<T>& operator++ () { e = e->next; return *this; } +}; + +template <class T> struct F : public A +{ + C<T> *f; + unsigned long f0; + F () { f = new C<T>; f->next = f->prev = f; f0 = 0; } + F (const F<T>& x) : A () + { + f = new C<T>; f->next = f->prev = f; f0 = 0; + D<T> b (x.f->next), e (x.f), i (f); + while (b != e) + f1 (i, *b++); + } + + ~F () + { + C<T> *p = f->next; + while (p != f) + { + C<T> *x = p->next; + delete p; + p = x; + } + delete f; + } + + D<T> f1 (D<T> x, const T& y) + { + C<T> *p = new C<T> (y); + p->next = x.d; + p->prev = x.d->prev; + x.d->prev->next = p; + x.d->prev = p; + f0++; + return p; + } +}; + +template <class T> struct G +{ + F<T> *g; + G () { g = new F<T>; } + G (const G<T>& x) { g = x.g; g->a1 (); } + ~G () {} + G<T>& operator= (const G<T>& x) { x.g->a1 (); g = x.g; return *this; } + D<T> g1 () { g4 (); return D<T> (g->f); } + E<T> g1 () const { return E<T> (g->f); } + E<T> g2 () const { return E<T> (g->f->next); } + D<T> g3 (const T& x) { g4 (); return g->f1 (g1 (), x); } + void g4 () { if (g->a > 1) { g->a2 (); g = new F<T> (*g); } } + + G<T> operator+ (const G<T>& x) const + { + G<T> x2 (*this); + for (E<T> i = x.g2 (); i != x.g1 (); ++i) + x2.g3 (*i); + return x2; + } + + G<T>& operator+= (const G<T>& x) + { + for (E<T> i = x.g2 (); i != x.g1 (); ++i) + g3 (*i); + return *this; + } +}; + +struct H : public G<B> +{ + H () {} + H (const H& x) : G<B> (x) {} + H (const G<B>& x) : G<B> (x) {} +}; + +void foo (); + +int +main () +{ + H a = H () + H (); + a += H (); + H b; + b = H () + H (); +} diff --git a/gcc/testsuite/g++.dg/opt/const2.C b/gcc/testsuite/g++.dg/opt/const2.C new file mode 100644 index 000000000..b4efbbe35 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/const2.C @@ -0,0 +1,42 @@ +// PR optimization/6631 + +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort (void); + +struct QSize +{ + QSize(); + QSize( int w, int h ); + int wd, ht; + friend inline const QSize operator+( const QSize &, const QSize & ); +}; + +inline QSize::QSize() +{ wd = ht = -1; } + +inline QSize::QSize( int w, int h ) +{ wd = w; ht = h; } + +inline const QSize operator+( const QSize & s1, const QSize & s2 ) +{ return QSize(s1.wd+s2.wd, s1.ht+s2.ht); } + +QSize minimumSize() +{ + return QSize (100, 200); +} + +QSize totalMinimumSize() +{ + QSize s = minimumSize(); + return s + QSize( 0, 0 ); +} + +int main() +{ + QSize s = totalMinimumSize(); + if (s.wd != 100 || s.ht != 200) + abort (); +} + diff --git a/gcc/testsuite/g++.dg/opt/const3.C b/gcc/testsuite/g++.dg/opt/const3.C new file mode 100644 index 000000000..c7c0a1645 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/const3.C @@ -0,0 +1,44 @@ +// PR optimization/12926 +// This failed on SPARC64 because the assignments to the bit-fields +// were wrongly swapped in the constructor. + +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort(void); + +typedef __SIZE_TYPE__ size_t; + +void *my_out; + +struct A +{ + enum Type {P, U, S}; + + int foo1(void *, const char *); + int foo2(int, const Type); + + A (const size_t size, const Type type): mSize(size), mType(type) + { + foo2(foo1(my_out, "type = "), type); + foo2(foo1(my_out, "mType = "), mType); + } + + const size_t mSize : 8*sizeof(size_t) - 3; + Type mType : 2; +}; + +int i; + +int A::foo1(void *ios, const char *str) { } +int A::foo2(int v, const Type t) { i=0; } + +int main() +{ + A testa(2, A::S); + + if (testa.mType != A::S) + abort(); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/const4.C b/gcc/testsuite/g++.dg/opt/const4.C new file mode 100644 index 000000000..883c24b55 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/const4.C @@ -0,0 +1,9 @@ +// PR c++/21454 +// Test whether A is put into .rodata section on platforms +// that have it. +// { dg-do compile } + +const int a[] __attribute__ ((__used__)) = { 0, 1, 2, 3 }; + +// The MMIX port always switches to the .data section at the end of a file. +// { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail powerpc*-*-aix* mmix-*-* } } } diff --git a/gcc/testsuite/g++.dg/opt/const5.C b/gcc/testsuite/g++.dg/opt/const5.C new file mode 100644 index 000000000..3785271a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/const5.C @@ -0,0 +1,13 @@ +// We don't have a good way of determining how ".rodata" is spelled on +// all targets, so we limit this test to a few common targets where we +// do know the spelling. +// { dg-do compile { target i?86-*-linux* x86_64-*-linux* } } +// { dg-final { scan-assembler "\\.rodata" } } + +template <typename T> +struct B { + int i; +}; + +// This declaration should be placed in .rodata. +const B<int> const_B __attribute__((used)) = { 3 }; diff --git a/gcc/testsuite/g++.dg/opt/const6.C b/gcc/testsuite/g++.dg/opt/const6.C new file mode 100644 index 000000000..1a5c79bb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/const6.C @@ -0,0 +1,14 @@ +// PR target/39179 +// Make sure that we don't optimize away the load from K::k. +// { dg-options "-O2" } +// { dg-final { scan-assembler _ZN1K1kE } } + +struct K { + static const unsigned k; +}; +extern "C" void abort (void); +int main() { + if ( K::k != 1 ) + abort (); + return 1; +} diff --git a/gcc/testsuite/g++.dg/opt/copysign-1.C b/gcc/testsuite/g++.dg/opt/copysign-1.C new file mode 100644 index 000000000..347bec26e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/copysign-1.C @@ -0,0 +1,10 @@ +// { dg-options "-O2" } +// { dg-do compile } +// PR rtl-opt/27883 +// MIPS used to ICE because local flow update +// was not removing an invalid REG_DEAD. + + +double copysign (double x, double y); +double GetDouble(); +double a = copysign (1.0, GetDouble()); diff --git a/gcc/testsuite/g++.dg/opt/covariant1.C b/gcc/testsuite/g++.dg/opt/covariant1.C new file mode 100644 index 000000000..e57cf4c6b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/covariant1.C @@ -0,0 +1,47 @@ +// PR c++/20206 +// { dg-do run } +// { dg-options "-O0" } + +void +bar (int x) +{ + asm ("" : : "g" (x)); +} + +struct S { S () {}; virtual ~S () {}; }; +struct T { virtual T *foo (int) {}; }; +struct V : virtual S, virtual T {}; +struct V v; +struct U : public S, public T +{ + bool a; + U () {} + virtual ~U () {} + virtual V *foo (int x) + { + switch (x) + { + case 12: + break; + case 9: + bar (7); + break; + case 10: + bar (12); + break; + case 4: + bar (18); + break; + case 2: + bar (26); + break; + } + return &v; + } +}; +U u; + +int +main () +{ +} diff --git a/gcc/testsuite/g++.dg/opt/crash1.C b/gcc/testsuite/g++.dg/opt/crash1.C new file mode 100644 index 000000000..3526df1dd --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/crash1.C @@ -0,0 +1,14 @@ +// PR opt/13681 +// Here we have an out-of-range array index. We should not abort +// trying to resolve the indirection back to an object. + +struct X { + double values[1]; + double & foo (const unsigned int index) { return values[index]; } +}; + +void foo() { + double d; + X h1; + h1.foo(1) = d; +} diff --git a/gcc/testsuite/g++.dg/opt/crossjump1.C b/gcc/testsuite/g++.dg/opt/crossjump1.C new file mode 100644 index 000000000..01abdc071 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/crossjump1.C @@ -0,0 +1,34 @@ +// PR middle-end/21492 +// { dg-do compile } +// { dg-options "-Os" } +// { dg-options "-Os -fPIC" { target fpic } } + +extern char *bar (const char *, const char *); +extern char *baz (char *, const char *); +extern unsigned int fn (const char *); +static const struct C { int i; } k = { 0}; + +struct A +{ + ~A (); +}; + +char * +foo (char *x, const char *y) +{ + A a; + char *c = x; + + if (bar (y, "foo")) + { + baz (c, "foo"); + c += fn ("foo"); + } + else if (bar (y, "bar")) + { + baz (c, "bar"); + c += fn ("bar"); + } + + return x; +} diff --git a/gcc/testsuite/g++.dg/opt/cse1.C b/gcc/testsuite/g++.dg/opt/cse1.C new file mode 100644 index 000000000..be1ad5a11 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cse1.C @@ -0,0 +1,12 @@ +// PR optimization/6759 +// This testcase ICEd on SPARC because folded REG_EQUAL +// note was note stored back and fold_rtx left invalid rtx +// in it. +// { dg-do compile } +// { dg-options "-O2" } + +struct A +{ + long long a; + A (unsigned short d) : a (d) {} +} x (65535); diff --git a/gcc/testsuite/g++.dg/opt/cse2.C b/gcc/testsuite/g++.dg/opt/cse2.C new file mode 100644 index 000000000..325169dff --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cse2.C @@ -0,0 +1,39 @@ +// This testcase caused ICE on IA-32 in simplify_unary_operation +// CSE did not assume SUBREGs changing mode from integral to floating. +// { dg-do run { target i?86-*-* sparc*-*-* x86_64-*-* } } +// { dg-options "-O2" } + +struct A +{ + union + { + float f; + unsigned int w; + } a; + + static inline const A foo (void) + { + return A ((unsigned int) (__extension__ ((union { unsigned l; float d; }) + { l: 0x3f800000 }).d)); + } + inline A (float f) { a.f = f; } + A (); + inline A (unsigned int w) { a.w = w; } +}; + +A::A() +{ + *this = foo (); +} + +A a; + +extern "C" void abort (void); +extern "C" void exit (int); + +int main () +{ + if (a.a.w != 1) + abort (); + exit (0); +} diff --git a/gcc/testsuite/g++.dg/opt/cse3.C b/gcc/testsuite/g++.dg/opt/cse3.C new file mode 100644 index 000000000..a63280716 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cse3.C @@ -0,0 +1,48 @@ +// This testcase resulted in invalid code generation on x86_64 targets +// due to a bug in fold_rtx. For a "true" value, fold_rtx represented it +// as const_true_rtx in floating-point mode, if the FLOAT_STORE_FLAG_VALUE +// macro is not defined. + +// { dg-do run } +// { dg-options "-O1 -fno-guess-branch-probability -fcse-follow-jumps -fgcse -frerun-cse-after-loop" } + +class StatVal { + + public: + + StatVal(double ev, double va) + : m(ev), + v(va) {} + + StatVal(const StatVal& other) + : m(other.m), + v(other.v) {} + + StatVal& operator*=(const StatVal& other) { + double A = m == 0 ? 1.0 : v / (m * m); + double B = other.m == 0 ? 1.0 : other.v / (other.m * other.m); + m = m * other.m; + v = m * m * (A + B); + return *this; + } + + double m; + double v; +}; + +extern "C" void abort (void); + +const StatVal two_dot_three(2, 0.3); + +int main(int argc, char **argv) { + + StatVal product3(two_dot_three); + + product3 *= two_dot_three; + + if (product3.v > 2.5) + { + abort(); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/delay-slot-1.C b/gcc/testsuite/g++.dg/opt/delay-slot-1.C new file mode 100644 index 000000000..d435873cc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/delay-slot-1.C @@ -0,0 +1,111 @@ +/* PR rtl-optimization/23585 */ +/* Testcase by Matti Rintala <matti.rintala@iki.fi> */ + +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +template <class _Ret, class _Tp> +class const_mem_fun_t +{ +public: + explicit + const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + +template <class _Ret, class _Tp> +class const_mem_fun_ref_t +{ +public: + explicit + const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } +private: + _Ret (_Tp::*_M_f)() const; +}; + +template <class _Ret, class _Tp, class _Arg> +class const_mem_fun1_t +{ +public: + explicit + const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + + +template <class _Ret, class _Tp, class _Arg> +class const_mem_fun1_ref_t +{ +public: + explicit + const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } +private: + _Ret (_Tp::*_M_f)(_Arg) const; +}; + +template <class _Ret, class _Tp> +inline const_mem_fun_t<_Ret, _Tp> +mem_fun(_Ret (_Tp::*__f)() const) +{ return const_mem_fun_t<_Ret, _Tp>(__f); } + +template <class _Ret, class _Tp> +inline const_mem_fun_ref_t<_Ret, _Tp> +mem_fun_ref(_Ret (_Tp::*__f)() const) +{ return const_mem_fun_ref_t<_Ret, _Tp>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_t<_Ret, _Tp, _Arg> +mem_fun(_Ret (_Tp::*__f)(_Arg) const) +{ return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } + +template <class _Ret, class _Tp, class _Arg> +inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> +mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) +{ return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } + +class Klasse { +public: + void vf0c() const; + void vf1c(const int&) const; +}; + +int main() +{ + Klasse obj; + const Klasse& objc = obj; + + mem_fun(&Klasse::vf0c)(&objc); + mem_fun(&Klasse::vf1c)(&objc, 1); + + mem_fun_ref(&Klasse::vf0c)(objc); + mem_fun_ref(&Klasse::vf1c)(objc, 1); + return 0; +} + +void Klasse::vf0c() const +{} + +void Klasse::vf1c(const int&) const +{} diff --git a/gcc/testsuite/g++.dg/opt/devirt1.C b/gcc/testsuite/g++.dg/opt/devirt1.C new file mode 100644 index 000000000..0a825c2a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/devirt1.C @@ -0,0 +1,7 @@ +// { dg-do compile } +// { dg-options "-O" } +// { dg-final { scan-assembler "xyzzy" { xfail *-*-* } } } + +struct S { S(); virtual void xyzzy(); }; +inline void foo(S *s) { s->xyzzy(); } +void bar() { S s; foo(&s); } diff --git a/gcc/testsuite/g++.dg/opt/dtor1.C b/gcc/testsuite/g++.dg/opt/dtor1.C new file mode 100644 index 000000000..0352676c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor1.C @@ -0,0 +1,27 @@ +// { dg-do run } +// { dg-options "-O2" } + +int i; + +struct S { + S (); + S (const S&); + ~S (); +}; + +S::S () { ++i; } +S::S (const S&) { ++i; } +S::~S () { --i; } + +inline void f (S) { +} + +int main () { + { + S s; + f (s); + } + + return i; +} + diff --git a/gcc/testsuite/g++.dg/opt/dtor2-aux.cc b/gcc/testsuite/g++.dg/opt/dtor2-aux.cc new file mode 100644 index 000000000..9e87cc817 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor2-aux.cc @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "" } + +#include "dtor2.h" + +A::A () {} +A::~A () {} + +void B::mb () {} +B::B (int) {} +B::~B () {} + +void C::mc () {} +C::C (int x) : B (x) {} + +D::~D () {} diff --git a/gcc/testsuite/g++.dg/opt/dtor2.C b/gcc/testsuite/g++.dg/opt/dtor2.C new file mode 100644 index 000000000..39b8e6999 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor2.C @@ -0,0 +1,13 @@ +// PR c++/42317 +// { dg-do link } +// { dg-options "-O0" } +// { dg-additional-sources "dtor2-aux.cc" } + +#include "dtor2.h" + +D::D (int x) : C (x) {} + +int +main () +{ +} diff --git a/gcc/testsuite/g++.dg/opt/dtor2.h b/gcc/testsuite/g++.dg/opt/dtor2.h new file mode 100644 index 000000000..a86940001 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor2.h @@ -0,0 +1,29 @@ +struct A +{ + A (); + ~A (); +}; + +struct B +{ + A b; + virtual void mb (); + B (int); + virtual ~B (); +}; + +struct C : public B +{ + virtual void mc (); + C (int); + ~C (); +}; + +inline C::~C () {} + +struct D : public C +{ + A d; + D (int); + ~D (); +}; diff --git a/gcc/testsuite/g++.dg/opt/dtor3.C b/gcc/testsuite/g++.dg/opt/dtor3.C new file mode 100644 index 000000000..2d9309877 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor3.C @@ -0,0 +1,11 @@ +// PR c++/42386 +// { dg-do compile } +// { dg-options "-O2" } +# 1 "A.h" 1 +#pragma interface +struct D { virtual bool d () const; }; +struct E { virtual ~E (); virtual void *e () const = 0; }; +struct A : public D, public E { ~A () {} }; +# 5 "dtor3.C" 1 +struct F : public A { void *f () const; void *e () const; }; +void *F::e () const { return __null; } diff --git a/gcc/testsuite/g++.dg/opt/dtor4-aux.cc b/gcc/testsuite/g++.dg/opt/dtor4-aux.cc new file mode 100644 index 000000000..e3ca43b74 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor4-aux.cc @@ -0,0 +1,6 @@ +// { dg-do compile } +// { dg-options "" } + +#include "dtor4.h" + +S s; diff --git a/gcc/testsuite/g++.dg/opt/dtor4.C b/gcc/testsuite/g++.dg/opt/dtor4.C new file mode 100644 index 000000000..c58fadfa1 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor4.C @@ -0,0 +1,13 @@ +// PR tree-optimization/42625 +// { dg-do run } +// { dg-options "-O1 -fipa-sra" } +// { dg-additional-sources "dtor4-aux.cc" } + +#include "dtor4.h" + +int +main () +{ + S s; + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/dtor4.h b/gcc/testsuite/g++.dg/opt/dtor4.h new file mode 100644 index 000000000..d3b43beab --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/dtor4.h @@ -0,0 +1,8 @@ +#include <cassert> + +struct S +{ + int a, i; + S () : i(1) {} + __attribute__((noinline)) ~S () { assert (i == 1); } +}; diff --git a/gcc/testsuite/g++.dg/opt/eh1.C b/gcc/testsuite/g++.dg/opt/eh1.C new file mode 100644 index 000000000..63a4d2ef3 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/eh1.C @@ -0,0 +1,21 @@ +// PR middle-end/14477 +// { dg-do compile } +// { dg-options "-O2 -fno-default-inline" } + +struct A +{ + A(); +}; + +struct B +{ + B(const A*); +}; + +struct C +{ + B b; + C(int) : b(new A) {} +}; + +C c(0); diff --git a/gcc/testsuite/g++.dg/opt/eh2.C b/gcc/testsuite/g++.dg/opt/eh2.C new file mode 100644 index 000000000..7cb49f00c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/eh2.C @@ -0,0 +1,34 @@ +// PR 6764 +// { dg-do run } +// { dg-options "-O -fomit-frame-pointer" } + +extern "C" void abort (); + +class test +{ + public: + test * const me; + test () : me(this) { } + ~test () { if (me != this) abort (); } +}; + +void x1 () +{ + test w1; + throw 1; +} + +void x2 () +{ + test w2; + x1 (); +} + +int main (void) +{ + try { + x2 (); + } catch (...) { + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/eh3.C b/gcc/testsuite/g++.dg/opt/eh3.C new file mode 100644 index 000000000..0cd9cac5f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/eh3.C @@ -0,0 +1,33 @@ +// PR target/18841 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); + +int r, i1 = 1, i2 = 2, i3 = 3, i4 = 4, i5 = 5; + +struct S +{ + ~S() { r = i1 + i2 + i3 + i4 + i5; } +}; + +void foo() +{ + S s; + throw 1; +} + +void bar() +{ + try { + foo(); + } catch (...) { + } +} + +int main() +{ + bar(); + if (r != 1 + 2 + 3 + 4 + 5) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/eh4.C b/gcc/testsuite/g++.dg/opt/eh4.C new file mode 100644 index 000000000..0a62ee2db --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/eh4.C @@ -0,0 +1,59 @@ +// { dg-do run } +// { dg-options "-O3" } + +// Make sure that the call to terminate within F2 is not eliminated +// by incorrect MUST_NOT_THROW optimization. Note that we expect F1 +// to be inlined into F2 in order to expose this case. + +#include <cstdlib> +#include <exception> + +static volatile int zero = 0; + +// Note that we need F0 to not be marked nothrow, though we don't actually +// want a throw to happen at runtime here. The noinline tag is merely to +// make sure the assembly in F0 is not unnecessarily complex. +static void __attribute__((noinline)) f0() +{ + if (zero != 0) + throw 0; +} + +struct S1 +{ + S1() { } + ~S1() { f0(); } +}; + +static void f1() +{ + S1 s1; + throw 1; +} + +struct S2 +{ + S2() { } + ~S2() { f1(); } +}; + +static void __attribute__((noinline)) f2() +{ + S2 s2; + throw 2; +} + +static void pass() +{ + exit (0); +} + +int main() +{ + std::set_terminate (pass); + try { + f2(); + } catch (...) { + } + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/eh5.C b/gcc/testsuite/g++.dg/opt/eh5.C new file mode 100644 index 000000000..3557ab2aa --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/eh5.C @@ -0,0 +1,43 @@ +// PR 41377 +// { dg-do compile } +// { dg-options "-O3" } + +struct A +{ + bool foo(int*) const; +} a; + +struct B {}; + +struct B1 : B +{ + bool (A::*pmf)(int*) const; + const A* pa; + + B1() : pmf(&A::foo), pa(&a) {} + bool operator()() const { return (pa->*pmf)(new int); } +}; + +struct B2 : B +{ + B1 b1; + + B2(const B1& _b1) : b1(_b1) {} + bool operator()() const { return b1(); } +}; + +template<int> struct C +{ + void bar(B2 b2) { while (b2()) ; } + C() { bar(B2(B1())); } +}; + +void baz(int i) +{ + switch(i) + { + case 0: new C<0>; + case 1: new C<1>; + case 2: new C<2>; + } +} diff --git a/gcc/testsuite/g++.dg/opt/empty1.C b/gcc/testsuite/g++.dg/opt/empty1.C new file mode 100644 index 000000000..66784fb28 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/empty1.C @@ -0,0 +1,11 @@ +// PR c++/43787 +// Test that we don't try to copy *x. +// { dg-do run } + +class empty_t {}; + +int main() +{ + empty_t* x = 0; + empty_t y = *x; +} diff --git a/gcc/testsuite/g++.dg/opt/empty2.C b/gcc/testsuite/g++.dg/opt/empty2.C new file mode 100644 index 000000000..86caa5ccb --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/empty2.C @@ -0,0 +1,18 @@ +// PR c++/46160 +// { dg-do compile } + +struct S +{ + enum E { A }; +} s; +volatile S t; + +void f (S::E); + +void +g () +{ + volatile S *p = &s; + f (p->A); + f (t.A); +} diff --git a/gcc/testsuite/g++.dg/opt/emptyunion.C b/gcc/testsuite/g++.dg/opt/emptyunion.C new file mode 100644 index 000000000..105faed58 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/emptyunion.C @@ -0,0 +1,13 @@ +// PR optimization/11059 +// This testcase ICEd because clear_by_pieces was called with zero length. +// { dg-do compile } +// { dg-options "-O2" } + +union uni {}; + +int main() { + uni *h; + + h = (uni *)new uni(); +} + diff --git a/gcc/testsuite/g++.dg/opt/enum1.C b/gcc/testsuite/g++.dg/opt/enum1.C new file mode 100644 index 000000000..6416b3f1b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/enum1.C @@ -0,0 +1,30 @@ +// Verify that we don't confuse precision and mode for enums. +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort(); + +enum E { + zero = 0, + test = 0xbb +}; + +static bool foo(unsigned char *x) +{ + E e = static_cast<E>(*x); + switch (e) + { + case test: + return true; + default: + return false; + } +} + +int main() +{ + unsigned char dummy = test; + if (! foo(&dummy)) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/enum2.C b/gcc/testsuite/g++.dg/opt/enum2.C new file mode 100644 index 000000000..6300896cf --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/enum2.C @@ -0,0 +1,21 @@ +// PR c++/43680 +// Test that we don't make excessively aggressive assumptions about what +// values an enum variable can have. +// { dg-options "-O2 -fPIC" } +// { dg-do run } + +extern "C" void abort (); + +enum E { A, B, C, D }; + +void +CheckE(const E value) +{ + long v = value; + if (v <= D) + abort (); +} + +int main() { + CheckE(static_cast<E>(5)); +} diff --git a/gcc/testsuite/g++.dg/opt/expect1.C b/gcc/testsuite/g++.dg/opt/expect1.C new file mode 100644 index 000000000..90a871f37 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/expect1.C @@ -0,0 +1,17 @@ +// PR c++/13239 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); + +struct Y { + int i; +}; + +bool foo () { return true; } +Y bar () { Y y = {0}; return y; } + +int main () +{ + __builtin_expect (foo () && (bar ().i) == 0, 0) ? 0 : (abort (), 1); +} diff --git a/gcc/testsuite/g++.dg/opt/expect2.C b/gcc/testsuite/g++.dg/opt/expect2.C new file mode 100644 index 000000000..1bb5d8331 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/expect2.C @@ -0,0 +1,11 @@ +// PR c++/13392 +// { dg-do compile } +// { dg-options "-O0" } + +extern "C" void abort (void); +struct X { ~X () throw() {} }; +bool foo (X s = X ()) { return false; } +void bar () +{ + __builtin_expect (foo () && true, 1) ? 0 : (abort (), 0); +} diff --git a/gcc/testsuite/g++.dg/opt/float1.C b/gcc/testsuite/g++.dg/opt/float1.C new file mode 100644 index 000000000..8f26ed5c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/float1.C @@ -0,0 +1,21 @@ +// PR optimization/11637 +// Origin: <nick@ilm.com> + +// This used to fail to assemble on x86 because a decimal +// floating point litteral was emitted, which originated +// from a bogus REG_EQUAL note not removed by the combiner. + +// { dg-do assemble } +// { dg-options "-O2 -fnon-call-exceptions" } + +void f(long int seed); + +void g(float &o) +{ + float a = 0.05f; + float b = 1.0 - a; + float c = 1.0 + a; + + f(0); + o = a; +} diff --git a/gcc/testsuite/g++.dg/opt/fold1.C b/gcc/testsuite/g++.dg/opt/fold1.C new file mode 100644 index 000000000..98f1b5191 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/fold1.C @@ -0,0 +1,17 @@ +// PR middle-end/13696 +// { dg-do compile } +// { dg-options "-O2" } + +extern void x(unsigned long*); + +enum e { red, blue, green }; + +struct s { + unsigned long l; +}; +struct s map[1][256]; + +void +f(int i,e j) { + x(&(map[i][j].l)); +} diff --git a/gcc/testsuite/g++.dg/opt/fold2.C b/gcc/testsuite/g++.dg/opt/fold2.C new file mode 100644 index 000000000..95063d7ab --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/fold2.C @@ -0,0 +1,19 @@ +// PR optimization/14669 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); +extern "C" void exit (int); + +enum ActionType { EE=-1, E0=0, E1, E2 }; + +int main(void) +{ + ActionType t = E0; + + if (E1 <= t && t <= E2) + abort (); + + exit (0); +} + diff --git a/gcc/testsuite/g++.dg/opt/fold3.C b/gcc/testsuite/g++.dg/opt/fold3.C new file mode 100644 index 000000000..87a36b9ad --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/fold3.C @@ -0,0 +1,21 @@ +// PR middle-end/15069 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); + +typedef enum { + FOUR = 4, + FIVE = 5 +} direction_t; + +int main () +{ + direction_t four = FOUR; + int flags = (four & 4L) ? (32L | 128L) : 0; + flags &= 32L; + + if (flags == 0) + abort (); +} + diff --git a/gcc/testsuite/g++.dg/opt/ice1.C b/gcc/testsuite/g++.dg/opt/ice1.C new file mode 100644 index 000000000..701897166 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ice1.C @@ -0,0 +1,41 @@ +// PR c++/43024 +// { dg-options "-O2" } + +void foo(); + +template<int> struct X +{ + enum { e }; + typedef int Y; +}; + +template<int N = 0> struct A +{ + ~A() { foo(); } + A() { a<0>(0); } + template<int> void a(typename X<!X<N>::e>::Y); + struct B b(); +}; + +struct B +{ + A<> b0, b1, b2, b3; + B operator+ (const B&); +}; + +struct C +{ + A<> c0, c1, c2, c3, c4, c5, c6, c7, c8; +}; + +inline void bar(int i) +{ + A<> a0, a1; + if (i) a0.b() + a0.b() + a0.b() + a0.b(); +} + +void baz() +{ + C c; + bar(0); +} diff --git a/gcc/testsuite/g++.dg/opt/ifcvt1.C b/gcc/testsuite/g++.dg/opt/ifcvt1.C new file mode 100644 index 000000000..8fcbf4619 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ifcvt1.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-options "-O2 -fnon-call-exceptions" } + +struct S { ~S () throw () {} }; +double bar (); + +int +foo () +{ + S a; + int i = 0; + double c = bar (); + c = c < 0 ? -c : c; + if (c <= 1.e-8) + i += 24; + return i; +} diff --git a/gcc/testsuite/g++.dg/opt/init1.C b/gcc/testsuite/g++.dg/opt/init1.C new file mode 100644 index 000000000..d9a139e72 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/init1.C @@ -0,0 +1,4 @@ +// PR c++/23171 +// { dg-options "-O" } + +int *p = (int*)(int[1]){0}; diff --git a/gcc/testsuite/g++.dg/opt/init2.C b/gcc/testsuite/g++.dg/opt/init2.C new file mode 100644 index 000000000..3c3bc939d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/init2.C @@ -0,0 +1,6 @@ +// PR middle-end/37414 +// { dg-do compile } +// { dg-options "-O2 -ffast-math" } + +double x = 6.0; +double y = x * x; diff --git a/gcc/testsuite/g++.dg/opt/inline1.C b/gcc/testsuite/g++.dg/opt/inline1.C new file mode 100644 index 000000000..55b931138 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline1.C @@ -0,0 +1,43 @@ +// PR c++/6316 +// This testcase ICEd because when deferred bar()::F::F() was being +// expanded, containing bar() was still deferred and had DECL_EXTERNAL set +// (and DECL_NOT_REALLY_EXTERN too). +// { dg-do compile } +// { dg-options "-O3" } + +struct A { ~A() throw() {} }; +template<typename T, typename U> struct B { U a; B(const T *); }; +typedef B<char, A> C; +struct D { D(); }; +struct E { virtual ~E(); }; + +E *bar (); + +void +foo () +{ + E *a = bar (); +} + +extern char *z []; + +E * +bar () +{ + struct F : public E + { + F () + { + for (int i = 0; i < 2; i++) + C e = z[i]; + } + D x, y; + }; + return new F (); +} + +int +main () +{ + foo (); +} diff --git a/gcc/testsuite/g++.dg/opt/inline10.C b/gcc/testsuite/g++.dg/opt/inline10.C new file mode 100644 index 000000000..086a48128 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline10.C @@ -0,0 +1,20 @@ +// PR c++/25010 +// { dg-options "-O2" } + +#pragma interface + +struct T +{ + T *p; + + void baz () + { + p->baz (); + } +}; + +void foo (T *p) +{ + p->baz (); +} + diff --git a/gcc/testsuite/g++.dg/opt/inline11.C b/gcc/testsuite/g++.dg/opt/inline11.C new file mode 100644 index 000000000..d9758176c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline11.C @@ -0,0 +1,28 @@ +/* Verify that gnu_inline inlines disregard inlining limits. */ +/* { dg-do link } */ +/* { dg-options "-O2" } */ + +extern int foo (int); +extern int baz (int); + +extern inline __attribute__((gnu_inline)) +int foo (int x) +{ + int i; + if (!__builtin_constant_p (x)) + { +#define B(n) baz (1##n) + baz (2##n) + baz (3##n) \ + + baz (4##n) + baz (5##n) + baz (6##n) +#define C(n) B(1##n) + B(2##n) + B(3##n) + B(4##n) + B(5##n) + B(6##n) +#define D(n) C(1##n) + C(2##n) + C(3##n) + C(4##n) + C(5##n) + C(6##n) + return D(0) + D(1) + D(2) + D(3) + D(4) + + D(5) + D(6) + D(7) + D(8) + D(9); + } + return 0; +} + +int +main (void) +{ + return foo (0); +} diff --git a/gcc/testsuite/g++.dg/opt/inline12.C b/gcc/testsuite/g++.dg/opt/inline12.C new file mode 100644 index 000000000..d9eae306d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline12.C @@ -0,0 +1,32 @@ +// PR tree-optimization/33458 +// { dg-do compile } +// { dg-options "-O" } + +inline void +foo (int *p, int n) +{ + for (; n > 0; --n, ++p) + *p = 0; +} + +struct A +{ + int x[2]; + A () { foo (x, 2); } +}; + +inline A +getA () +{ + return A (); +} + +struct B +{ + A a; + B (); +}; + +B::B () : a (getA ()) +{ +} diff --git a/gcc/testsuite/g++.dg/opt/inline14.C b/gcc/testsuite/g++.dg/opt/inline14.C new file mode 100644 index 000000000..8d2a5d4bb --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline14.C @@ -0,0 +1,51 @@ +// PR middle-end/34018 +// { dg-do compile } +// { dg-options "-O1" } + +template <typename E, unsigned long N> +struct A +{ + typedef E F; + E elems[N]; + A () {} + E *begin () { return elems; } + const E *begin () const { return elems; } + + explicit A (F const &v0, F const &v1, F const &v2) + { + elems[0] = v0; + elems[1] = v1; + elems[2] = v2; + } +}; + +template <typename E1, typename E2, typename E3> +inline void +bar (const E1 *a1, E2 const &a2, E3 *a3, unsigned long const &sz) +{ + E3 *r = a3 + sz; + for (;a3 != r; a1++, a3++) + *a3 = *a1 - a2; +} + +template<typename E, unsigned long N> +inline A<E, N> +operator- (A<E, N> const& a1, E const& a2) +{ + typedef A<E, N> G; + G a3; + bar (a1.begin (), a2, a3.begin (), N); + return a3; +} + +struct B +{ + B (A<unsigned long, 3> const &m) : n (m - static_cast<unsigned long>(1)) {} + A<unsigned long, 3> n; +}; + +void +foo () +{ + B t (A<unsigned long, 3> (0,0,0)); +} diff --git a/gcc/testsuite/g++.dg/opt/inline15.C b/gcc/testsuite/g++.dg/opt/inline15.C new file mode 100644 index 000000000..5da3a6105 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline15.C @@ -0,0 +1,42 @@ +// PR tree-optimization/40813 +// { dg-do compile } +// { dg-options "-O -fcheck-new" } + +typedef __SIZE_TYPE__ size_t; +typedef void *P; +struct A; +struct B +{ + void *b[5]; + A *foo () { return (A *) & b[0]; } +}; +struct A +{ + void *operator new (size_t x, B &y) { return y.foo (); } +}; +struct C : public A +{ + virtual int bar () { } +}; +struct D : public C +{ + static B baz (unsigned *x) { B b; new (b) D (x); return b; } + D (unsigned *x) { } +}; +struct E +{ + B e; + B fn (unsigned *a) { return D::baz (a); } + E (P b, unsigned *a) : e (fn (a)) { } +}; + +static unsigned * +fn2 () +{ +} + +void +test (P x) +{ + E (x, fn2 ()); +} diff --git a/gcc/testsuite/g++.dg/opt/inline16.C b/gcc/testsuite/g++.dg/opt/inline16.C new file mode 100644 index 000000000..6ee6d76d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline16.C @@ -0,0 +1,19 @@ +// PR c++/36959 +// We shouldn't have to emit fromSlotB just because we need shuf_BZZZ. +// { dg-options -O } +// { dg-final { scan-assembler-not "_ZL9fromSlotBv" } } + +static inline int *fromSlotB(void) +{ + static int shuf_BZZZ = 1; + return &shuf_BZZZ; +} + +int *p; + +int main(void) +{ + p = fromSlotB(); + return (*p != 1); +} + diff --git a/gcc/testsuite/g++.dg/opt/inline17.C b/gcc/testsuite/g++.dg/opt/inline17.C new file mode 100644 index 000000000..a42233d57 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline17.C @@ -0,0 +1,80 @@ +// PR tree-optimization/47420 +// Testcase by Yu Simin <silver24k@gmail.com> + +// { dg-do compile } +// { dg-options "-O2" } + +class fooControlBase +{ +public: + fooControlBase() { } + + virtual ~fooControlBase(); +}; + +class fooControl : public fooControlBase +{ +public: + fooControl() { } +}; + +class sfTextEntryBase +{ +public: + sfTextEntryBase() { } + virtual ~sfTextEntryBase(); +}; + +class sfTextEntry : public sfTextEntryBase +{ +public: + sfTextEntry() + { + } +}; + +class sfTextAreaBase +{ +public: + sfTextAreaBase() { } + virtual ~sfTextAreaBase() { } + +protected: +}; + + +class sfTextCtrlBase : public fooControl, + public sfTextAreaBase, + public sfTextEntry +{ +public: + + + + sfTextCtrlBase() { } + virtual ~sfTextCtrlBase() { } +}; + +class sfTextCtrl : public sfTextCtrlBase +{ +public: + sfTextCtrl(void* parent) + { + Create(parent); + } + virtual ~sfTextCtrl(); + + bool Create(void *parent); + + +}; + +sfTextCtrl* CreateTextCtrl() +{ + return new sfTextCtrl(0); +} + +void foo () +{ + new sfTextCtrl(0); +} diff --git a/gcc/testsuite/g++.dg/opt/inline2.C b/gcc/testsuite/g++.dg/opt/inline2.C new file mode 100644 index 000000000..6e6889fc7 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline2.C @@ -0,0 +1,18 @@ +// { dg-do link } +// { dg-options "-O1 -finline-functions" } + +static void g (); + +void f() +{ + void g(); + g(); +} + +void g() +{ +} + +int main () { + f (); +} diff --git a/gcc/testsuite/g++.dg/opt/inline3.C b/gcc/testsuite/g++.dg/opt/inline3.C new file mode 100644 index 000000000..7199de09c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline3.C @@ -0,0 +1,40 @@ +// PR opt/6793 +// We failed to supress inlining of a varargs function when it's a template. +// { dg-do compile } +// { dg-options "-O3" } + +#include <stdarg.h> + +typedef __SIZE_TYPE__ size_t; + +template < class Type > class VectorNd +{ + size_t size; + Type *data; + public: + + VectorNd (size_t _size, size_t count, ...) + : size (_size) + { + data = new Type[size]; + + va_list ap; + + va_start (ap, count); + + for (size_t i = 0; i < count; i++) + data[i] = va_arg (ap, Type); + + va_end (ap); + } + + ~VectorNd () + { + delete [] data; + } +}; + +int main () +{ + VectorNd <double> vector (3, 3, 1.0, 2.0, 3.0); +} diff --git a/gcc/testsuite/g++.dg/opt/inline4.C b/gcc/testsuite/g++.dg/opt/inline4.C new file mode 100644 index 000000000..2eaad115f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline4.C @@ -0,0 +1,13 @@ +// { dg-options "-O2 -ftemplate-depth-20000" } + +template <int I> +inline void g() { g<I-1>(); return; } + +template <> +inline void g<0>() { int i; return; } + +void h() { + g<250>(); +} + +// { dg-final { scan-assembler-not "\n_?_Z1gILi\[0-9\]+EEvv\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/opt/inline5.C b/gcc/testsuite/g++.dg/opt/inline5.C new file mode 100644 index 000000000..dd61ee6bc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline5.C @@ -0,0 +1,20 @@ +// PR c++/12519 + +// { dg-do compile } +// { dg-options "-O" } + +struct A +{ + ~A(); +}; + +inline const A foo() +{ + A a; + return a; +} + +A bar() +{ + return foo(); +} diff --git a/gcc/testsuite/g++.dg/opt/inline6.C b/gcc/testsuite/g++.dg/opt/inline6.C new file mode 100644 index 000000000..b1616c7e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline6.C @@ -0,0 +1,14 @@ +// PR c++/13081 +// { dg-options "-O2" } +// { dg-final { scan-assembler-not "\n_?_Z3fooIlET_S0_\[: \t\n\]" } } + +template<typename T> T foo(T); + +template<typename T> inline T foo(T t) +{ + return t; +} + +void bar (long& l) { + l = foo(l); +} diff --git a/gcc/testsuite/g++.dg/opt/inline7.C b/gcc/testsuite/g++.dg/opt/inline7.C new file mode 100644 index 000000000..7a873b01a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline7.C @@ -0,0 +1,7 @@ +// PR c++/13543 +// { dg-do compile } +// { dg-options "-O3" } + +struct basic_string { basic_string(const basic_string&); }; +basic_string operator+(const basic_string& lhs, char); +void dumpNode(basic_string start) { dumpNode(start + 'a'); } diff --git a/gcc/testsuite/g++.dg/opt/inline8.C b/gcc/testsuite/g++.dg/opt/inline8.C new file mode 100644 index 000000000..b2ca021b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline8.C @@ -0,0 +1,5 @@ +// PR c++/15871 +// { dg-options "-O2 -fkeep-inline-functions" } +// { dg-final { scan-assembler "foo" } } + +inline void foo(void) { } diff --git a/gcc/testsuite/g++.dg/opt/inline9.C b/gcc/testsuite/g++.dg/opt/inline9.C new file mode 100644 index 000000000..10bc54ccd --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/inline9.C @@ -0,0 +1,29 @@ +// PR c++/17972 +// Origin: Michal Ostrowski <mostrows@watson.ibm.com> +// Testcase by Alan Modra <amodra@bigpond.net.au> +// { dg-do run } +// { dg-options "-O" } +// { dg-options "-O -mtune=i686" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } + +struct thread_info +{ + short preempt_count; +} x; + +static inline struct thread_info *cti (void) __attribute__ ((const)); +static inline struct thread_info *cti (void) +{ + return &x; +} + +void fn (void) __attribute__ ((noinline)); +void fn (void) +{ + ++cti()->preempt_count; +} + +int main (void) +{ + fn (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/interface1-a.cc b/gcc/testsuite/g++.dg/opt/interface1-a.cc new file mode 100644 index 000000000..595585257 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface1-a.cc @@ -0,0 +1,9 @@ +struct Test { + void f(); +}; + +Test t; + +void g() { + t.f(); +} diff --git a/gcc/testsuite/g++.dg/opt/interface1.C b/gcc/testsuite/g++.dg/opt/interface1.C new file mode 100644 index 000000000..850fe3840 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface1.C @@ -0,0 +1,13 @@ +// { dg-do run } +// { dg-options "-O2" } +// { dg-additional-sources "interface1-a.cc" } + +#pragma implementation "interface1.h" + +#include "interface1.h" + +extern void g(); + +int main () { + g(); +} diff --git a/gcc/testsuite/g++.dg/opt/interface1.h b/gcc/testsuite/g++.dg/opt/interface1.h new file mode 100644 index 000000000..125f4b59e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface1.h @@ -0,0 +1,8 @@ +#pragma interface "interface1.h" + +struct Test { + void f(); +}; + +inline void Test::f() { +} diff --git a/gcc/testsuite/g++.dg/opt/interface2.C b/gcc/testsuite/g++.dg/opt/interface2.C new file mode 100644 index 000000000..e75e42589 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface2.C @@ -0,0 +1,19 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Jun 2005 <nathan@codesourcery.com> + +// PR 21280 +// Origin: Jens Maurer <jens.maurer@gmx.net> + +#include "interface2.h" + +struct A +{ + A() { } + virtual ~A() { } +}; + +int main() +{ + A a; + C<A> c(a); +} diff --git a/gcc/testsuite/g++.dg/opt/interface2.h b/gcc/testsuite/g++.dg/opt/interface2.h new file mode 100644 index 000000000..dc0590472 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/interface2.h @@ -0,0 +1,11 @@ +#pragma interface + +template<class T> +struct C +{ + explicit C(const T& t) : a(t) { } + virtual ~C() { } + T a; +}; + + diff --git a/gcc/testsuite/g++.dg/opt/life1.C b/gcc/testsuite/g++.dg/opt/life1.C new file mode 100644 index 000000000..f029767b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/life1.C @@ -0,0 +1,18 @@ +// This testcase did not set up the pic register on IA-32 due +// to bug in calculate_global_regs_live EH edge handling. +// { dg-do compile { target i?86-*-linux* x86_64-*-linux* } } +// { dg-require-effective-target ilp32 } +// { dg-require-effective-target fpic } +// { dg-options "-O2 -fPIC" } + +struct A { }; + +void foo (A (*fn)()) +{ + try { + A a = fn (); + } catch (...) { + } +} + +// { dg-final { scan-assembler "GLOBAL_OFFSET_TABLE" } } diff --git a/gcc/testsuite/g++.dg/opt/local1.C b/gcc/testsuite/g++.dg/opt/local1.C new file mode 100644 index 000000000..9cecaee6f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/local1.C @@ -0,0 +1,20 @@ +// { dg-options "-O" } + +struct Outer { + struct Inner { virtual bool f() = 0; }; + void g(Inner &) const; +}; + +inline void h(const Outer &o) +{ + struct Local : public Outer::Inner { + virtual bool f() {}; + }; + Local l; + o.g(l); +} + +void f(Outer &req) { + h (req); +} + diff --git a/gcc/testsuite/g++.dg/opt/longbranch1.C b/gcc/testsuite/g++.dg/opt/longbranch1.C new file mode 100644 index 000000000..a64a57aea --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/longbranch1.C @@ -0,0 +1,36 @@ +// PR c++/5964 +// This testcase failed to link on sparc -m64 -O0, because instruction +// lengths were incorrectly computed +// { dg-do link } +// { dg-options "-O0" } + +#define makecode for (int i = 1; i < 1000; ++i) i *= 3 +#define muchcode \ + makecode; makecode; makecode; makecode; makecode; makecode; \ + makecode; makecode; makecode; makecode; makecode; makecode; \ + makecode; makecode; makecode; makecode; makecode; makecode; \ + makecode; makecode; makecode; makecode; makecode; makecode + +#define verymuchcode \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \ + muchcode; muchcode; muchcode; muchcode; muchcode; muchcode + +int +main (int argc, char **argv) +{ +loop: + verymuchcode; + delete[] argv; + goto loop; +} diff --git a/gcc/testsuite/g++.dg/opt/longbranch2.C b/gcc/testsuite/g++.dg/opt/longbranch2.C new file mode 100644 index 000000000..f2a3a7817 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/longbranch2.C @@ -0,0 +1,63 @@ +// PR target/11689 +// Originator: thor@math.tu-berlin.de + +// { dg-do compile } +// { dg-options "-O3 -funroll-loops -mtune=k6 -fomit-frame-pointer" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } + + +// This used to fail to assemble because of an out-of-range 'loop' instructions. + + +class JKeeper { +public: + unsigned long a0; +}; + +class EBCOTLut : public JKeeper { + unsigned char a1[1<<8]; + unsigned char a2[1<<8]; + unsigned char a3[1<<8]; + long a4[1<<9]; +public: + EBCOTLut(void); +}; + +EBCOTLut::EBCOTLut(void) +{ + unsigned char inter[36]; // intermediate lookup table; + unsigned long i; + for(i=0;i<36;i++) { + inter[i] = 0; + } + for(i=1;i<16;i++) { + a1[i | (1<<7)] = 8<<1; + a1[i | (1<<6)] = 8<<1; + } + for(i=0;i < ((1<<9)-1);i++) { + int ds = (i>>0) & 0x01; // significance of DOWN + int us = (i>>1) & 0x01; // significance of UP + int rs = (i>>2) & 0x01; // significance of RIGHT + int ls = (i>>3) & 0x01; // significance of LEFT + int dn = (i>>5) & 0x01; // sign of DOWN + int un = (i>>6) & 0x01; // sign of UP + int rn = (i>>7) & 0x01; // sign of RIGHT + int ln = (i>>8) & 0x01; // sign of LEFT + int h,v; // h and v as in the VM description + + h = ls*(1-ln*2) + rs*(1-2*rn); + v = us*(1-un*2) + ds*(1-2*dn); + h = (h >= -1)?(h):(-1); + v = (v >= -1)?(v):(-1); + h = (h <= 1)?(h):(1); + v = (v <= 1)?(v):(1); + a2[i] = inter[((h+1)<<3) | (v+1)]; + a3[i] = inter[((h+1)<<3) | (v+1)] & (unsigned char)(~1); + } + for(i=0;i< 1<<9; i++) { + a4[i] = 2*(i-(1<<(9-1)))*(i-(1<<(9-1))) - + ((i< (1<<(9-1)))? + (2*(i-(1<<(9-2)))*(i-(1<<(9-2)))): + (2*(i-(3<<(9-2)))*(i-(3<<(9-2))))); + + } +} diff --git a/gcc/testsuite/g++.dg/opt/loop1.C b/gcc/testsuite/g++.dg/opt/loop1.C new file mode 100644 index 000000000..ad0308e7f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/loop1.C @@ -0,0 +1,24 @@ +// PR rtl-optimization/16590 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort(); + +struct iterator { + char * p; + int *dummy; +}; + +static iterator pend(char * start) { + iterator p = {start, 0}; + if (p.p == start) p.p = start+5; + --p.p; + return p; +} + +int main() { + char mem[4+1]; + + if(pend(mem).p != mem+4) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/loop2.C b/gcc/testsuite/g++.dg/opt/loop2.C new file mode 100644 index 000000000..aee612ab5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/loop2.C @@ -0,0 +1,24 @@ +// PR middle-end/22484 +// { dg-do compile } +// { dg-options "-O3" } + +struct A { ~A(); }; +typedef bool B; + +bool foo(); + +bool bar(A&) +{ + B b = true; + + for (int i = 0; i < 2 && b; ++i) + b = foo(); + + return b; +} + +void baz() +{ + A a; + if (bar(a)) foo(); +} diff --git a/gcc/testsuite/g++.dg/opt/memcpy1.C b/gcc/testsuite/g++.dg/opt/memcpy1.C new file mode 100644 index 000000000..f29134599 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/memcpy1.C @@ -0,0 +1,79 @@ +// PR target/34403 +// Origin: Martin Michlmayr <tbm@cyrius.com> + +// { dg-do compile } +// { dg-options "-O" } + +typedef unsigned char uint8_t; +typedef uint8_t uint8; +__extension__ typedef __SIZE_TYPE__ size_t; +class csVector2 +{ +public:float x; +}; +class csBox2 +{ +}; +struct iBase +{ +}; +struct iClipper2D:public virtual iBase +{ +}; +template < class Class > class scfImplementation:public virtual iBase +{ +}; +template < class Class, class I1 > class scfImplementation1:public +scfImplementation < Class >, + public I1 +{ +}; +class csClipper:public scfImplementation1 < csClipper, iClipper2D > +{ +}; +class csBoxClipper:public csClipper +{ + csBox2 region; + virtual uint8 Clip (csVector2 * InPolygon, size_t InCount, + csVector2 * OutPolygon, size_t & OutCount); +}; +struct StatusOutputNone +{ +}; +namespace CS +{ + template < typename BoxTest, typename StatusOutput > class BoxClipper + { + BoxTest boxTest; + StatusOutput statOut; + const csBox2 & region; + csVector2 *InP; + size_t InV; + csVector2 *OutP; + size_t OutV; + public: BoxClipper (const BoxTest & boxTest, const StatusOutput & statOut, + const csBox2 & region, csVector2 * InP, size_t InV, + csVector2 * OutP):boxTest (boxTest), statOut (statOut), + region (region), InP (InP), InV (InV), OutP (OutP), OutV (-1) + { + } + uint8 Clip () + { + __builtin_memcpy (this->OutP, InP, OutV * sizeof (csVector2)); + } + }; +} +struct BoxTestAll +{ +}; +uint8 +csBoxClipper::Clip (csVector2 * InPolygon, size_t InCount, + csVector2 * OutPolygon, size_t & OutCount) +{ + BoxTestAll b; + StatusOutputNone n; + CS::BoxClipper < BoxTestAll, StatusOutputNone > boxClip (b, n, region, + InPolygon, InCount, + OutPolygon); + uint8 Clipped = boxClip.Clip (); +} diff --git a/gcc/testsuite/g++.dg/opt/mmx1.C b/gcc/testsuite/g++.dg/opt/mmx1.C new file mode 100644 index 000000000..7af0d0145 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/mmx1.C @@ -0,0 +1,65 @@ +// PR optimization/4994 +// This testcase ICEd because movsi was not supporting direct +// mmx -> mmx register moves. +// { dg-do compile } +// { dg-options "-O2" } +// { dg-options "-fno-exceptions -O2 -mmmx -fPIC" { target { { i?86-*-* x86_64-*-* } && { ilp32 && fpic } } } } + +struct A { + unsigned a0; + bool a1 () { return !--a0; } + void a2 (); +}; + +struct B +{ + B (); + B (const B &); + ~B(); + B &operator= (const B &); + B b0 (unsigned long x, int y = 0, int z = 10) const; + +private: + A *b1; + static A *b2; +}; + +inline B::~B() +{ + if (b1->a1 () && b1 == b2) + b1->a2(); +} + +struct C +{ + C *c0; +}; + +struct D +{ + C *d0; + D (); + D (const D &c0) {} + D &operator++ () { + C *x = d0; C *y = x->c0; + while (x == y->c0) + x = y; + d0 = x; + return *this; + } +}; + +B foo (const char *x, const B &y); + +void bar (void) +{ + B *y = 0; + B z; + for (unsigned long l = 0; l < 2147483647L * 2UL + 1; l++) + { + z = y->b0 (l); + *y = foo ("data", z); + } + D d; + ++d; +} diff --git a/gcc/testsuite/g++.dg/opt/mmx2.C b/gcc/testsuite/g++.dg/opt/mmx2.C new file mode 100644 index 000000000..8ee6cd469 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/mmx2.C @@ -0,0 +1,24 @@ +// { dg-do link { target i?86-*-* x86_64-*-* } } +// { dg-options "-O2 -mmmx" } +// { dg-prune-output "mangled name" } + +#include <mmintrin.h> + +static union u { __m64 m; long long l; } u; +extern "C" void abort (void); + +__attribute__((noinline)) +void bar (__m64 x) +{ + u.m = x; +} + +int +main () +{ + bar (_mm_set_pi32 (0x000000FF,0xFFFF00FF)); + _mm_empty (); + if (u.l != 0xffffff00ffLL) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/new1.C b/gcc/testsuite/g++.dg/opt/new1.C new file mode 100644 index 000000000..dbcc0f851 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/new1.C @@ -0,0 +1,71 @@ +// PR c++/39367 +// { dg-options "-O" } + +class QScriptEnginePrivate; +class QScriptClassInfo; +namespace QScript { + enum Type { InvalidType }; +}; +class QScriptValueImpl { +public: + inline QScriptValueImpl(); + QScript::Type m_type; +}; +namespace QScript { + namespace Ecma { + class Core { + public: + inline QScriptEnginePrivate *engine() const { } + inline QScriptClassInfo *classInfo() const { } + QScriptValueImpl publicPrototype; + }; + class Boolean: public Core { + void newBoolean(QScriptValueImpl *result, bool value = false); + }; + } + template <typename T> class Buffer { + public: + inline void reserve(int num); + inline void resize(int s); + T *m_data; + int m_capacity; + int m_size; + }; +} +template <typename T> void QScript::Buffer<T>::resize(int s) { + if (m_capacity < s) + reserve (s << 1); +} +template <typename T> void QScript::Buffer<T>::reserve(int x) { + T *new_data = new T[m_capacity]; + for (int i=0; i<m_size; ++i) + new_data[i] = m_data[i]; +} +class QScriptObject { +public: + inline void reset(); + QScript::Buffer<QScriptValueImpl> m_values; +}; +class QScriptEnginePrivate { +public: + inline QScriptObject *allocObject() { return 0; } + inline void newObject(QScriptValueImpl *o, const QScriptValueImpl &proto, + QScriptClassInfo *oc = 0); +}; +inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o, + const QScriptValueImpl &proto, + QScriptClassInfo *oc) +{ + QScriptObject *od = allocObject(); + od->reset(); +} +inline QScriptValueImpl::QScriptValueImpl() : m_type(QScript::InvalidType) { } +inline void QScriptObject::reset() { m_values.resize(0); } +namespace QScript { + namespace Ecma { + void Boolean::newBoolean(QScriptValueImpl *result, bool value) + { + engine()->newObject(result, publicPrototype, classInfo()); + } + } +} diff --git a/gcc/testsuite/g++.dg/opt/noreturn-1.C b/gcc/testsuite/g++.dg/opt/noreturn-1.C new file mode 100644 index 000000000..9b2fc0cf1 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/noreturn-1.C @@ -0,0 +1,87 @@ +// PR optimization/12965 +// Origin: <qboosh@pld-linux.org> +// Reduced testcase: Falk Hueffner <falk@debian.org> + +// This ICEd on Alpha because the reload pass emitted save/restore +// insns around a no-return call. + +// { dg-do compile } +// { dg-options "-O2" } + +template <typename _Alloc> class allocator; +template <class _CharT> struct char_traits; +template <typename _CharT, + typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > +class basic_string; +typedef basic_string<char> string; + +static inline int __exchange_and_add(volatile int * __mem, int __val) { + int __result; + asm("" : "=&r"(__result)); + return __result; +} + +template<typename _Tp> struct allocator { + allocator() throw() { } + allocator(const allocator &) throw() {} +}; + +template<typename _CharT, typename _Traits, typename _Alloc> +struct basic_string { + typedef _Alloc allocator_type; + struct _Rep { + int _M_references; + void _M_dispose(const _Alloc & __a) { + if (__exchange_and_add(&_M_references, -1) <= 0) + _M_destroy(__a); + } void _M_destroy(const _Alloc &) throw(); + }; + struct _Alloc_hider : _Alloc { + _CharT *_M_p; + }; + mutable _Alloc_hider _M_dataplus; + _CharT *_M_data() const { return _M_dataplus._M_p; } + _Rep *_M_rep() const { + return &((reinterpret_cast<_Rep *>(_M_data()))[-1]); + } + basic_string(); + basic_string(const _CharT * __s, const _Alloc & __a = _Alloc()); + ~basic_string() { + _M_rep()->_M_dispose(this->get_allocator()); + } + allocator_type get_allocator() const { return _M_dataplus; } +}; + +struct Egeneric { + void stack(const string & passage, const string & message = "") { } +}; + +struct infinint { + void detruit() throw(Egeneric); + template<class T> void infinint_from(T a) throw(Egeneric); + infinint(long a = 0) throw(Egeneric) { + try { + infinint_from(a); + } catch(Egeneric& e) { + e.stack("infinint::infinint", "long"); + } + } + ~infinint() throw(Egeneric) { + try { + detruit(); + } catch(Egeneric& e) { } + } +}; + +struct inode { + string x; + infinint a, c; + infinint ea_offset; + inode(); +}; + +inode::inode() +{ + ea_offset = 0; +} diff --git a/gcc/testsuite/g++.dg/opt/nothrow1.C b/gcc/testsuite/g++.dg/opt/nothrow1.C new file mode 100644 index 000000000..c1a80822b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nothrow1.C @@ -0,0 +1,25 @@ +// Test that the nothrow optimization works properly. +// { dg-do compile } +// { dg-options "-O -fdump-tree-optimized" } + +extern void blah() throw(); + +int i, j, k; + +int main() +{ + try + { + ++i; + blah(); + ++j; + } + catch (...) + { + return -42; + } +} + +// The catch block should be optimized away. +// { dg-final { scan-tree-dump-times "-42" 0 "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/opt/nrv1.C b/gcc/testsuite/g++.dg/opt/nrv1.C new file mode 100644 index 000000000..cba162522 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv1.C @@ -0,0 +1,28 @@ +// Test for the named return value optimization. +// { dg-do run } +// { dg-options -fno-inline } + +int c; +int d; + +struct A +{ + A() { ++c; } + A(const A&) { ++c; }; + ~A() { ++d; } +}; + +inline A f () +{ + A a; + return a; +} + +int main () +{ + { + A a = f (); + } + + return !(c == 1 && c == d); +} diff --git a/gcc/testsuite/g++.dg/opt/nrv10.C b/gcc/testsuite/g++.dg/opt/nrv10.C new file mode 100644 index 000000000..d4cb92c33 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv10.C @@ -0,0 +1,48 @@ +// PR c++/25979 +// Bug: we were eliding too many temporaries, so that a1 was used +// as both 'a' and 'x' in the second operator+. +// { dg-do run } + +struct A +{ + A() : data1_(0), data2_(0) {} + A(int i, int j) : data1_(i), data2_(j) {} + A operator+(int); + friend A operator+(int, const A&); + ~A() {} +//private: + int data1_; + int data2_; +}; + +extern bool x; + +extern "C" void abort (); + +int main() +{ + A a1(1,2); + a1 = (x ? a1 + 3 : 3 + a1); + if (a1.data1_ != 3 || a1.data2_ != 2) + abort (); +} + +bool x = false; + +A +A::operator+(int i) +{ + A a; + a = *this; + a.data2_ = i; + return a; +} + +A +operator+(int i, const A& x) +{ + A a; + a = x; + a.data1_ = i; + return a; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv11.C b/gcc/testsuite/g++.dg/opt/nrv11.C new file mode 100644 index 000000000..2b72f790b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv11.C @@ -0,0 +1,58 @@ +// PR middle-end/25977 +// Bug: We were assuming that the return slot of the current function is +// always safe to use as the return slot for another call, because its +// address cannot escape. But its address can escape if we perform the +// named return value optimization. + +// { dg-do run } + +struct A +{ + A( int left, int top, int width, int height ) + : x1(left), y1(top), x2(left+width-1), y2(top+height-1) {} + + //A(const A& o) : x1(o.x1), y1(o.y1), x2(o.x2), y2(o.y2) {} + //A& operator=(const A& o ) { x1=o.x1; y1=o.y1; x2=o.x2; y2=o.y2; return *this; } + + A operator&(const A &r) const + { + A tmp(0, 0, -1, -1); + tmp.x1 = ((r.x1) < (x1) ? (x1) : (r.x1)); + tmp.x2 = ((x2) < (r.x2) ? (x2) : (r.x2)); + tmp.y1 = ((r.y1) < (y1) ? (y1) : (r.y1)); + tmp.y2 = ((y2) < (r.y2) ? (y2) : (r.y2)); + return tmp; + } + + int x1; + int y1; + int x2; + int y2; +}; + +bool operator==( const A &r1, const A &r2 ) +{ + return r1.x1==r2.x1 && r1.x2==r2.x2 && r1.y1==r2.y1 && r1.y2==r2.y2; +} + +static A test() +{ + A all = A( 0, 0, 1024, 768); + A a = all; + A r = all; + a = a & r; + return a; +} + +extern "C" void abort(void); + +int main( int argc, char ** argv ) +{ + A all = A( 0, 0, 1024, 768); + A a = test(); + + if ( ! ( a == all)) + abort(); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv12.C b/gcc/testsuite/g++.dg/opt/nrv12.C new file mode 100644 index 000000000..944dddd7b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv12.C @@ -0,0 +1,25 @@ +/* Verify that gimple-level NRV is occurring even for RESULT_DECLs. *./ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O -fdump-tree-optimized" } */ +/* { dg-require-effective-target ilp32 } */ + +struct P +{ + long long l; + int a; + unsigned int b; + P(long long x) : l(x) {} +}; + +P foo (P); +P bar (P); + +P foo (P x) +{ + P y = P (-1LL); + y = bar (x); + return y; +} + +/* { dg-final { scan-tree-dump-times "return slot optimization" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/opt/nrv13.C b/gcc/testsuite/g++.dg/opt/nrv13.C new file mode 100644 index 000000000..bb49a3a6e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv13.C @@ -0,0 +1,42 @@ +// PR tree-optimization/32353 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); + +struct A +{ + int f; + A (int x) : f (x) {} +}; + +A +foo (const A &x, const A &y) +{ + A r (0); + r = x.f == -111 ? y : (y.f == -111 || x.f > y.f) ? x : y; + A s (0); + r = r.f == -111 ? s : (r.f > s.f) ? r : s; + return r; +} + +int +main () +{ + if (foo (A (0), A (1)).f != 1) + abort (); + if (foo (A (1), A (9)).f != 9) + abort (); + if (foo (A (9), A (1)).f != 9) + abort (); + if (foo (A (-4), A (-5)).f != 0) + abort (); + if (foo (A (-111), A (-111)).f != 0) + abort (); + if (foo (A (2), A (-111)).f != 2) + abort (); + if (foo (A (-111), A (6)).f != 6) + abort (); + if (foo (A (-111), A (-4)).f != 0) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/nrv14.C b/gcc/testsuite/g++.dg/opt/nrv14.C new file mode 100644 index 000000000..22526d6b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv14.C @@ -0,0 +1,39 @@ +// PR c++/32992 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); + +struct A +{ + long int a1; + long int a2; + long int a3; +}; + +struct B +{ + long int f[3]; + operator A () + { + union + { + long int t[3]; + A a; + }; + for (int i = 0; i < 3; i++) + t[i] = f[i]; + return a; + } +}; + +int +main () +{ + B b = { {1, 3, 5} }; + A a = b; + + if (a.a1 != b.f[0] || a.a2 != b.f[1] || a.a3 != b.f[2]) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv15.C b/gcc/testsuite/g++.dg/opt/nrv15.C new file mode 100644 index 000000000..23511b284 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv15.C @@ -0,0 +1,97 @@ +// PR debug/39086 +// { dg-options "-g -O -fno-tree-sra" } + +struct A { int v; }; + +A ax; + +struct B +{ + static A f1 () { return ax; } + static bool f2 (); + static A f3 (); +}; + +struct C +{ + A f4 () + { + A x; + if (__builtin_expect (this->f6 () < this->f12 (), true)) + x = B::f1 (); + else + x = this->f7 (); + return x; + } + A f5 () + { + A y; + if (this->f6 () < this->f12 ()) + y = B::f1 (); + else + y = this->f7 (); + return y; + } + void *f6 () const; + void *f12 () const; + virtual A f7 (); +}; + +C *dx; + +struct D +{ + C *f8 () const; +}; + +class E : virtual public D +{ + void f11 (); + void f9 (); + void f10 (); +}; + +struct G +{ + explicit G (); + operator bool () const; +}; + +void +E::f11 (void) +{ + A d = B::f3 (); + d = this->f8 ()->f4 (); +} + +void +E::f9 () +{ + G c; + if (c) + { + const A e = B::f3 (); + C * f = this->f8 (); + A d = f->f5 (); + if (B::f2 ()) + ; + else if (B::f2 ()) + f->f4 (); + } +} + +void +E::f10 () +{ + G c; + if (c) + { + const A e = B::f3 (); + C * f = this->f8 (); + A d = f->f5 (); + if (B::f2 ()) + ; + else if (B::f2 ()) + f->f4 (); + } +} diff --git a/gcc/testsuite/g++.dg/opt/nrv16.C b/gcc/testsuite/g++.dg/opt/nrv16.C new file mode 100644 index 000000000..7b24d4a4e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv16.C @@ -0,0 +1,16 @@ +// PR c++/44808 +// { dg-do compile } + +struct S +{ + void *a, *b; + int c; +}; + +S +foo () +{ + S x; + S y = x; + return x; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv17.C b/gcc/testsuite/g++.dg/opt/nrv17.C new file mode 100644 index 000000000..6248bca03 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv17.C @@ -0,0 +1,32 @@ +// { dg-do run } + +#include <cstdlib> +#include <complex> + +void __attribute__((noinline)) +h(std::complex<double> x) +{ + if (x.real() != 2.0) + std::abort (); +} + +void __attribute__((noinline)) +g(std::complex<double> x) +{ + if (x.real() != 0.5) + std::abort (); +} + +void __attribute__((noinline)) +f(std::complex<double> x) +{ + h (x); + x = 1.0 / x; + g (x); +} + +int main() +{ + f(2.0); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv2.C b/gcc/testsuite/g++.dg/opt/nrv2.C new file mode 100644 index 000000000..4ffc07587 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv2.C @@ -0,0 +1,28 @@ +// Test for the named return value optimization, this time with inlining. +// { dg-do run } +// { dg-options -O2 } + +int c; +int d; + +struct A +{ + A() { ++c; } + A(const A&) { ++c; }; + ~A() { ++d; } +}; + +inline A f () +{ + A a; + return a; +} + +int main () +{ + { + A a = f (); + } + + return !(c == 1 && c == d); +} diff --git a/gcc/testsuite/g++.dg/opt/nrv3.C b/gcc/testsuite/g++.dg/opt/nrv3.C new file mode 100644 index 000000000..2ec597744 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv3.C @@ -0,0 +1,24 @@ +// PR optimization/6189 +// Bug: we forgot about foo's nrv after writing it out. +// { dg-options -O3 } +// { dg-do run } + +struct A +{ + int i; +}; + + +A foo () +{ + A a; + a.i = 42; + return a; +} + + +int main() +{ + A b = foo(); + return b.i != 42; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv4.C b/gcc/testsuite/g++.dg/opt/nrv4.C new file mode 100644 index 000000000..531647d67 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv4.C @@ -0,0 +1,23 @@ +// PR optimization/7145 +// Bug: The NRV optimization caused us to lose the initializer for 'ret'. +// { dg-options -O } +// { dg-do run } + +struct GdkColor { + long pixel; + short red; + short green; + short blue; +}; + +inline GdkColor mkcolor() { + GdkColor ret={0,1,2,3}; + return ret; +} + +int +main() +{ + GdkColor col=mkcolor(); + return (col.pixel != 0 || col.red != 1 || col.green != 2 || col.blue != 3); +} diff --git a/gcc/testsuite/g++.dg/opt/nrv5.C b/gcc/testsuite/g++.dg/opt/nrv5.C new file mode 100644 index 000000000..7c3c0591f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv5.C @@ -0,0 +1,57 @@ +// PR c++/7279 +// Test for the named return value optimization with inlining. +// Contributed by Jakub Jelinek <jakub@redhat.com>. +// { dg-do run } +// { dg-options -O2 } + +enum E { E0, E1, E2, E3 }; + +struct S +{ + E s0 : 2; + bool s1 : 1, s2 : 1, s3 : 1, s4 : 1, s5 : 1, s6 : 1; + S (); + void foo (E x); +}; + +S::S() : s1 (true), s2 (false), s0 (E1), s3 (true), s4 (false), + s5 (true), s6 (false) {} +void S::foo (E x) { this->s0 = x; } + +inline S foo () +{ + S s; + s.foo (E0); + return s; +} + +inline S bar () +{ + S s; + s.foo (E2); + return s; +} + +void check (S &s, bool isfoo); + +void test (bool isfoo) +{ + S a = isfoo ? foo () : bar (); + check (a, isfoo); +} + +extern "C" void abort (); + +void check (S &s, bool isfoo) +{ + if (! s.s1 || s.s2 || ! s.s3 || s.s4 || ! s.s5 || s.s6) + abort (); + if (s.s0 != (isfoo ? E0 : E2)) + abort (); +} + +int main () +{ + test (true); + test (false); +} diff --git a/gcc/testsuite/g++.dg/opt/nrv6.C b/gcc/testsuite/g++.dg/opt/nrv6.C new file mode 100644 index 000000000..57ff12e41 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv6.C @@ -0,0 +1,26 @@ +// PR c++/9993 +// Bug: We were failing to destroy b. + +// { dg-do run } + +int c, d; + +struct Object { + Object() { ++c; } + Object(const Object&) { ++c; } + ~Object() { ++d; } +}; + +Object function() { + int i = 0; + do { + Object b; + if (i++ == 2) + return b; + } while (1); +} + +int main() { + function(); + return c != d; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv7.C b/gcc/testsuite/g++.dg/opt/nrv7.C new file mode 100644 index 000000000..c5034ecc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv7.C @@ -0,0 +1,13 @@ +// PR c++/15461 + +struct A { + int i; +}; + +inline A foo () { + int j = 1; + A a = { j }; + return a; +} + +A tv = foo(); diff --git a/gcc/testsuite/g++.dg/opt/nrv8.C b/gcc/testsuite/g++.dg/opt/nrv8.C new file mode 100644 index 000000000..19999a188 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv8.C @@ -0,0 +1,31 @@ +// PR optimization/19531 +// forbids NRV on volatile return value. +// { dg-options -O2 } +// { dg-do run } + +extern "C" { void abort(); } + +struct A +{ + int d; + + A () { d = 123; } + A (const A & o) { d = o.d; } + A (volatile const A & o) { d = o.d + 2; } +}; + +A bar() +{ + volatile A l; + return l; +} + +main() +{ + A a = bar (); + + if (a.d != 125) + abort(); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/nrv9.C b/gcc/testsuite/g++.dg/opt/nrv9.C new file mode 100644 index 000000000..462506867 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv9.C @@ -0,0 +1,28 @@ +// PR c++/19317 +// If we do both NRV and caller-side return slot opt for ga = f() +// constructing la sets ga.i to 0 too soon. + +extern "C" void abort(); + +struct A +{ + int i; + int pad[32]; // force return in memory + A(): i(0) {} + A(int ia): i(ia) {} +}; + +A ga(42); + +A f() +{ + A la; + if (ga.i != 42) + abort(); + return la; +} + +int main() +{ + ga = f (); +} diff --git a/gcc/testsuite/g++.dg/opt/operator1.C b/gcc/testsuite/g++.dg/opt/operator1.C new file mode 100644 index 000000000..9f286b9f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/operator1.C @@ -0,0 +1,10 @@ +// Tests whether g++ can handle large number of operators +// { dg-do compile } + +#define OP0(n) struct I##n { int i; }; operator I##n (); +#define OP1(n) OP0(n) +#define OP2(n) OP1(n##0) OP1(n##1) OP1(n##2) OP1(n##3) OP1(n##4) +#define OP3(n) OP2(n##0) OP2(n##1) OP2(n##2) OP2(n##3) OP2(n##4) +struct S { + OP3(0) OP3(1) OP3(2) OP3(3) OP3(4) OP3(5) +}; diff --git a/gcc/testsuite/g++.dg/opt/placeholder1.C b/gcc/testsuite/g++.dg/opt/placeholder1.C new file mode 100644 index 000000000..a1c984263 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/placeholder1.C @@ -0,0 +1,10 @@ +// PR rtl-optimization/15159 +// { dg-options "-O2" } +struct S { S (); }; +struct P { P (S *); }; +void foo (const P &); +void bar () +{ + P p = new S; + foo (p); +} diff --git a/gcc/testsuite/g++.dg/opt/pmf1.C b/gcc/testsuite/g++.dg/opt/pmf1.C new file mode 100644 index 000000000..428e7530b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pmf1.C @@ -0,0 +1,76 @@ +// PR c++/37016 +// { dg-do run } +// { dg-options "-O2 -Wall" } + +/* + Basic design concept is that WorldObject implements remote method call + functionality using the "curiously recurring template pattern" to enable + forwarding calls from the generic base class that implements the transport + layer to the derived class. + + The specific failure was in forwarding calls to items in a container. + This is emulated here by wrapping a single item. + + In the main program there are two forms of the call. In the last + (uncommented) form the member function pointer is for clarity + assigned to a variable (itemfunptr) before making the call. + With 4.3.0 and 4.3.1 this code compiles incorrectly with -O1 or greater + to produce this warning + + reproduce.cc: In function ‘int main()’: + reproduce.cc:26: warning: ‘itemfunptr.void (Container::*)(void +(Item::*)(int), int)::__pfn’ is used uninitialized in this function + reproduce.cc:47: note: ‘itemfunptr.void (Container::*)(void (Item::*)(int), +int)::__pfn’ was declared here + + and the resulting executable segvs. It works correctly with -O0. + + With 4.2.3 and earlier it works correctly with optimization. + + In the first (commented out) form of the call in the main program + we directly refer to desired member function. This compiles + and executes correctly with all tested versions. +*/ + +extern "C" int printf (const char *, ...); + +template <class Derived> +struct WorldObject { + template <typename memfunT, typename arg1T, typename arg2T> + void forward(memfunT memfun, arg1T arg1, arg2T arg2) { + Derived* obj = static_cast<Derived*>(this); + (obj->*memfun)(arg1, arg2); + } +}; + +struct Item { + void fred(int a) { + printf ("a=%d\n", a); + } +}; + +struct Container : public WorldObject<Container> { + Item item; + template <typename itemfunT, typename arg1T> + void itemfun(itemfunT itemfun, int a) { + (item.*itemfun)(a); + } +}; + +int main() { + typedef void (Item::*itemfun)(int); + + Container t; + + // This call compiles and executes correctly with all versions tested + //t.forward(&Container::itemfun<itemfun,int>, &Item::fred, 1); + + // This call compiles with a warning and segvs on execution if using + // -O1 or greater with 4.3.*. 4.2.* is correct. + void (Container::*itemfunptr)(itemfun, int) = +&Container::itemfun<itemfun,int>; + t.forward(itemfunptr, &Item::fred, 1); + + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr13066-1.C b/gcc/testsuite/g++.dg/opt/pr13066-1.C new file mode 100644 index 000000000..67f853456 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr13066-1.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +class nsIURI; + +struct nsCOMPtr +{ + operator nsIURI*() const + { + return mRawPtr; + } + + nsIURI *mRawPtr; +}; + +void func() +{ + nsCOMPtr u1; + if (!u1 == !u1) + return; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr14029.C b/gcc/testsuite/g++.dg/opt/pr14029.C new file mode 100644 index 000000000..1673edfd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr14029.C @@ -0,0 +1,41 @@ +// { dg-do run } +// { dg-options "-O2" } +// We used to mis-compile this testcase as we did not know that +// &a+offsetof(b,a) was the same as &a.b + +struct Iterator { + int * ptr; + + Iterator(int * i) : ptr(i) { } + void operator++() { ++ptr; } + int *const & base() const { return ptr; } +}; + + +Iterator find_7(Iterator first, Iterator last) +{ + int trip_count = (last.base() - first.base()) >> 1; + + for ( ; trip_count > 0 ; --trip_count) { + if (*first.ptr == 7) return first; + ++first; + + if (*first.ptr == 7) return first; + ++first; + } + + switch(last.base() - first.base()) { + case 1: + if (*first.ptr == 7) return first; + ++first; + case 0: + default: + return last; + } +} + +int main() { + int as[5] = {4,4,4,4,7}; + return (find_7(Iterator(&as[0]), Iterator(&as[5])).ptr == &as[5]); +}; + diff --git a/gcc/testsuite/g++.dg/opt/pr14888.C b/gcc/testsuite/g++.dg/opt/pr14888.C new file mode 100644 index 000000000..e5c56aaab --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr14888.C @@ -0,0 +1,22 @@ +// PR target/14888 +// This used to ICE because the truncdfsf2 isn't completely eliminated + +// { dg-do compile } +// { dg-options "-O2 -ffast-math" } + +class xcomplex +{ +public: + float re, im; + + xcomplex &operator*= (const float &fact) + { re*=fact; im*=fact; return *this; } +}; + +void foo (xcomplex &almT, xcomplex &almG) +{ + double gb; + almT*=gb; + almG*=gb*42; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr15054-2.C b/gcc/testsuite/g++.dg/opt/pr15054-2.C new file mode 100644 index 000000000..156e945d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr15054-2.C @@ -0,0 +1,39 @@ +// PR middle-end/15054 + +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); + +void +__attribute__((noinline)) +check (long x, long y) +{ + if (x != y) + abort (); +} + +struct A +{ + A() : a(2) { check (a, 2); } + ~A() { check (a, 2); } +private: + long a; +}; + +class B { + long b; + B& operator =(const B& ); +public: + B (long p) : b(p) { check (b, 6); } + B (const B& p) : b(p.b) { check (b, 6); } + ~B () { check (b, 6); A obj; check (b, 6); } + B foo() { return B(*this); } +}; + +int main () +{ + B o(6); + o.foo().foo(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr15054.C b/gcc/testsuite/g++.dg/opt/pr15054.C new file mode 100644 index 000000000..cfc48cf24 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr15054.C @@ -0,0 +1,36 @@ +// PR middle-end/15054 +// This used to abort due to overlapping stack temporaries. + +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort (void); + +struct pointer +{ + void* ptr; + + pointer(void* x = 0) : ptr(x) {} + pointer(const pointer& x) : ptr(x.ptr) {} +}; + +struct element +{ + int canary; + + element() : canary(123) { } + ~element() { pointer(); if (canary != 123) abort (); } +}; + +inline pointer +insert(const element& x) +{ + return pointer(new element(x)); +} + +int +main (void) +{ + insert(element()); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr15551.C b/gcc/testsuite/g++.dg/opt/pr15551.C new file mode 100644 index 000000000..dc3ddc446 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr15551.C @@ -0,0 +1,26 @@ +// PR target/15551 +// This used to crash on pentium4-pc-cygwin due to an alloca problem. +// Testcase submitted by Hans Horn to mingw bug tracker +// +// { dg-do run } +// { dg-options "-O3" } + +#include <cstring> +#include <fstream> +#include <cstdio> +using namespace std; + +ostream* logfile; + +int main () { + + logfile = new ofstream("bar", ios::out); + + char expList[20000]; + strcpy(expList, "foo"); + + delete logfile; + remove ("bar"); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr16372-1.C b/gcc/testsuite/g++.dg/opt/pr16372-1.C new file mode 100644 index 000000000..b797e4ad2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr16372-1.C @@ -0,0 +1,17 @@ +// PR tree-optimization/16372 +// { dg-do run } +// { dg-options "-O1" } + +extern "C" void abort(); + +enum number {ZERO, ONE, TWO, THREE, FOUR, FIVE}; + +int main() { + number n = FIVE; + + if((n == ONE) || (n == TWO) || (n == THREE)) { + abort (); + } + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr16693-1.C b/gcc/testsuite/g++.dg/opt/pr16693-1.C new file mode 100644 index 000000000..6b716116d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr16693-1.C @@ -0,0 +1,25 @@ +// PR middle-end/16693 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort(); + +unsigned short ret6666(int) { + return 0x66; +} + +typedef enum { + a = 0x0, b = 0x1, c = 0x2, d = 0x3, e = 0x4, f = 0x5, + g = 0x6, h = 0x7, i = 0x8, j = 0x9, k = 0xa, l = 0xb, + m = 0xc, n = 0xd, o = 0xe, p = 0xf +} Test_Enum; + +int main(void) { + unsigned char r1; + r1 = static_cast<Test_Enum>(0xf & ret6666(44)); + + if(r1 != 0x6) + abort(); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr16693-2.C b/gcc/testsuite/g++.dg/opt/pr16693-2.C new file mode 100644 index 000000000..cb60df642 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr16693-2.C @@ -0,0 +1,21 @@ +// PR middle-end/16693 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort(); + +char foo() +{ + return 0x10; +} + +enum E { e = 0x0f }; + +int main() +{ + char c = (char)(E)(e & foo()); + if (c != 0) + abort(); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr17411-1.C b/gcc/testsuite/g++.dg/opt/pr17411-1.C new file mode 100644 index 000000000..62b57a5a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17411-1.C @@ -0,0 +1,21 @@ +// PR middle-end/17411 +// { dg-do compile } +// { dg-options "-O2" } + +struct CalibData { + float mean_pedestal; +}; + +struct pair +{ + CalibData second; + pair(const CalibData& __b) : second(__b) { } +}; + +void insert(const pair& __x); + +void foo() +{ + insert(pair(CalibData())); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr17624.C b/gcc/testsuite/g++.dg/opt/pr17624.C new file mode 100644 index 000000000..07fbf14da --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17624.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O2" } + +extern void foo (void); +int c; +void foo (int n) +{ + int j = 0; + try + { + for(;;) + { + foo (); + if (j ++ == n) + break; + foo (); + } + } + catch (...) + { + c = j; + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr17697-1.C b/gcc/testsuite/g++.dg/opt/pr17697-1.C new file mode 100644 index 000000000..50a75b845 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17697-1.C @@ -0,0 +1,32 @@ +// PR tree-optimization/17697 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" +{ + extern int strcmp (const char *s, const char *t) throw () + __attribute__ ((pure)); +} + +namespace A +{ + extern int strcmp (const char *s, const char *t); +} + +inline int +A::strcmp (const char *s, const char *t) +{ + return ::strcmp (s, t); +} + +int +foo (const char *x) throw () +{ + return A::strcmp ("", x); +} + +int +main () +{ + return foo ("") != 0 || foo ("a") == 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr17697-2.C b/gcc/testsuite/g++.dg/opt/pr17697-2.C new file mode 100644 index 000000000..4a746be3d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17697-2.C @@ -0,0 +1,32 @@ +// PR tree-optimization/17697 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" +{ + extern int strcmp (const char *s, const char *t) throw () + __attribute__ ((pure)); +} + +namespace A +{ + extern int strcmp (const char *s, const char *t) throw (); +} + +inline int +A::strcmp (const char *s, const char *t) throw () +{ + return ::strcmp (s, t); +} + +int +foo (const char *x) throw () +{ + return A::strcmp ("", x); +} + +int +main () +{ + return foo ("") != 0 || foo ("a") == 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr17697-3.C b/gcc/testsuite/g++.dg/opt/pr17697-3.C new file mode 100644 index 000000000..630441c25 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17697-3.C @@ -0,0 +1,28 @@ +// PR tree-optimization/17697 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" int strcmp (const char *s, const char *t); + +namespace A +{ + extern int strcmp (const char *s, const char *t); +} + +inline int +A::strcmp (const char *s, const char *t) +{ + return ::strcmp (s, t); +} + +int +foo (const char *x) +{ + return A::strcmp ("", x); +} + +int +main () +{ + return foo ("") != 0 || foo ("a") == 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr17724-1.C b/gcc/testsuite/g++.dg/opt/pr17724-1.C new file mode 100644 index 000000000..79de663b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17724-1.C @@ -0,0 +1,23 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +namespace N { char *strcpy (char *, const char *); } +extern "C" char *strcpy (char *, const char *) throw (); +inline char *N::strcpy (char *s, const char *t) { return ::strcpy (s, t); } + +struct S { ~S (); }; +int foo (); + +int +main () +{ + S s; + int a; + char b[64]; + N::strcpy (b, "ABCDEFGHIJKLM"); + while ((a = foo ()) != -1) + if (a) + return -1; + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr17724-2.C b/gcc/testsuite/g++.dg/opt/pr17724-2.C new file mode 100644 index 000000000..c9c7f2a40 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17724-2.C @@ -0,0 +1,23 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +namespace N { char *strcpy (char *, const char *); } +extern "C" char *strcpy (char *, const char *); +inline char *N::strcpy (char *s, const char *t) { return ::strcpy (s, t); } + +struct S { ~S (); }; +int foo (); + +int +main () +{ + S s; + int a; + char b[64]; + N::strcpy (b, "ABCDEFGHIJKLM"); + while ((a = foo ()) != -1) + if (a) + return -1; + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr17724-3.C b/gcc/testsuite/g++.dg/opt/pr17724-3.C new file mode 100644 index 000000000..212ab4770 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17724-3.C @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" char *strcpy (char* d, const char* s) throw (); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} diff --git a/gcc/testsuite/g++.dg/opt/pr17724-4.C b/gcc/testsuite/g++.dg/opt/pr17724-4.C new file mode 100644 index 000000000..7828a25e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17724-4.C @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" char *strcpy (char* d, const char* s); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} diff --git a/gcc/testsuite/g++.dg/opt/pr17724-5.C b/gcc/testsuite/g++.dg/opt/pr17724-5.C new file mode 100644 index 000000000..5ce303856 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17724-5.C @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern char *strcpy (char* d, const char* s) throw (); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} diff --git a/gcc/testsuite/g++.dg/opt/pr17724-6.C b/gcc/testsuite/g++.dg/opt/pr17724-6.C new file mode 100644 index 000000000..f95c4d0ef --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17724-6.C @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern char *strcpy (char* d, const char* s); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} diff --git a/gcc/testsuite/g++.dg/opt/pr17902.C b/gcc/testsuite/g++.dg/opt/pr17902.C new file mode 100644 index 000000000..fc5b6541f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr17902.C @@ -0,0 +1,26 @@ +/* { dg-options "-O3" } */ +/* { dg-do compile } */ + +void foo(); +struct A { ~A(){ foo(); } }; +struct B { A a; }; +void bar() +{ + A a; + bool b = false; + int i, j; + + + for (j=0; j<i; j++) + { + if (i) b=true; + if (j && i) foo(); + if (j && i) i++; + } + + + for (j=0; j<i; j++) + if ( !j || (j==1 && b && i) ) + B x; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr18084-1.C b/gcc/testsuite/g++.dg/opt/pr18084-1.C new file mode 100644 index 000000000..bf62a7b70 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr18084-1.C @@ -0,0 +1,32 @@ +// { dg-do run } +// { dg-options "-O3" } + +extern "C" void abort (void); + +struct X { + bool init; + void foo() { if (!init) init = true; } + void bar() { foo(); } + +}; + +typedef unsigned long long int uint64_t; +uint64_t mask1, mask2; + +uint64_t calc() { + return mask1 & mask2; +} + +int main() +{ + mask1 = 0x00000000FFFFFFFFull; + mask2 = 0x000000000000FFFFull; + uint64_t value = calc(); + + X().bar(); + + if(value != calc()) + abort (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr18683-1.C b/gcc/testsuite/g++.dg/opt/pr18683-1.C new file mode 100644 index 000000000..847a4d3c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr18683-1.C @@ -0,0 +1,29 @@ +// PR middle-end/18683 +// { dg-do compile } +// { dg-options "-O0" } + +template<typename _CharT> +struct basic_ostream +{ + basic_ostream& operator<<(int __n); +}; + +extern basic_ostream<char> cout; + +template<int> struct linear_congruential +{ + template<class CharT> + friend basic_ostream<CharT>& + operator<<(basic_ostream<CharT>& os, + const linear_congruential& lcg) + { + return os << 1; + } +}; + +void instantiate_all() +{ + linear_congruential<0> lcf; + cout << lcf; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr18968.C b/gcc/testsuite/g++.dg/opt/pr18968.C new file mode 100644 index 000000000..cce73b579 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr18968.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// { dg-options "-O1" } +struct X +{ + int i; +}; +struct Y : virtual X {}; +struct Z : Y {}; +struct A +{ + Z* p; + A(); +}; +A::A() : p(0) +{ + ((X*)(Y*)p)->i++; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr19108.C b/gcc/testsuite/g++.dg/opt/pr19108.C new file mode 100644 index 000000000..206a2bc38 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr19108.C @@ -0,0 +1,19 @@ +// PR tree-optimization/19108 +// This used to abort due to not handing RANGE_EXPR in SRA. + +// { dg-do compile } +// { dg-options "-O" } + +struct A +{ + int i[6]; + A () : i() {} +}; + +struct B +{ + A a; + B(const A& x) : a(x) {} +}; + +B b=A(); diff --git a/gcc/testsuite/g++.dg/opt/pr19317-1.C b/gcc/testsuite/g++.dg/opt/pr19317-1.C new file mode 100644 index 000000000..ffb646a90 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr19317-1.C @@ -0,0 +1,39 @@ +// PR c++/19317 +// { dg-options "-O2" } +// { dg-do run } +// Origin: Dirk Mueller <mueller@kde.org> + +extern "C" void abort (void); + +struct A +{ + A () { d = e = 0; f = -1; } + A (int x) : d (0), e (0), f (x) { } + A b (const A &r) const; + int d; + int e; + int f; +}; + +A +A::b (const A & r) const +{ + A t; + t.f = f < r.f ? f : r.f; + return t; +} + +int +main () +{ + A a (100); + a = a.b (A (10)); + if (a.f != 10) + abort (); + + A c (10); + A d (100); + c = d.b (c); + if (c.f != 10) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr19317-2.C b/gcc/testsuite/g++.dg/opt/pr19317-2.C new file mode 100644 index 000000000..70c642b21 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr19317-2.C @@ -0,0 +1,32 @@ +// PR c++/19317 +// { dg-options "-O2" } +// { dg-do run } + +extern "C" void abort (void); + +struct A +{ + A () { d = e = 0; f = -1; } + A (int x) : d (0), e (0), f (x) { } + A b () const; + int d; + int e; + int f; +}; + +A +A::b () const +{ + A t; + t.f = 10 + this->f; + return t; +} + +int +main () +{ + A a (100); + a = a.b (); + if (a.f != 110) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr19317-3.C b/gcc/testsuite/g++.dg/opt/pr19317-3.C new file mode 100644 index 000000000..b2b2bb0e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr19317-3.C @@ -0,0 +1,37 @@ +// PR c++/19317 +// { dg-options "-O2" } +// { dg-do run } + +extern "C" void abort (void); + +struct A { int c; int d; int e; int f; }; + +A +foo (const A *x, const A *r) +{ + A t; + t.c = -1; + t.c += x->c < r->c ? x->c : r->c; + t.d = 0; + t.e = 0; + t.f = 0; + return t; +} + +int +main () +{ + A a; + a.c = 10; + a.d = 0; + a.e = 0; + a.f = 0; + A b; + b.c = 100; + b.d = 0; + b.e = 0; + b.f = 0; + a = foo (&b, &a); + if (a.c != 9) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr19650.C b/gcc/testsuite/g++.dg/opt/pr19650.C new file mode 100644 index 000000000..1f495cb7d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr19650.C @@ -0,0 +1,71 @@ +// { dg-options "-O1 -w -fpermissive" } +// { dg-do run } +// Tests the fold bug described in PR 19650. +#include <stdio.h> +#include <stdlib.h> +#define test(a) ((a) ? 1 : 0) + +typedef int (*arg_cmp_func)(); + +class Item_func +{ +public: + enum Functype { UNKNOWN_FUNC, EQ_FUNC, EQUAL_FUNC }; + virtual enum Functype functype() const { return UNKNOWN_FUNC; } +}; + +class Item_bool_func2 : public Item_func +{ +public: + virtual enum Functype functype() const { return EQUAL_FUNC; } +}; + +class Arg_comparator +{ +public: + Item_bool_func2 *owner; + arg_cmp_func func; + static arg_cmp_func comparator_matrix[4][2]; + + int Arg_comparator::set_compare_func(Item_bool_func2 *item, int type) + { + owner = item; + + /****************** problematic line is here ************************/ + + func = comparator_matrix[type][test(owner->functype() == Item_func::EQUAL_FUNC)]; + return 0; + } +}; + +int compare_string() { return 0; } +int compare_e_string() { return 0; } +int compare_real() { return 0; } +int compare_e_real() { return 0; } +int compare_int_signed() { return 0; } +int compare_e_int() { return 0; } +int compare_row() { return 0; } +int compare_e_row() { return 0; } + +arg_cmp_func Arg_comparator::comparator_matrix[4][2] = + {{&compare_string, &compare_e_string}, + {&compare_real, &compare_e_real}, + {&compare_int_signed, &compare_e_int}, + {&compare_row, &compare_e_row}}; + +void myfunc (const char*p, arg_cmp_func f1, arg_cmp_func f2) __attribute__((noinline)); +void myfunc (const char*p, arg_cmp_func f1, arg_cmp_func f2) +{ + if (f1!=f2) + abort (); +} + +int main() +{ + Arg_comparator cmp; + Item_bool_func2 equal_func; + + cmp.set_compare_func(&equal_func, 0); + myfunc("cmp.func is %p (expected %p)\n", cmp.func, &compare_e_string); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr19768.C b/gcc/testsuite/g++.dg/opt/pr19768.C new file mode 100644 index 000000000..376ca9938 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr19768.C @@ -0,0 +1,29 @@ +// PR tree-opt/19768 +// tree DSE was removing one store to LL.currentLevel +// but forgot that since the vop was in an abnormal PHI +// that we have to update the SSA_NAME which we propagate +// into the abnormal PHI + +// { dg-do compile } +// { dg-options "-O" } + +struct LeveLogger +{ + int currentLevel; +}; +extern LeveLogger LL; +struct gg +{ + ~gg ( void ) + { LL.currentLevel = 1; } +}; +void f(void); +void g ( void ) +{ + gg sll; + { + gg sll; + f(); + } + f(); +} diff --git a/gcc/testsuite/g++.dg/opt/pr20931.C b/gcc/testsuite/g++.dg/opt/pr20931.C new file mode 100644 index 000000000..01518c06d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr20931.C @@ -0,0 +1,13 @@ +// PR middle-end +// This testcase ICEd because fold checking saw a type change which +// is allowed as TYPE_CONTAINS_PLACEHOLDER_INTERNAL could change. +// { dg-do compile } +// { dg-options "-O2" } + +int +__finite (double __x) throw () +{ + return (__extension__ + (((((union { double __d; int __i[2]; }) {__d: __x}).__i[1] + | 0x800fffffu) + 1) >> 31)); +} diff --git a/gcc/testsuite/g++.dg/opt/pr20991.C b/gcc/testsuite/g++.dg/opt/pr20991.C new file mode 100644 index 000000000..32b3d05c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr20991.C @@ -0,0 +1,34 @@ +// PR middle-end/20991 +// { dg-options "-O2" } +// { dg-do compile } + +struct S +{ + virtual inline int foo () const; + virtual inline bool bar () const; + virtual int baz (int) const; +}; + +inline int S::foo () const +{ + return 1; +} + +inline bool S::bar () const +{ + return foo () == 0; +} + +void A () +{ + S s; + if (s.bar ()) + s.foo (); +} + +void B () +{ + S s; + if (s.bar ()) + s.foo (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr20995-1.C b/gcc/testsuite/g++.dg/opt/pr20995-1.C new file mode 100644 index 000000000..aa9689639 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr20995-1.C @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +template<int N> void foo() +{ + double d = (N ? 0.0 : 0) + 1; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr22167.C b/gcc/testsuite/g++.dg/opt/pr22167.C new file mode 100644 index 000000000..07af74462 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr22167.C @@ -0,0 +1,32 @@ +// Derived from PR22167, which failed on some RISC targets. The call to +// foo() has two successors, one normal and one exceptional, and both +// successors use &a[0] and x. Expressions involving &a[0] can be hoisted +// before the call but those involving x cannot. +// { dg-options "-Os" } +// { dg-do run } + +int a[4]; + +struct S { + S() : x (0) {} + ~S() { a[0] = x; } + int x; +}; + +void +foo (int *x) +{ + if (*x == 1) + throw 1; + *x = 1; +} + +int +main() +{ + S s; + foo (&s.x); + if (a[0] == s.x) + a[0]++; + return a[0]; +} diff --git a/gcc/testsuite/g++.dg/opt/pr23056.C b/gcc/testsuite/g++.dg/opt/pr23056.C new file mode 100644 index 000000000..b9689ec50 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23056.C @@ -0,0 +1,9 @@ +// PR c++/23056 +// { dg-do compile } + +template <bool T> struct S { virtual ~S(); }; +void foo () +{ + static_cast<bool>("Foo"); +} +S<true> a; diff --git a/gcc/testsuite/g++.dg/opt/pr23299.C b/gcc/testsuite/g++.dg/opt/pr23299.C new file mode 100644 index 000000000..94a414aa5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23299.C @@ -0,0 +1,63 @@ +// PR rtl-optimization/23299 +// { dg-do run } +// { dg-options "-Os" } + +extern "C" void abort (); + +struct A +{ + virtual int a () {} +}; +struct B : public A +{ + virtual int b () {} +}; +struct C : public A +{ + virtual int c () {} +}; +struct D +{ + D () { d = 64; } + ~D (); + int d; +}; + +int x; +D::~D () +{ + x |= 1; + if (d != 64) + abort (); +} + +struct E : public B, public C +{ + E () {} + virtual int c (); + ~E (); + D dv; +}; + +E::~E () +{ + int r = c (); +} + +int +E::c () +{ + if (x > 10) + throw 1; + x |= 2; +} + +int +main (void) +{ + { + E e; + } + if (x != 3) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr23454-2.C b/gcc/testsuite/g++.dg/opt/pr23454-2.C new file mode 100644 index 000000000..bd5e9e99b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23454-2.C @@ -0,0 +1,106 @@ +/* PR rtl-optimization/23454 */ +/* Submitted by Matthias Klose <doko@debian.org> */ + +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +typedef unsigned long long int ulonglong; +typedef long long int longlong; +typedef unsigned int uint32; +typedef unsigned int uint; +typedef unsigned long int ulong; + +class Item { +public: + bool null_value; + virtual longlong val_int()=0; +}; + +typedef struct st_tree_element { + struct st_tree_element *left,*right; + uint32 count; +} TREE_ELEMENT; + +typedef struct st_tree { + uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated; + void *custom_arg; + bool with_delete; + uint flag; +} TREE; + +class field_info +{ +public: + ulong treemem, tree_elements, empty, nulls, min_length, max_length; + uint room_in_tree; + bool found; + TREE tree; + Item *item; +}; + +class field_ulonglong: public field_info +{ + ulonglong min_arg, max_arg; + ulonglong sum, sum_sqr; + void add(); +}; + +extern char *longlong10_to_str(longlong val,char *dst,int radix); +extern void delete_tree(TREE*); +extern TREE_ELEMENT *tree_insert(TREE *tree,void *custom_arg); + +static int compare_ulonglong(const ulonglong *s, const ulonglong *t) +{ + return ((*s < *t) ? -1 : *s > *t ? 1 : 0); +} + +void field_ulonglong::add() +{ + char buff[(255*3 +1)]; + longlong num = item->val_int(); + uint length = (uint) (longlong10_to_str(num, buff, 10) - buff); + TREE_ELEMENT *element; + + if (item->null_value) + { + nulls++; + return; + } + if (num == 0) + empty++; + + if (room_in_tree) + { + if (!(element = tree_insert(&tree, tree.custom_arg))) + { + room_in_tree = 0; + delete_tree(&tree); + } + else if (element->count == 1) + { + room_in_tree = 0; + delete_tree(&tree); + } + } + + if (!found) + { + found = 1; + min_arg = max_arg = sum = num; + sum_sqr = num * num; + min_length = max_length = length; + } + else if (num != 0) + { + sum += num; + sum_sqr += num * num; + if (length < min_length) + min_length = length; + if (length > max_length) + max_length = length; + if (compare_ulonglong((ulonglong*) &num, &min_arg) < 0) + min_arg = num; + if (compare_ulonglong((ulonglong*) &num, &max_arg) > 0) + max_arg = num; + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr23454.C b/gcc/testsuite/g++.dg/opt/pr23454.C new file mode 100644 index 000000000..ab82b1f9b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23454.C @@ -0,0 +1,41 @@ +/* PR rtl-optimization/23454 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void foo (); +int a, b; +char c; +long long d, e; + +static inline int +bar (const long long s, const long long t) +{ + return ((s < t) ? -1 : s > t ? 1 : 0); +} + +int fn (); +int f; + +void +baz (int x) +{ + long long g = fn (); + if (f) + { + b++; + return; + } + if (g == 0) + a++; + if (x) + foo (); + if (!c) + c = 1; + else if (g != 0) + { + if (bar (g, d) < 0) + d = g; + if (bar (g, e) > 0) + e = g; + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr23478.C b/gcc/testsuite/g++.dg/opt/pr23478.C new file mode 100644 index 000000000..da1371d25 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23478.C @@ -0,0 +1,211 @@ +// PR rtl-optimization/23478 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); +bool tthrow; +struct C3 { int i; }; +class C14 {}; +struct C7 +{ + virtual ~C7 (); +}; + +C7::~C7 () +{ + asm volatile ("" : : : "memory"); +} +class C2 : public C7 {}; + +template <class X> class C13 +{ + bool ma; + X *mb; +public: + explicit C13 (X *p = 0) throw () : ma (p != 0), mb (p) {} + ~C13 (); +}; + +template <class X> +C13<X>::~C13 () +{ + asm volatile ("" : : "r" (ma), "r" (mb) : "memory"); +} + +struct C1 +{ + C1 (const C3 &, const C3 &, const C3 &, const C3 *&); +}; + +C1::C1 (const C3 &, const C3 &, const C3 &, const C3 *&) +{ + if (!tthrow) + throw 24; +} + +struct C8 +{ + struct C15 {}; + typedef C15 *C9; + virtual void f1 (C2 &, long *, void *, C3 &, void *, bool) = 0; + virtual C13<C14> f3 () const = 0; + virtual ~C8 () {} +}; + +bool +xx14 () +{ + bool b = false; + if (tthrow) + throw 6; + asm volatile ("" : : "r" (&b) : "memory"); + return b; +} + +bool +xx2 () +{ + bool b = false; + if (tthrow) + throw 6; + asm volatile ("" : : "r" (&b) : "memory"); + return b; +} + +C13<C7> +xx9 () +{ + return C13<C7>(); +} + +C2 & +xx10 () +{ + static C2 c2; + return c2; +} + +C3 & +xx12 () +{ + static C3 c3 = { 1 }; + return c3; +} + +const C3 & +xx5 () +{ + static const C3 c3 = { 2 }; + return c3; +} + +const C3 *& +xx4 () +{ + static const C3 *p; + if (tthrow) + throw 6; + return p; +} + +long ll13; + +long +xx13 () +{ + long ret; + asm volatile ("" : "=r" (ret) : "r" (ll13)); + return ret; +} + +void +xx15 (C3 &x, C13<C1> &y) +{ + asm volatile ("" : : "r" (&x), "r" (&y) : "memory"); +} + +long +xx16 (const void *x) +{ + long ret; + asm volatile ("" : "=r" (ret) : "0" (1), "r" (x) : "memory"); + return ret; +} + +void +xx1 (C13<C14> x) +{ + asm volatile ("" : : "r" (&x) : "memory"); + if (tthrow) + throw 6; +} + +void +xx3 (const C7 *x) +{ + if (x) + abort (); +} + +void +xx7 () +{ + asm volatile ("" : : : "memory"); +} + +struct C5 +{ + C13<C7> f2 (C3 &v1, const void *v2, C8 *v6); + C7 *m2[2]; + long m1[2]; +}; + +C13<C7> +C5::f2 (C3 &v1, const void *v2, C8 *v6) +{ + C13<C7> v13 = xx9 (); + C2 &v9 = xx10 (); + for (long i = 1; i < 2; i++) + xx3 (m2[i]); + const C3 &ld = xx5 (); + xx7 (); + if (xx2 ()) + throw ""; + xx4 (); + C3 &si = xx12 (); + for (long i = 0; i < xx16 (v2); ++i) + { + C13<C1> sk (new C1 (xx5 (), ld, xx5 (), xx4 ())); + xx15 (si, sk); + } + long v4 = xx13 (); + for (long i = v4 - 1; i >= 0; --i) + m1[i] = i; + bool v8 = xx2 (); + for (long i = 0; i < 2 && !xx14 (); i++) + { + v6[i].f1 (v9, 0, __null, v1, __null, v8); + if (v8) + xx1 (v6[i].f3 ()); + } + return v13; +} + +int +main (void) +{ + C5 c5 = { { __null, __null }, { 0, 0 } }; + bool seen = false; + try + { + c5.f2 (xx12 (), __null, __null); + } + catch (int n) + { + if (n != 24) + abort (); + seen = true; + } + if (!seen) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr23714.C b/gcc/testsuite/g++.dg/opt/pr23714.C new file mode 100644 index 000000000..bf1b4ac5c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23714.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "-O2 -fnon-call-exceptions" } + +void run (void) { + float stack[1]; + float *sp = stack; + try + { + float value2 = ((float) *(--sp)); + float value1 = ((float) *(--sp)); + *(sp++) = (value1 - value2); + } + catch (int *ex) + { + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr24665.C b/gcc/testsuite/g++.dg/opt/pr24665.C new file mode 100644 index 000000000..646642c49 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr24665.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// { dg-options "-O2" } + +typedef unsigned long T; +typedef volatile T* const hwreg_t; +struct RegisterLayout +{ + T intmask; +}; +struct Controller_t +{ + Controller_t(); + inline void + disableInterrupt() + { + *mpMaskRegister = 0; + }; + static hwreg_t mpMaskRegister; +}; + +extern char SimulatedRegisters[]; + +hwreg_t Controller_t::mpMaskRegister + = &(reinterpret_cast<volatile RegisterLayout*>(SimulatedRegisters))->intmask; + +Controller_t::Controller_t() +{ + disableInterrupt(); +} diff --git a/gcc/testsuite/g++.dg/opt/pr24780.C b/gcc/testsuite/g++.dg/opt/pr24780.C new file mode 100644 index 000000000..7baad386b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr24780.C @@ -0,0 +1,14 @@ +// PR c++/24780 +// { dg-do compile } + +template<typename S=int> +struct Move { + Move(); + static Move<S> const MOVES[2][2]; +}; +template<typename S> + Move<S> const Move<S>::MOVES[2][2]={}; +typedef Move<int> const MoveClass; +void moves(int x, int y) { + &MoveClass::MOVES[x][y]; +} diff --git a/gcc/testsuite/g++.dg/opt/pr25005.C b/gcc/testsuite/g++.dg/opt/pr25005.C new file mode 100644 index 000000000..f62f8a2bc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr25005.C @@ -0,0 +1,34 @@ +// PR target/25005 +// { dg-options "-O2 -funroll-loops" } +// { dg-do compile } + +inline void *operator new (__SIZE_TYPE__, void *__p) throw() { return __p; } + +struct M { ~M() { } }; + +struct P +{ + P () { v[0] = 0; v[1] = 0; v[2] = 0; } + P (const P &x) { for (int i = 0; i < 3; ++i) v[i] = x.v[i]; } + double v[3]; +}; + +struct V : public M +{ + V (const P *x, const P *y) + { + P *b = this->a = ::new P[2]; + for (; x != y; ++x, ++b) + ::new (b) P(*x); + } + P *a; +}; + +void bar (const V &); + +void +foo () +{ + const P d[2] = { P(), P() }; + bar (V (&d[0], &d[2])); +} diff --git a/gcc/testsuite/g++.dg/opt/pr25857.C b/gcc/testsuite/g++.dg/opt/pr25857.C new file mode 100644 index 000000000..4e6858fe1 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr25857.C @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int foo(); +int i; + +struct A +{ + ~A() { if (this != (A*)(&i)) foo(); } +}; + +struct B +{ + A a1, a2, a3, a4; + ~B() { foo(); } +}; + +B b; diff --git a/gcc/testsuite/g++.dg/opt/pr26179.C b/gcc/testsuite/g++.dg/opt/pr26179.C new file mode 100644 index 000000000..32cd7a00e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr26179.C @@ -0,0 +1,22 @@ +/* The problem here is that Load PRE on the tree level + forgot to handle RETURN_DECL which causes us to ICE. */ + +// { dg-do compile } +// { dg-options "-O2" } + +struct a +{ + int i; +}; +void h(struct a&); +void l(void); + +struct a g(void) +{ + struct a fl; + h(fl); + if (fl.i) + l(); + fl.i+=2; + return fl; +} diff --git a/gcc/testsuite/g++.dg/opt/pr27826.C b/gcc/testsuite/g++.dg/opt/pr27826.C new file mode 100644 index 000000000..5e40f1746 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr27826.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +struct Geometry +{ + int type:16; +}; +struct Geometry get() {}; +int f() +{ + struct Geometry test; + return get().type == test.type; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr28116.C b/gcc/testsuite/g++.dg/opt/pr28116.C new file mode 100644 index 000000000..a85917c8f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr28116.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +struct QDateTime +{ + QDateTime addSecs( int secs ) const; + int t; +}; +QDateTime gridToDate(long x) +{ + QDateTime date; + date = date.addSecs(1); + return date; +} +void whatsOnAt(long x, long y) +{ + gridToDate(x); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr30590.C b/gcc/testsuite/g++.dg/opt/pr30590.C new file mode 100644 index 000000000..42ae046db --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr30590.C @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ +struct test +{ + int type; + char buffer[4242]; /* should trigger pass-by-reference */ +}; + +int flag = 0; + +struct test +reset (void) +{ + struct test retval; + retval.type = 1; + return retval; +} + +struct test +test (void) +{ + struct test result; + result.type = 0; + + for (int i = 0; i < 2; ++i) + { + struct test candidate = reset (); + if (flag) + result = candidate; + } + + return result; +} + +int +main (void) +{ + struct test result = test (); + return result.type; +} diff --git a/gcc/testsuite/g++.dg/opt/pr30965.C b/gcc/testsuite/g++.dg/opt/pr30965.C new file mode 100644 index 000000000..91bb55c05 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr30965.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ + +#include <tr1/functional> +#include <algorithm> + +extern void assign( long* variable, long v ) +{ + std::transform( variable, variable + 1, variable, + std::tr1::bind( std::plus< long >(), 0L, v ) ); +} +extern void assign( long& variable, long v ) +{ + std::transform( &variable, &variable + 1, &variable, + std::tr1::bind( std::plus< long >(), 0L, v ) ); +} + +/* { dg-final { scan-tree-dump-times ";; Function" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "variable_..D. = v_..D." 2 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/opt/pr32383.C b/gcc/testsuite/g++.dg/opt/pr32383.C new file mode 100644 index 000000000..af4161888 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr32383.C @@ -0,0 +1,20 @@ +// Testcase by Volker Reichelt <reichelt@gcc.gnu.org> + +// { dg-do compile } +// { dg-options "-O -ffast-math" } + +struct A +{ + ~A(); +}; + +double& foo(); + +inline void bar (double d) { foo() /= d; } + +void baz() +{ + A a; + bar(2); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr34036.C b/gcc/testsuite/g++.dg/opt/pr34036.C new file mode 100644 index 000000000..ecf6cf745 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr34036.C @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fnon-call-exceptions -ffast-math -fsignaling-nans" } */ +/* { dg-warning "-fassociative-math disabled" "" { target *-*-* } 1 } */ + +template <class T> +class ggStaticArray { +public: + ~ggStaticArray(); +}; + +template <class T> +class ggGrid { +public: + ggGrid() : grid() { } + ggStaticArray<T> grid; +}; + +class mrGrid { +public: + mrGrid(void); +protected: + ggGrid<int*> grid; + double multiplier; +}; + +mrGrid::mrGrid(void) +{ + double xMeasure, yMeasure, zMeasure; + double cellDimension; + + cellDimension = multiplier * (xMeasure * yMeasure * zMeasure); +} diff --git a/gcc/testsuite/g++.dg/opt/pr36185.C b/gcc/testsuite/g++.dg/opt/pr36185.C new file mode 100644 index 000000000..2ffa52f8e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr36185.C @@ -0,0 +1,24 @@ +// PR rtl-optimization/36185 +// { dg-do run } +// { dg-options "-O2 -fgcse-sm" } + +struct Base { + virtual ~Base() {} + virtual void f() = 0; +}; +struct Derived : Base { + Derived(); + virtual void f() {} +}; +struct Foo { + Foo(Base&); +}; +Derived::Derived() { + Foo foo(*this); +} +Foo::Foo(Base& base) { + base.f(); +} +int main() { + Derived d; +} diff --git a/gcc/testsuite/g++.dg/opt/pr36187.C b/gcc/testsuite/g++.dg/opt/pr36187.C new file mode 100644 index 000000000..91166940d --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr36187.C @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern "C" void abort (void); +enum SbxDataType { SbxINTEGER, SbxDECIMAL, SbxBYREF = 0x4000 }; +struct SbxValues { + union { + float nSingle; + float* pSingle; + }; + SbxDataType eType; +}; +static bool ImpPutDoubleFoo( SbxValues* p) +{ + bool bRet = false; + SbxValues aTmp; + int count = 0; +start: + switch( p->eType ) { + case SbxINTEGER: + if (count++ > 0) + abort (); + aTmp.pSingle = &p->nSingle; goto direct; + case SbxBYREF | SbxDECIMAL: + bRet = false; + break; + direct: + aTmp.eType = SbxDataType( p->eType | SbxBYREF ); + p = &aTmp; goto start; + case SbxBYREF | SbxINTEGER: + break; + default: + bRet =true; + } + return bRet; +} + +int main( int argc, char** argv ) +{ + SbxValues aTmp; + aTmp.eType = SbxINTEGER; + if ( ImpPutDoubleFoo( &aTmp ) ) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr36449.C b/gcc/testsuite/g++.dg/opt/pr36449.C new file mode 100644 index 000000000..f66598040 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr36449.C @@ -0,0 +1,70 @@ +// PR middle-end/36449 +// { dg-do run } +// { dg-options "-O3" } + +extern "C" void exit (int); +extern "C" void abort (); + +struct R +{ + short a; + short b; +}; + +struct S +{ + R e; + long f; + long g; +}; + +struct T +{ + short c; + short d; +}; + +struct U +{ + long h[0x1ffffff + 1]; + T i; +}; + +U *j; + +void __attribute__((noinline)) +bar () +{ + exit (0); +} + +void __attribute__((noinline)) +foo () +{ + S s; + + s.e.a = 36; + s.e.b = 38; + if (s.e.a == j->i.c && s.e.b == j->i.d) + bar (); +} + +int +main () +{ + try + { + j = new U; + } + catch (...) + { + return 0; + } + j->i.c = 36; + j->i.d = 38; + j->h[0] = 1; + j->h[1] = 2; + j->h[2] = 3; + foo (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr39607.C b/gcc/testsuite/g++.dg/opt/pr39607.C new file mode 100644 index 000000000..c39260dc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr39607.C @@ -0,0 +1,65 @@ +// PR rtl-optimization/39607 +// { dg-do compile } +// { dg-options "-O2" } + +void abcErrorMessage(int error); +enum AbcSurfType { + SURF_U, + SURF_V +}; +class AbcVec2d +{ +public: + double x; + double y; +}; +class AbcIval1d +{ +protected: + double m_dMin; + double m_dMax; +public: + AbcIval1d(); + AbcIval1d(double dMin, double dMax); + double GetMax() const { return m_dMax; } + double GetMin() const { return m_dMin; } +}; +inline AbcIval1d::AbcIval1d(double dMin, double dMax) +{ + if (dMin > dMax) { + abcErrorMessage(1); + } + else { + m_dMin = dMin; + m_dMax = dMax; + } +} +class AbcIval2d +{ +protected: + AbcVec2d m_vMin; + AbcVec2d m_vMax; +public: + AbcVec2d GetMax() const { return m_vMax; } + AbcVec2d GetMin() const { return m_vMin; } +}; +class AbcCone +{ +protected: + int m_uv; +public: + AbcIval2d GetNaturalUVDomain() const; + AbcIval1d GetLinearParamIval(AbcSurfType * pSurfParam) const; +}; +AbcIval1d AbcCone::GetLinearParamIval(AbcSurfType * pSurfParam) const +{ + AbcIval1d sIval; + AbcIval2d sUVDomain = GetNaturalUVDomain(); + if (m_uv) { + sIval = AbcIval1d(sUVDomain.GetMin().x,sUVDomain.GetMax().x); + } + else { + sIval = AbcIval1d(sUVDomain.GetMin().y,sUVDomain.GetMax().y); + } + return sIval; +} diff --git a/gcc/testsuite/g++.dg/opt/pr40496.C b/gcc/testsuite/g++.dg/opt/pr40496.C new file mode 100644 index 000000000..961f067af --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr40496.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-options "-O2 -fprefetch-loop-arrays -msse2" { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target sse2 { target i?86-*-* x86_64-*-* } } + +struct DOMStringHandle +{ + unsigned int fLength; + int fRefCount; +}; +static void *freeListPtr; +void foo(DOMStringHandle *dsg) +{ + int i; + for (i = 1; i < 1023; i++) + { + *(void **) &dsg[i] = freeListPtr; + freeListPtr = &dsg[i]; + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr42508.C b/gcc/testsuite/g++.dg/opt/pr42508.C new file mode 100644 index 000000000..68dd4c693 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr42508.C @@ -0,0 +1,33 @@ +// PR tree-optimization/42508 +// { dg-do run } +// { dg-options "-O1 -fipa-sra" } + +extern "C" void abort (); + +int v[10], vidx; + +struct A +{ + A *prev; + int i; + ~A() + { + v[vidx++] = i; + delete prev; + } +}; + +int +main () +{ + A *a1 = new A (); + A *a2 = new A (); + a1->prev = 0; + a1->i = 1; + a2->prev = a1; + a2->i = 2; + delete a2; + if (vidx != 2 || v[0] != 2 || v[1] != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/pr43655.C b/gcc/testsuite/g++.dg/opt/pr43655.C new file mode 100644 index 000000000..f7e370b9e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr43655.C @@ -0,0 +1,34 @@ +// PR tree-optimization/43655 +// { dg-do run } +// { dg-options "-O0 -ftree-ter" } + +extern "C" void abort (); + +struct C +{ + C (int i) : val(i) { } + C (const C& c) : val(c.val) { } + ~C (void) { val = 999; } + C& operator = (const C& c) { val = c.val; return *this; } + C& inc (int i) { val += i; return *this; } + int val; +}; + +C +f () +{ + return C (3); +} + +C +f (int i) +{ + return f ().inc (i); +} + +int +main () +{ + if (f (2).val != 5) + abort (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr44919.C b/gcc/testsuite/g++.dg/opt/pr44919.C new file mode 100644 index 000000000..e90851be3 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr44919.C @@ -0,0 +1,253 @@ +// { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } +// { dg-options "-O3 -fselective-scheduling2" } + +namespace std { + +typedef long unsigned int size_t; + +template<typename _Tp> class new_allocator { public: typedef size_t size_type; typedef _Tp* pointer; }; +template<typename _Tp> class allocator: public new_allocator<_Tp> { public: typedef size_t size_type; template<typename _Tp1> struct rebind { typedef allocator<_Tp1> other; }; }; + +class back_insert_iterator { }; +template<typename _Container> back_insert_iterator back_inserter(_Container& __x) { }; + +class vector { }; + +struct _List_node_base { }; +struct _List_node : public _List_node_base { }; +template<typename _Tp> struct _List_iterator { typedef _List_iterator<_Tp> _Self; typedef _Tp& reference; explicit _List_iterator(_List_node_base* __x) : _M_node(__x) { } reference operator*() const { } _Self& operator++() { } bool operator!=(const _Self& __x) const { return _M_node != __x._M_node; } _List_node_base* _M_node; }; +template<typename _Tp, typename _Alloc> class _List_base { protected: typedef typename _Alloc::template rebind<_List_node >::other _Node_alloc_type; struct _List_impl : public _Node_alloc_type { _List_node_base _M_node; }; _List_impl _M_impl; }; +template<typename _Tp, typename _Alloc = std::allocator<_Tp> > class list : protected _List_base<_Tp, _Alloc> { public: typedef _Tp value_type; typedef _List_iterator<_Tp> iterator; iterator begin() { } iterator end() { return iterator(&this->_M_impl._M_node); } }; + +namespace tr1 { template<typename _Tp, size_t _Nm> struct array { typedef _Tp value_type; typedef const value_type& const_reference; typedef const value_type* const_iterator; typedef size_t size_type; value_type _M_instance[_Nm ? _Nm : 1]; const_iterator begin() const { return const_iterator(&_M_instance[0]); } const_reference operator[](size_type __n) const { return _M_instance[__n]; } }; } +} + +namespace X { + +class Object { }; +struct Has_qrt { }; +template <typename F> struct qrt_or_not { typedef const typename F::result_type & type; }; +template <typename Functor, typename P1 = void> struct Qualified_result_of : qrt_or_not<Functor> { }; + +using std::tr1::array; + +template <class R_> class Point_2 : public R_::Kernel_base::Point_2 { +public: + typedef typename R_::Kernel_base::Point_2 RPoint_2; + typedef RPoint_2 Rep; + const Rep& rep() const { } +}; + +template <class R_> class Vector_2 : public R_::Kernel_base::Vector_2 { +public: + typedef typename R_::Kernel_base::Vector_2 RVector_2; + typedef RVector_2 Rep; + const Rep& rep() const { return *this; } + typedef R_ R; + typename Qualified_result_of<typename R::Compute_x_2,Vector_2>::type x() const { return R().compute_x_2_object()(*this); } + typename Qualified_result_of<typename R::Compute_y_2,Vector_2>::type y() const { return R().compute_y_2_object()(*this); } + typename Qualified_result_of<typename R::Compute_y_2,Vector_2>::type cartesian(int i) const { return (i==0) ? x() : y(); } + typename Qualified_result_of<typename R::Compute_hx_2,Vector_2>::type hx() const { return R().compute_hx_2_object()(*this); } + typename Qualified_result_of<typename R::Compute_hy_2,Vector_2>::type hy() const { return R().compute_hy_2_object()(*this); } + typename Qualified_result_of<typename R::Compute_hw_2,Vector_2>::type hw() const { return R().compute_hw_2_object()(*this); } + typename Qualified_result_of<typename R::Compute_hx_2,Vector_2>::type homogeneous(int i) const { return (i==0) ? hx() : (i==1)? hy() : hw(); } +}; + +template <class R_> class Segment_2 : public R_::Kernel_base::Segment_2 { }; +template <class R_> class Iso_rectangle_2 : public R_::Kernel_base::Iso_rectangle_2 { }; + +template <typename T, int i > const T& constant() { static const T t(i); return t; } +template <class T, class Alloc = std::allocator<T > > class Handle_for { struct RefCounted { T t; }; typedef typename Alloc::template rebind<RefCounted>::other Allocator; typedef typename Allocator::pointer pointer; pointer ptr_; public: typedef T element_type; const T * Ptr() const { return &(ptr_->t); } }; +template <class T, class Allocator> const T& get(const Handle_for<T, Allocator> &h) { return *(h.Ptr()); } + +template <class R_> class PointC2 { +public: + typedef typename R_::Vector_2 Vector_2; Vector_2 base; + typedef typename Vector_2::Cartesian_const_iterator Cartesian_const_iterator; Cartesian_const_iterator cartesian_begin() const { return base.cartesian_begin(); } +}; + +template <class R_> class VectorC2 { +public: + typedef typename R_::FT FT; + typedef array<FT, 2> Rep; + typedef typename R_::template Handle<Rep>::type Base; + Base base; + typedef typename Rep::const_iterator Cartesian_const_iterator; + const FT & x() const { return X::get(base)[0]; } + const FT & y() const { return X::get(base)[1]; } + const FT & hx() const { return x(); } + const FT & hy() const { return y(); } + const FT & hw() const { return constant<FT, 1>(); } + Cartesian_const_iterator cartesian_begin() const { return X::get(base).begin(); } +}; + +template <class R_> class SegmentC2 { }; +template <class R_> class Iso_rectangleC2 { }; + +namespace internal { + template <class K> class Segment_2_Iso_rectangle_2_pair { + public: + enum Intersection_results { NO_INTERSECTION }; + Segment_2_Iso_rectangle_2_pair(typename K::Segment_2 const *seg, typename K::Iso_rectangle_2 const *rect) ; + Intersection_results intersection_type() const; + mutable Intersection_results _result; + typename K::Point_2 _ref_point; + typename K::Vector_2 _dir; + typename K::Point_2 _isomin; + typename K::Point_2 _isomax; + mutable typename K::FT _min, _max; + }; + template <class K> Object intersection( const typename K::Segment_2 &seg, const typename K::Iso_rectangle_2 &iso, const K&) { + typedef Segment_2_Iso_rectangle_2_pair<K> is_t; is_t ispair(&seg, &iso); switch (ispair.intersection_type()) { } + } + template <class K> typename Segment_2_Iso_rectangle_2_pair<K>::Intersection_results Segment_2_Iso_rectangle_2_pair<K>::intersection_type() const { + typedef typename K::RT RT; + typedef typename K::FT FT; + typename K::Construct_cartesian_const_iterator_2 construct_cccit; + typename K::Cartesian_const_iterator_2 ref_point_it = construct_cccit(_ref_point); + typename K::Cartesian_const_iterator_2 end = construct_cccit(_ref_point, 0); + typename K::Cartesian_const_iterator_2 isomin_it = construct_cccit(_isomin); + typename K::Cartesian_const_iterator_2 isomax_it = construct_cccit(_isomax); + for (unsigned int i=0; ref_point_it != end; ++i, ++ref_point_it, ++isomin_it, ++isomax_it) { + if (_dir.homogeneous(i) == RT(0)) { + if ( *(ref_point_it) <*(isomin_it) ) { + _result = NO_INTERSECTION; + } + if ( *(ref_point_it) > *(isomax_it)) { + _result = NO_INTERSECTION; + } + } else { + FT newmin, newmax; + if (_dir.homogeneous(i) > RT(0)) { + newmin = ( *(isomin_it) - (*ref_point_it)) / _dir.cartesian(i); + newmax = ( *(isomax_it) - (*ref_point_it)) / _dir.cartesian(i); + } else { + newmin = ( (*isomax_it) - (*ref_point_it)) / _dir.cartesian(i); + newmax = ( (*isomin_it) - (*ref_point_it)) / _dir.cartesian(i); + } + if (newmin > _min) _min = newmin; + if (newmax <_max) _max = newmax; + if (_max <_min) { return _result; } + } + } + } +} + +template <class K> Object intersection(const Segment_2<K> &seg, const Iso_rectangle_2<K> &iso) { typedef typename K::Intersect_2 Intersect; return Intersect()(seg, iso); } + +namespace CommonKernelFunctors { + template <typename K> class Construct_cartesian_const_iterator_2 { + typedef typename K::Point_2 Point_2; + typedef typename K::Cartesian_const_iterator_2 Cartesian_const_iterator_2; +public: + typedef Cartesian_const_iterator_2 result_type; + Cartesian_const_iterator_2 operator()( const Point_2& p) const { return p.rep().cartesian_begin(); } + Cartesian_const_iterator_2 operator()( const Point_2& p, int) const { } + }; + template <typename K> class Intersect_2 { + typedef typename K::Object_2 Object_2; + public: + typedef Object_2 result_type; + template <class T1, class T2> Object_2 operator()(const T1& t1, const T2& t2) const { return internal::intersection(t1, t2, K()); } + }; +} + +namespace CartesianKernelFunctors { + using namespace CommonKernelFunctors; + template <typename K> class Compute_x_2 : Has_qrt { + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + public: + typedef FT result_type; + const result_type & operator()(const Vector_2& v) const { return v.rep().x(); } + }; + template <typename K> class Compute_y_2 : Has_qrt { + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + public: + typedef FT result_type; + const result_type & operator()(const Vector_2& v) const { return v.rep().y(); } + }; + template <typename K> class Compute_hx_2 : public Has_qrt { + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + public: + typedef FT result_type; + const result_type & operator()(const Vector_2& v) const { return v.rep().hx(); } + }; + template <typename K> class Compute_hy_2 : public Has_qrt { + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + public: + typedef FT result_type; + const result_type & operator()(const Vector_2& v) const { return v.rep().hy(); } + }; + template <typename K> class Compute_hw_2 : public Has_qrt { + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + public: + typedef FT result_type; + const result_type & operator()(const Vector_2& v) const { return v.rep().hw(); } + }; +} + +template <typename K_, typename FT_> struct Cartesian_base { + typedef K_ Kernel; + typedef X::Object Object_2; + typedef PointC2<Kernel> Point_2; + typedef VectorC2<Kernel> Vector_2; + typedef SegmentC2<Kernel> Segment_2; + typedef Iso_rectangleC2<Kernel> Iso_rectangle_2; + typedef typename array<FT_, 2>::const_iterator Cartesian_const_iterator_2; +}; + +template <typename K_base, typename Kernel_ > struct Type_equality_wrapper : public K_base { + typedef K_base Kernel_base; + typedef X::Point_2<Kernel_> Point_2; + typedef X::Vector_2<Kernel_> Vector_2; + typedef X::Segment_2<Kernel_> Segment_2; + typedef X::Iso_rectangle_2<Kernel_> Iso_rectangle_2; +}; + +template <typename FT_, typename Kernel_ > struct Cartesian_base_ref_count : public Cartesian_base<Kernel_, FT_ > { + typedef FT_ RT; + typedef FT_ FT; + template <typename T > struct Handle { typedef Handle_for<T> type; }; + typedef Kernel_ K; + typedef CartesianKernelFunctors::Compute_x_2<K> Compute_x_2; + Compute_x_2 compute_x_2_object() const { } + typedef CartesianKernelFunctors::Compute_y_2<K> Compute_y_2; + Compute_y_2 compute_y_2_object() const { } + typedef CartesianKernelFunctors::Compute_hx_2<K> Compute_hx_2; + Compute_hx_2 compute_hx_2_object() const { } + typedef CartesianKernelFunctors::Compute_hy_2<K> Compute_hy_2; + Compute_hy_2 compute_hy_2_object() const { } + typedef CartesianKernelFunctors::Compute_hw_2<K> Compute_hw_2; + Compute_hw_2 compute_hw_2_object() const { } + typedef CartesianKernelFunctors::Construct_cartesian_const_iterator_2<K> Construct_cartesian_const_iterator_2; + typedef CartesianKernelFunctors::Intersect_2<K> Intersect_2; +}; + +template <typename FT_ > struct Cartesian : public Type_equality_wrapper<Cartesian_base_ref_count<FT_, Cartesian<FT_> >, Cartesian<FT_> > { }; + +template <class Kernel> class Ipelet_base { +public: + typedef typename X::Point_2<Kernel> Point_2; + typedef typename Kernel::Segment_2 Segment_2; + typedef typename Kernel::Iso_rectangle_2 Iso_rectangle_2; + + Iso_rectangle_2 read_active_objects () const { } + struct Voronoi_from_tri{ std::list<Segment_2> seg_list; }; + + template <class T,class output_iterator> bool cast_into_seg(const T& obj,const Iso_rectangle_2& bbox,output_iterator out_it) const{ X::intersection(obj,bbox); } + template<class iterator,class output_iterator> void cast_into_seg(const iterator first,const iterator end, const Iso_rectangle_2& bbox, output_iterator out_it) const { for (iterator it=first; it!=end; ++it) cast_into_seg(*it,bbox,out_it); } + void draw_dual_(Voronoi_from_tri& v_recup,const Iso_rectangle_2& bbox) const { std::vector seg_cont; cast_into_seg(v_recup.seg_list.begin(),v_recup.seg_list.end(),bbox,std::back_inserter(seg_cont)); } + void draw_dual_in_ipe(const Iso_rectangle_2& bbox) const { Voronoi_from_tri v_recup; draw_dual_(v_recup,bbox); } +}; + +typedef X::Cartesian<double> Kernel; + +class diagrammeIpelet : public X::Ipelet_base<Kernel> { void protected_run(); }; +void diagrammeIpelet::protected_run() { Iso_rectangle_2 bbox = read_active_objects( ); draw_dual_in_ipe(bbox); } + +} diff --git a/gcc/testsuite/g++.dg/opt/pr45316.C b/gcc/testsuite/g++.dg/opt/pr45316.C new file mode 100644 index 000000000..74ad30ead --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr45316.C @@ -0,0 +1,28 @@ +// { dg-do compile } +// { dg-options "-O1 -ftree-pre -fnon-call-exceptions" } + +struct A +{ + int i; +}; + +struct B : A +{ + int i[6]; + B (int = 0) : A () + { + m (); + } + int m (); +}; + +struct C : B +{ +}; + +void +foo () +{ + new C (); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr45412.C b/gcc/testsuite/g++.dg/opt/pr45412.C new file mode 100644 index 000000000..e374f52b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr45412.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "-O2 -fipa-cp-clone -ftracer" } + +int foo (int *); +void bar (); + +struct S +{ + virtual int vm (); + ~S (); +}; + +int +S::vm () +{ + int state; + switch (foo (&state)) + { + case 0: + bar (); + case 1: + delete this; + } + return state; +} + diff --git a/gcc/testsuite/g++.dg/opt/pr46640.C b/gcc/testsuite/g++.dg/opt/pr46640.C new file mode 100644 index 000000000..0892c9ac8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr46640.C @@ -0,0 +1,44 @@ +// { dg-do compile { target x86_64-*-* } } +// { dg-options "-fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -fno-exceptions -O" } + +struct QBasicAtomicInt +{ + int i, j; + bool deref () + { + asm volatile ("":"=m" (i), "=qm" (j)); + } +}; + +struct Data +{ + QBasicAtomicInt ref; + void *data; +}; + +struct QByteArray +{ + Data * d; + ~QByteArray () + { + d->ref.deref (); + } +}; + +int indexOf (unsigned); +int stat (void *, int *); +QByteArray encodeName (); + +bool makeDir (unsigned len) +{ + unsigned i = 0; + while (len) + { + int st; + int pos = indexOf (i); + QByteArray baseEncoded = encodeName (); + if (stat (baseEncoded.d->data, &st) && stat (baseEncoded.d, &st)) + return false; + i = pos; + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr46649.C b/gcc/testsuite/g++.dg/opt/pr46649.C new file mode 100644 index 000000000..1428e8bdd --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr46649.C @@ -0,0 +1,9 @@ +// { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } +// { dg-options "-fschedule-insns -fselective-scheduling" } + +void foo () +{ + for (;;) + for (;;({break;})) + ; +} diff --git a/gcc/testsuite/g++.dg/opt/pr46864.C b/gcc/testsuite/g++.dg/opt/pr46864.C new file mode 100644 index 000000000..0f7b7d2f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr46864.C @@ -0,0 +1,26 @@ +// PR tree-optimization/46864 +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions" } + +int baz (); + +struct S +{ + int k; + bool bar () throw () + { + int m = baz (); + for (int i = 0; i < m; i++) + k = i; + return m; + } +}; + +extern S *s; + +void +foo () +{ + while (baz () && s->bar ()) + ; +} diff --git a/gcc/testsuite/g++.dg/opt/pr47036.C b/gcc/testsuite/g++.dg/opt/pr47036.C new file mode 100644 index 000000000..d6d5adc6a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47036.C @@ -0,0 +1,10 @@ +// { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } +// { dg-options "-fschedule-insns -fselective-scheduling -fno-dce" } + + +void foo () +{ + for (;;) + for (;;({break;})); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr47280.C b/gcc/testsuite/g++.dg/opt/pr47280.C new file mode 100644 index 000000000..01ca48439 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47280.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions -ftrapv" } + +void bar (int n, char *p) +{ + try + { + n++; + for (int i = 0; i < n - 1; i++) + p[i]; + } + catch (...) + {} +} + diff --git a/gcc/testsuite/g++.dg/opt/pr47355.C b/gcc/testsuite/g++.dg/opt/pr47355.C new file mode 100644 index 000000000..4fdbd9f59 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47355.C @@ -0,0 +1,39 @@ +// PR tree-optimization/47355 +// { dg-do compile } +// { dg-options "-O -fipa-cp -fipa-cp-clone" } + +struct T +{ + T (); + void *p; + ~T (); +}; + +void foo (T *i); + +T *bar (); +void baz (T *); + +struct V +{ + long q; + T *r; + ~V () + { + while (q) + { + foo (r); + ++r; + --q; + } + baz (r); + } +}; + +void +foo () +{ + V v; + T t; + v.r = bar (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr47366.C b/gcc/testsuite/g++.dg/opt/pr47366.C new file mode 100644 index 000000000..e133edfbf --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47366.C @@ -0,0 +1,22 @@ +// PR rtl-optimization/47366 +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions -fno-tree-ccp -fno-tree-forwprop" } + +struct A +{ + int i; + virtual ~A (); +}; + +struct B : virtual A +{}; + +struct C : B +{ + void bar () {} +}; + +void foo () +{ + C ().bar (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr47615.C b/gcc/testsuite/g++.dg/opt/pr47615.C new file mode 100644 index 000000000..bbbcbe1e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47615.C @@ -0,0 +1,711 @@ +// { dg-do compile } +// { dg-options "-O -fstrict-aliasing -ftree-pre -fno-tree-fre -fno-tree-sra" } + +typedef __SIZE_TYPE__ size_t; +namespace std +{ + template < class _T1, class > struct pair + { + _T1 first; + }; +} +namespace __gnu_cxx +{ + template < typename _Tp > class new_allocator + { + public: + typedef size_t size_type; + typedef _Tp * pointer; + typedef _Tp const_pointer; + typedef _Tp & reference; + typedef const _Tp & const_reference; + template < typename _Tp1 > struct rebind + { + typedef new_allocator < _Tp1 > other; + }; + }; +} +namespace std +{ +template < typename _Tp > class allocator: + public __gnu_cxx::new_allocator < _Tp > + {}; + template < typename, typename, typename > struct binary_function; + template < typename _Tp > struct less:binary_function < _Tp, _Tp, bool > + {}; +} +namespace __gnu_cxx +{ + namespace typelist + { + struct null_type; + template < typename Root > struct node + { + typedef Root root; + }; + template < typename, typename > struct chain; + namespace detail + { + template < typename, int >struct chain_at_index_; + template + < + typename + Hd, typename Tl > struct chain_at_index_ <chain < Hd, Tl >, 0 > + { + typedef Hd type; + }; + template + < + typename + Hd, typename Tl, int i > struct chain_at_index_ <chain < Hd, Tl >, i > + { + typedef typename chain_at_index_ < Tl, i - 1 >::type type; + }; + } + template < typename Typelist, int i > struct at_index + { + typedef typename Typelist::root root_type; + typedef detail::chain_at_index_ < root_type, i > index_type; + typedef typename index_type::type type; + }; + template < typename T1, typename T2 > struct create2 + { + typedef node < chain < T1, chain < T2, null_type > > >type; + }; + } +} +namespace std +{ + namespace tr1 + { + template < typename _Tp, _Tp __v > struct integral_constant + { + static const _Tp value = __v; + }; + typedef integral_constant < bool, false > false_type; + template < typename, typename > struct is_same:false_type + {}; + } +} +using std::tr1::is_same; +namespace __gnu_pbds +{ + struct null_mapped_type; + struct rb_tree_tag; + namespace detail + { + template < typename, typename, typename > struct basic_tree_policy_base; + template + < + typename + Const_Node_Iterator, + typename + Allocator + > + struct + basic_tree_policy_base + <Const_Node_Iterator, Const_Node_Iterator, Allocator > + {}; + } + template + < typename, typename, typename, typename > struct null_tree_node_update; +template < typename Const_Node_Iterator, typename Node_Iterator, typename, typename Allocator > class tree_order_statistics_node_update: + detail::basic_tree_policy_base + < Const_Node_Iterator, Node_Iterator, Allocator > + { + public: + typedef Allocator allocator_type; + typedef typename allocator_type::size_type size_type; + typedef size_type metadata_type; + typedef Const_Node_Iterator const_node_iterator; + typedef Node_Iterator node_iterator; + typedef + typename + allocator_type::template + rebind < metadata_type >::other::reference metadata_reference; + void operator () (node_iterator, const_node_iterator) const; + }; + template + < + typename + Const_Node_Iterator, + class + Node_Iterator, + class + Cmp_Fn, + class + Allocator + > + inline + void + tree_order_statistics_node_update + < + Const_Node_Iterator, + Node_Iterator, + Cmp_Fn, + Allocator + >::operator + () (node_iterator node_it, const_node_iterator end_nd_it) const + { + node_iterator l_child_it; + size_type + l_rank = (l_child_it == end_nd_it) ? : l_child_it.get_metadata (); + node_iterator r_child_it = node_it.get_r_child (); + size_type + r_rank = (r_child_it == end_nd_it) ? : r_child_it.get_metadata (); + const_cast + < metadata_reference > (node_it.get_metadata ()) = l_rank + r_rank; + } + namespace + { + template < typename, typename, typename, bool > struct value_type_base; + template + < + typename + Key, + typename + Allocator + > struct value_type_base <Key, null_mapped_type, Allocator, false > + { + typedef Key value_type; + typedef + typename + Allocator::template rebind < value_type >::other value_type_allocator; + typedef typename value_type_allocator::pointer pointer; + typedef typename value_type_allocator::const_pointer const_pointer; + typedef typename value_type_allocator::reference reference; + typedef typename value_type_allocator::const_reference const_reference; + }; + template + < + typename + Key, + typename + Mapped, typename Alloc, bool Store_Extra > struct vt_base_selector + { + typedef value_type_base < Key, Mapped, Alloc, Store_Extra > type; + }; + template + < + typename + Key, + typename + Mapped, + typename + Alloc, + bool + Store_Extra + > + struct + types_traits:vt_base_selector < Key, Mapped, Alloc, Store_Extra >::type + {}; + template < typename, class, class > struct dumconst_node_iterator; + template + < + typename + Key, + typename + Mapped, + class, + class + Node_And_It_Traits, class Allocator > class bin_search_tree_no_data_ + { + protected: + typedef + typename + Allocator::template + rebind + < typename Node_And_It_Traits::node >::other::pointer node_pointer; + typedef + typename + types_traits + < Key, Mapped, Allocator, false >::const_reference const_reference; + typedef typename Node_And_It_Traits::point_iterator point_iterator; + typedef typename Node_And_It_Traits::node_update node_update; + void rotate_right (node_pointer); + template + < + typename + Node_Update_ > void apply_update (node_pointer, Node_Update_ *); + }; + template + < + typename + Key, + typename + Mapped, + class + Cmp_Fn, + class + Node_And_It_Traits, + class + Allocator + > + void + bin_search_tree_no_data_ + < + Key, + Mapped, + Cmp_Fn, Node_And_It_Traits, Allocator >::rotate_right (node_pointer p_x) + { + node_pointer p_y = p_x->m_p_parent; + p_y->m_p_right = p_x; + apply_update (p_x, this); + apply_update (p_x->m_p_parent, (node_update *) this); + } + template + < + typename + Key, + typename + Mapped, + class + Cmp_Fn, + class + Node_And_It_Traits, + class + Allocator + > + template + < + typename + Node_Update_ + > + void + bin_search_tree_no_data_ + < + Key, + Mapped, + Cmp_Fn, + Node_And_It_Traits, + Allocator >::apply_update (node_pointer p_nd, Node_Update_ *) + { + node_update ()((p_nd), ((0))); + } + } + namespace detail + { + template < typename Key, typename Mapped, typename Cmp_Fn, typename Node_And_It_Traits, typename Allocator > class rb_tree_no_data_: + bin_search_tree_no_data_ + < Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator > + { + typedef + bin_search_tree_no_data_ + < Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator > base_type; + typedef typename base_type::node_pointer node_pointer; + public: + typedef typename base_type::const_reference const_reference; + typedef typename base_type::point_iterator point_iterator; + std::pair < point_iterator, bool > insert (const_reference); + void insert_fixup (node_pointer); + }; + template + < + typename + Key, + typename + Mapped, + typename + Cmp_Fn, + typename + Node_And_It_Traits, + typename + Allocator + > + std::pair + < + typename + rb_tree_no_data_ + < + Key, + Mapped, + Cmp_Fn, + Node_And_It_Traits, + Allocator + >::point_iterator, + bool + > + rb_tree_no_data_ + < + Key, + Mapped, + Cmp_Fn, Node_And_It_Traits, Allocator >::insert (const_reference) + { + std::pair < point_iterator, bool > ins_pair; +{ + insert_fixup (ins_pair.first.m_p_nd); + } + } + template + < + typename + Key, + typename + Mapped, + typename + Cmp_Fn, + typename + Node_And_It_Traits, + typename + Allocator + > + void + rb_tree_no_data_ + < + Key, + Mapped, + Cmp_Fn, + Node_And_It_Traits, Allocator >::insert_fixup (node_pointer p_nd) + { +{ +{ +{ + rotate_right (p_nd); + } + } + } + } + template + < + typename, + typename, typename, typename, typename > struct container_base_dispatch; + template + < + typename + Key, + typename + Policy_Tl, + typename + Alloc + > + struct + container_base_dispatch + <Key, null_mapped_type, rb_tree_tag, Policy_Tl, Alloc > + { + typedef __gnu_cxx::typelist::at_index < Policy_Tl, 0 > at0; + typedef typename at0::type at0t; + typedef __gnu_cxx::typelist::at_index < Policy_Tl, 1 > at1; + typedef typename at1::type at1t; + typedef + rb_tree_no_data_ < Key, null_mapped_type, at0t, at1t, Alloc > type; + }; + template + < + typename + Node_Pointer, + typename, + typename, + typename, + typename, typename, bool, class > class bin_search_tree_const_it_ + { + public: + Node_Pointer m_p_nd; + }; + template + < + typename + Node, + class + Const_Iterator, + class Iterator, class Allocator > class bin_search_tree_const_node_it_ + { + typedef + typename + Allocator::template rebind < Node >::other::pointer node_pointer; + public: + typedef typename Node::metadata_type metadata_type; + typedef + typename + Allocator::template + rebind + < metadata_type >::other::const_reference const_metadata_reference; + bin_search_tree_const_node_it_ (node_pointer p_nd): + m_p_nd ((p_nd)) + {} + const_metadata_reference get_metadata () + { + return (m_p_nd->get_metadata ()); + } + bin_search_tree_const_node_it_ () + {} + bin_search_tree_const_node_it_ + < Node, Const_Iterator, Iterator, Allocator > get_r_child () + { + return ((m_p_nd->m_p_right)); + } + bool operator == (bin_search_tree_const_node_it_) + {} + node_pointer m_p_nd; + }; + template + < + typename, + typename, + class, + template + < + typename, + class, + class, class > class, class, class > struct bin_search_tree_traits; + template + < + typename + Key, + class + Cmp_Fn, + template + < + typename, + class, + class, + class + > + class + Node_Update, + class + Node, + class + Allocator + > + struct + bin_search_tree_traits + <Key, null_mapped_type, Cmp_Fn, Node_Update, Node, Allocator > + { + typedef + types_traits < Key, null_mapped_type, Allocator, false > type_traits; + typedef Node node; + typedef + bin_search_tree_const_it_ + < + typename + Allocator::template + rebind + < + node + >::other::pointer, + typename + type_traits::value_type, + typename + type_traits::pointer, + typename + type_traits::const_pointer, + typename + type_traits::reference, + typename + type_traits::const_reference, true, Allocator > const_point_iterator; + typedef const_point_iterator point_iterator; + typedef + bin_search_tree_const_node_it_ + < + Node, + const_point_iterator, point_iterator, Allocator > const_node_iterator; + typedef const_node_iterator node_iterator; + typedef + Node_Update + < const_node_iterator, node_iterator, Cmp_Fn, Allocator > node_update; + }; + template < typename Node_Update, bool > struct tree_metadata_helper + { + typedef typename Node_Update::metadata_type type; + }; + template + < + typename + Key, + typename + Data, + class + Cmp_Fn, + template + < + typename, + class, + class, + class + > + class Node_Update, class Allocator > struct tree_node_metadata_selector + { + typedef + dumconst_node_iterator < Key, Data, Allocator > dumconst_node_it; + enum + { + null_update = is_same < Node_Update < dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator >, + null_tree_node_update < dumconst_node_it, + dumconst_node_it, + Cmp_Fn, + Allocator > >::value + }; + typedef + typename + tree_metadata_helper + < + Node_Update + < + dumconst_node_it, + dumconst_node_it, Cmp_Fn, Allocator >, null_update >::type type; + }; + template + < + typename, + typename, + class, + template + < + typename, + class, class, class > class, class, class > struct tree_traits; + template < typename Value_Type, class Metadata, class Allocator > struct rb_tree_node_ + { + typedef Metadata metadata_type; + typedef + typename + Allocator::template + rebind + < + rb_tree_node_ + < Value_Type, Metadata, Allocator > >::other::pointer node_pointer; + typedef + typename + Allocator::template + rebind < metadata_type >::other::reference metadata_reference; + metadata_reference get_metadata () + { + return m_metadata; + } + node_pointer m_p_right; + node_pointer m_p_parent; + metadata_type m_metadata; + }; + template + < + typename + Key, + typename + Mapped, + typename + Cmp_Fn, + template + < + typename, + class, + class, + class + > + class + Node_Update, + typename + Allocator + > + struct + tree_traits + <Key, + Mapped, + Cmp_Fn, + Node_Update, + rb_tree_tag, + Allocator + >:bin_search_tree_traits + < + Key, + Mapped, + Cmp_Fn, + Node_Update, + rb_tree_node_ + < + typename + types_traits + < + Key, + Mapped, + Allocator, + false + >::value_type, + typename + tree_node_metadata_selector + < + Key, + Mapped, Cmp_Fn, Node_Update, Allocator >::type, Allocator >, Allocator > + {}; + } +template < typename Key, typename Mapped, typename Tag, typename Policy_Tl, typename Allocator > class container_base: + public + detail::container_base_dispatch + < Key, Mapped, Tag, Policy_Tl, Allocator >::type + {}; +template < typename Key, typename Mapped, typename Tag, typename, typename Policy_Tl, typename Allocator > class basic_tree: + public + container_base < Key, Mapped, Tag, Policy_Tl, Allocator > + {}; + template + < + typename + Key, + typename + Mapped, + typename + Cmp_Fn + = + std::less + < + Key + >, + typename + Tag + = + rb_tree_tag, + template + < + typename, + typename, + typename, + typename + > + class + Node_Update + = + null_tree_node_update, + typename + Allocator + = + std::allocator + < + char + > >class + tree:public + basic_tree + < + Key, + Mapped, + Tag, + detail::tree_traits + < + Key, + Mapped, + Cmp_Fn, + Node_Update, + Tag, + Allocator + >, + typename + __gnu_cxx::typelist::create2 + < + Cmp_Fn, + detail::tree_traits + < Key, Mapped, Cmp_Fn, Node_Update, Tag, Allocator > >::type, Allocator > + {}; +} +using namespace std; +using namespace __gnu_pbds; +typedef + tree + < + int, + null_mapped_type, + less < int >, rb_tree_tag, tree_order_statistics_node_update > set_t; +main () +{ + set_t s; + s.insert (12); +} diff --git a/gcc/testsuite/g++.dg/opt/pr47632.C b/gcc/testsuite/g++.dg/opt/pr47632.C new file mode 100644 index 000000000..4b0572a61 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47632.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions -ftrapv" } + +template < typename > struct S +{ + int n; + void bar () + { + int *i = new int[n]; + } +}; + +void +foo (S < char >*s) +{ + s->bar (); +} + diff --git a/gcc/testsuite/g++.dg/opt/pr47639.c b/gcc/testsuite/g++.dg/opt/pr47639.c new file mode 100644 index 000000000..6ee8bb7de --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr47639.c @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-options "-fnon-call-exceptions" } + +typedef int __attribute__ ((vector_size (8))) vec; + +vec foo (vec v1, vec v2) +{ + try + { + return v1 / v2; + } + catch (...) + { + throw; + } +} + diff --git a/gcc/testsuite/g++.dg/opt/pr48273.C b/gcc/testsuite/g++.dg/opt/pr48273.C new file mode 100644 index 000000000..4c5108bdd --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr48273.C @@ -0,0 +1,10 @@ +// { dg-do compile { target x86_64-*-* } } +// { dg-options "-fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -funroll-all-loops -march=core2" } + +void bar (); + +void foo () +{ + for (;;) + bar (); +} diff --git a/gcc/testsuite/g++.dg/opt/pr48549.C b/gcc/testsuite/g++.dg/opt/pr48549.C new file mode 100644 index 000000000..30799ee93 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr48549.C @@ -0,0 +1,63 @@ +// PR rtl-optimization/48549 +// { dg-do compile } +// { dg-options "-fcompare-debug -O2" } + +void +foo (void *from, void *to) +{ + long offset = reinterpret_cast <long>(to) - reinterpret_cast <long>(from); + if (offset != static_cast <int>(offset)) + *(int *) 0xC0DE = 0; + reinterpret_cast <int *>(from)[1] = offset; +} +struct A +{ + A () : a () {} + A (void *x) : a (x) {} + void *bar () { return a; } + void *a; +}; +struct C; +struct D; +struct E : public A +{ + C m1 (int); + D m2 (); + E () {} + E (A x) : A (x) {} +}; +struct C : public E +{ + C () {} + C (void *x) : E (x) {} +}; +struct D : public E +{ + D (void *x) : E (x) {} +}; +C +E::m1 (int x) +{ + return (reinterpret_cast <char *>(bar ()) + x); +} +D +E::m2 () +{ + return reinterpret_cast <char *>(bar ()); +} +struct B +{ + E a; + unsigned b : 16; + unsigned c : 1; +}; +void +baz (B *x) +{ + for (unsigned i = 0; i < 64; i++) + { + D d = x[i].a.m2 (); + C c = x[i].a.m1 (x[i].c); + foo (d.bar (), c.bar ()); + } +} diff --git a/gcc/testsuite/g++.dg/opt/pr48967.C b/gcc/testsuite/g++.dg/opt/pr48967.C new file mode 100644 index 000000000..db2ea5474 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr48967.C @@ -0,0 +1,98 @@ +// PR debug/48967 +// { dg-do compile } +// { dg-options "-g -O2" } + +template <typename> struct A; +template <typename T> struct A <T *> +{ + typedef T ref; +}; +template <typename T, typename> struct B +{ + typedef A <T> t; + typedef typename t::ref ref; + ref operator * () { return ref (); } +}; +template <typename T> struct I +{ + typedef T *cp; + template <typename T1> struct J + { + typedef I <T1> other; + }; +}; +template <typename T> struct S : public I <T> +{ +}; +template <typename T, typename _A> struct E +{ + typedef typename _A::template J <T>::other at; +}; +template <typename T, typename _A = S <T> > struct D +{ + typedef E <T, _A> _Base; + typedef typename _Base::at at; + typedef typename at::cp cp; + typedef B <cp, D> H; +}; +template <class T> struct F +{ + T *operator -> () { return __null; } +}; +template <typename T> long +lfloor (T x) +{ + return static_cast <long>(x) - (x && x != static_cast <long>(x)); +} +template <typename T> long +lround (T x) +{ + return lfloor (x - 0.5) + 1; +} +class M; +template <typename> class P; +typedef P <M> Q; +template <typename> struct P +{ + float x (); +}; +struct CV +{ + Q c; +}; +struct C +{ + void foo (const CV &) const; + class O; + typedef D <F <O> > R; + R n; +}; +struct S3 +{ + S3 (int, int); +}; +struct S2 +{ + S3 sx, sy; + S2 (int x = 0, int y = 0, int s = 0, int t = 0) : sx (x, y), sy (s, t) {} +}; +template <typename> struct N +{ + int bar (); +}; +struct C::O +{ + N <float> o; + void foo (CV r, int) + { + Q c = r.c; + float t = 0.5 * (o.bar ()); + S2 (lround (c.x ()), t); + } +}; +void +C::foo (const CV &w) const +{ + R::H m; + (*m)->foo (w, 8); +} diff --git a/gcc/testsuite/g++.dg/opt/pr49264.C b/gcc/testsuite/g++.dg/opt/pr49264.C new file mode 100644 index 000000000..dc23740f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr49264.C @@ -0,0 +1,19 @@ +// PR c++/49264 +// { dg-do compile } +// { dg-options "-O2" } + +struct B { }; +struct A { char a[sizeof (B) + 1]; } a; + +static inline void +foo (const B &b) +{ + __builtin_memcpy (&a, &b, sizeof (b)); +} + +void +bar () +{ + B c; + foo (c); +} diff --git a/gcc/testsuite/g++.dg/opt/pr6713.C b/gcc/testsuite/g++.dg/opt/pr6713.C new file mode 100644 index 000000000..d89fef81b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr6713.C @@ -0,0 +1,117 @@ +// PR optimization/6713 +// This testcase segfaulted on x86 because a dangling REG_EQUAL note +// resulted in incorrect substitutions later. +// { dg-do run } +// { dg-options "-O2" } + +template<typename _CharT> class basic_iterator +{ + public: + basic_iterator(_CharT* _p) : _M_current(_p) {} + basic_iterator& operator++() { ++_M_current; return *this; } + _CharT& operator*() const { return *_M_current; } + bool operator!=(basic_iterator &_rhs) { return _M_current != _rhs._M_current; } + + private: + _CharT* _M_current; +}; + +template<typename _CharT> class basic_string +{ + public: + typedef unsigned int size_type; + typedef basic_iterator<_CharT> iterator; + + private: + struct _Rep + { + size_type _M_length; + size_type _M_capacity; + int _M_references; + + bool _M_is_leaked() const { return _M_references < 0; } + bool _M_is_shared() const { return _M_references > 0; } + void _M_set_leaked() { _M_references = -1; } + void _M_set_sharable() { _M_references = 0; } + }; + + struct _Rep _M_rep; + + struct _Alloc_hider + { + _CharT _raw[16]; + _CharT* _M_p; + }; + + mutable _Alloc_hider _M_dataplus; + + _CharT* _M_data() const { return _M_dataplus._M_p; } + + void _M_leak() { if (!_M_rep._M_is_leaked()) _M_leak_hard(); } + + static int count; + + static void _M_leak_hard(); + + public: + explicit basic_string(const _CharT* __s); + + iterator begin() { _M_leak(); return iterator(_M_data()); } + + iterator end() { _M_leak(); return iterator(_M_data() + this->size()); } + + size_type size() const { return _M_rep._M_length; } +}; + +template<typename _CharT> basic_string<_CharT>:: +basic_string(const _CharT* __s) +{ + int i; + + for (i=0; i<15; i++) { + if (!__s[i]) + break; + + _M_dataplus._raw[i] = __s[i]; + } + + _M_dataplus._raw[i] = 0; + _M_dataplus._M_p = _M_dataplus._raw; + + _M_rep._M_length = i; + _M_rep._M_capacity = i; + _M_rep._M_references = 1; +} + +template<typename _CharT> int basic_string<_CharT>::count = 0; + +template<typename _CharT> void basic_string<_CharT>:: +_M_leak_hard() +{ + count++; +} + +typedef basic_string<char> string; + +template int basic_string<char>::count; + +int isspa(int ch) +{ + return 0; +} + +void foo(string& str) +{ + string::iterator it = str.begin(); + string::iterator stop = str.end(); + + for (; it != stop; ++it) + if (isspa(*it)) + break; +} + +int main() +{ + string str("test"); + foo(str); +} diff --git a/gcc/testsuite/g++.dg/opt/pr7503-1.C b/gcc/testsuite/g++.dg/opt/pr7503-1.C new file mode 100644 index 000000000..d366a6180 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr7503-1.C @@ -0,0 +1,148 @@ +// PR c++/7503 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort(); + +void test1a() +{ + int A = 4; + int B = 4; + + (A > B ? A : B) = 1; + if (A != 4 || B != 1) + abort (); +} + +void test1b() +{ + int A = 3; + int B = 5; + + (A > B ? A : B) = 1; + if (A != 3 || B != 1) + abort (); +} + +void test1c() +{ + int A = 5; + int B = 3; + + (A > B ? A : B) = 1; + if (A != 1 || B != 3) + abort (); +} + +void test2a() +{ + int A = 4; + int B = 4; + + (A >= B ? A : B) = 1; + if (A != 1 || B != 4) + abort (); +} + +void test2b() +{ + int A = 3; + int B = 5; + + (A >= B ? A : B) = 1; + if (A != 3 || B != 1) + abort (); +} + +void test2c() +{ + int A = 5; + int B = 3; + + (A >= B ? A : B) = 1; + if (A != 1 || B != 3) + abort (); +} + +void test3a() +{ + int A = 4; + int B = 4; + + (A < B ? A : B) = 1; + if (A != 4 || B != 1) + abort (); +} + +void test3b() +{ + int A = 3; + int B = 5; + + (A < B ? A : B) = 1; + if (A != 1 || B != 5) + abort (); +} + +void test3c() +{ + int A = 5; + int B = 3; + + (A < B ? A : B) = 1; + if (A != 5 || B != 1) + abort (); +} + +void test4a() +{ + int A = 4; + int B = 4; + + (A <= B ? A : B) = 1; + if (A != 1 || B != 4) + abort (); +} + +void test4b() +{ + int A = 3; + int B = 5; + + (A <= B ? A : B) = 1; + if (A != 1 || B != 5) + abort (); +} + +void test4c() +{ + int A = 5; + int B = 3; + + (A <= B ? A : B) = 1; + if (A != 5 || B != 1) + abort (); +} + + +int main() +{ + test1a(); + test1b(); + test1c(); + + test2a(); + test2b(); + test2c(); + + test3a(); + test3b(); + test3c(); + + test4a(); + test4b(); + test4c(); + + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/preinc1.C b/gcc/testsuite/g++.dg/opt/preinc1.C new file mode 100644 index 000000000..89a0116b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/preinc1.C @@ -0,0 +1,59 @@ +// PR optimization/6086 +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort (void); + +struct A +{ + A (int x, int y); + int a, b; + int foo () { return a; } + int bar () { return b; } +}; + +struct B +{ + virtual ~B (); + virtual A baz () const; +}; + +struct C +{ + A foo () const; + B *c; +}; + +A C::foo () const +{ + int x, y; + x = c->baz ().foo (); + y = c->baz ().bar (); + return A (x, y); +} + +A B::baz () const +{ + return A (4, 8); +} + +A::A (int x, int y) +{ + a = x; + b = y; +} + +B::~B () +{ +} + +int +main () +{ + C the_c; + B the_b; + the_c.c = &the_b; + if (the_c.foo().a != 4) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/ptrintsum1.C b/gcc/testsuite/g++.dg/opt/ptrintsum1.C new file mode 100644 index 000000000..a6a3c9727 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrintsum1.C @@ -0,0 +1,29 @@ +// PR c++/4401 +// This testcase was miscompiled on 64-bit platforms, resulting to +// operating on a[0x100000000] instead of a[0]. +// { dg-do run } +// { dg-options "-O2" } + +char *a; +char b[] = "AAAA"; + +extern "C" void abort (void); +extern "C" void exit (int); + +void foo (void) +{ + unsigned int i, j; + + i = 2; + j = 3; + a[i + 1 - j] += i; +} + +int main (void) +{ + a = b; + foo (); + if (b[0] != 'A' + 2) + abort (); + exit (0); +} diff --git a/gcc/testsuite/g++.dg/opt/ptrmem1.C b/gcc/testsuite/g++.dg/opt/ptrmem1.C new file mode 100644 index 000000000..0a02a53a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem1.C @@ -0,0 +1,12 @@ +// { dg-options "-O2" } + +class QWidget +{ + public: void repaint( bool erase = 1 ); +}; +void f (void) +{ + typedef void (QWidget::*A)(bool); + A b = &QWidget::repaint; +} + diff --git a/gcc/testsuite/g++.dg/opt/ptrmem2.C b/gcc/testsuite/g++.dg/opt/ptrmem2.C new file mode 100644 index 000000000..19c43f7cd --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem2.C @@ -0,0 +1,12 @@ +typedef unsigned int Mword; +struct Thread +{ + Mword sys_ipc_log(); + void hook_ipc_vector(); + unsigned (Thread::*syscall_table)(); +}; + +void Thread::hook_ipc_vector() +{ + syscall_table = &Thread::sys_ipc_log; +} diff --git a/gcc/testsuite/g++.dg/opt/ptrmem3.C b/gcc/testsuite/g++.dg/opt/ptrmem3.C new file mode 100644 index 000000000..552a92c9c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem3.C @@ -0,0 +1,23 @@ +// { dg-options "-O1" } + +#include <stdio.h> +struct A { + A(int arg) : ia(arg) {} + int x,y,z,ia; + int mf(int arg) { return arg + ia; } +}; +int func(int A::*pdm, int (A::*pmf)(int)) // 2. regular function +{ + A oa(2); + return ((&oa)->*pdm) + (oa.*pmf)(2); +} +int main() +{ + int val; + + int A::*pda = &A::ia; + int (A::*pmfa)(int) = &A::mf; + val = func( pda, pmfa ); + if(val != 6) + printf("val=%d, expect 6 \n", val); +} diff --git a/gcc/testsuite/g++.dg/opt/ptrmem4.C b/gcc/testsuite/g++.dg/opt/ptrmem4.C new file mode 100644 index 000000000..ad39a371b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem4.C @@ -0,0 +1,12 @@ +// { dg-do compile } +// { dg-options "-O3" } + +struct X { void foo (); }; + +template <typename> +inline void spawn (void (X::*fun_ptr)()) {} + +void bar () { + void (X::*const comp)() = &X::foo; + spawn<int> (comp); +} diff --git a/gcc/testsuite/g++.dg/opt/ptrmem5.C b/gcc/testsuite/g++.dg/opt/ptrmem5.C new file mode 100644 index 000000000..639ad2831 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem5.C @@ -0,0 +1,19 @@ +// PR tree-opt/18904 +// { dg-do compile } +// { dg-options "-O3" } + +struct Data; +struct Wrapper { + Data* D; +}; +struct Data { + int X; + void init(Wrapper&); +}; +void Data::init( Wrapper &w ) { + int Data::* res = &Data::X; + w.D = this; + for( int i = 0; i < 4; i++ ) + (w.D->*res) = 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/ptrmem6.C b/gcc/testsuite/g++.dg/opt/ptrmem6.C new file mode 100644 index 000000000..891c4ff17 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/ptrmem6.C @@ -0,0 +1,28 @@ +// PR tree-opt/18040 +// { dg-do compile } +// { dg-options "-O3" } + +int PyObject_IsTrue(); +struct object_base +{ + void ptr() const; + void ptr1() const; +}; +struct object : public object_base +{ + typedef void (object::*bool_type)() const; + inline operator bool_type() const + { return PyObject_IsTrue() + ? &object_base::ptr : &object::ptr1; } +}; +void f(); +void g (void) +{ + for (unsigned n = 0; n < 100; ++n) + { + object kv; + if (kv) + f(); + } +} + diff --git a/gcc/testsuite/g++.dg/opt/range-test-1.C b/gcc/testsuite/g++.dg/opt/range-test-1.C new file mode 100644 index 000000000..cc5ba6694 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/range-test-1.C @@ -0,0 +1,216 @@ +// Test fold-const.c (fold_range_test) optimizations. +// { dg-do run } */ +// { dg-options "-O2" } */ + +#ifndef __RANGE_TEST_HDR_INCL +#define __RANGE_TEST_HDR_INCL +/* Protect against fix-header weakness */ +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#endif + +#if (INT_MAX == 2147483647) && (INT_MIN == -2147483648) \ + && (SCHAR_MIN == -128) && (SCHAR_MAX == 127) \ + && (UCHAR_MIN == 0) && (UCHAR_MAX == 255) + +#ifndef T + +enum integers +{ + int_smallest = INT_MIN, + int_2ndsmallest = INT_MIN + 1, + int_3rdsmallest = INT_MIN + 2, + int_minus2 = -2, + int_minus1 = -1, + int_zero = 0, + int_one = 1, + int_two = 2, + int_3rdlargest = INT_MAX - 2, + int_2ndlargest = INT_MAX - 1, + int_largest = INT_MAX +}; + +enum smallenum +{ + smalle_minus4 = -4, + smalle_minus3 = -3, + smalle_minus2 = -2, + smalle_minus1 = -1, + smalle_zero = 0, + smalle_one = 1, + smalle_two = 2, + smalle_three = 3 +}; + +enum enum2 +{ + enum2_two = 2, + enum2_three = 3, + enum2_four = 4, + enum2_five = 5 +}; + +enum enum3 +{ + enum3_zero, + enum3_one, + enum3_two, + enum3_three, + enum3_four, + enum3_five, + enum3_six, + enum3_seven +}; + +int var; +void +check () +{ + ++var; +} + +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ +void __attribute__((noinline)) \ +test##IDX (TYPE x) \ +{ \ + if (TEST) \ + check (); \ +} +#include "range-test-1.C" +#undef T + +int +main () +{ + int i, fails = 0; + +#define C , +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ + { \ + static TYPE yesarr##IDX [] = YESARR; \ + static TYPE noarr##IDX [] = NOARR; \ + for (i = 0; i < (int) (sizeof (yesarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + var = 0; \ + test##IDX (yesarr##IDX [i]); \ + if (var != 1) \ + printf ("test" #IDX " failed for yesarr [%u]\n", i), ++fails; \ + } \ + var = 0; \ + for (i = 0; i < (int) (sizeof (noarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + test##IDX (noarr##IDX [i]); \ + if (var != 0) \ + printf ("test" #IDX " failed for noarr [%u]\n", i), ++fails; \ + } \ + } +#include "range-test-1.C" +#undef T + + if (fails) + abort (); + + exit (0); +} + +#else + +/* Use `C' instead of `,' below to separate array entries. */ + +/* These ought to be all optimized into single comparison. */ +T(1, unsigned int, x == 0 || x == 1, + { 0 C 1 }, { -1U C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(2, unsigned int, x == 0 || x == -1U || x == -2U, + { 0 C -1U C -2U }, { -3U C -6U C 1 C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(3, unsigned int, x == 0 || x == 1 || x == 2, + { 0 C 1 C 2 }, { -3U C -6U C -1U C -2U C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(4, unsigned int, x == 3 || x == 4 || x == 5 || x == 6, + { 3 C 4 C 5 C 6 }, { -3U C 0 C 1 C 2 C 7 C 8 C 12 C 0x7fffffff C 0x80000000 }) +T(5, unsigned int, x == -3U || x == -4U || x == -5U || x == -6U, + { -3U C -4U C -5U C -6U }, { -7U C -8U C -2U C -1U C 1 C 2 C 0x7fffffff C 0x80000000 }) +T(6, unsigned int, x == -3U || x == -4U || x == -5U, + { -3U C -4U C -5U }, { -6U C -7U C -8U C -2U C -1U C 1 C 2 C 0x7fffffff C 0x80000000 }) +T(7, char *, x == (char *) -3UL || x == (char *) -4UL || x == (char *) -5UL, + { (char *) -3UL C (char *) -4UL C (char *) -5UL }, + { (char *) -6UL C (char *) -20UL C (char *) -2UL C (char *) -1UL C (char *) 0 + C (char *) 1UL C (char *) 35UL C (char *) 0x7fffffffUL C (char *) 0x80000000UL }) +T(8, unsigned long, x == -2UL || x == -1UL || x == 0, + { 0 C -1UL C -2UL }, { -3UL C -6UL C 1 C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(9, unsigned long, x >= -4UL || x <= 8, + { -4UL C -3UL C -2UL C -1UL C 0 C 1 C 2 C 3 C 4 C 5 C 6 C 7 C 8 }, + { -7UL C -5UL C 9 C 10 C 61 C 127 C 0x7fffffff C 0x80000000 }) +T(10, signed char, x == 0 || x == -1 || x == -2 || x == -3, + { 0 C -1 C -2 C -3 }, { -4 C -5 C 1 C 2 C 3 C 35 C -24 }) +T(11, int, x == 0 || x == 1, + { 0 C 1 }, { -1 C 2 C 12 C 35 C INT_MAX C INT_MIN }) +T(12, int, x == 0 || x == -1 || x == -2, + { 0 C -1 C -2 }, { -3 C -6 C 1 C 2 C 12 C 35 C INT_MAX C INT_MIN }) +T(13, int, x == 0 || x == 1 || x == 2, + { 0 C 1 C 2 }, { -3 C -6 C -1 C -2 C 12 C 35 C INT_MAX C INT_MIN }) +T(14, int, x == 3 || x == 4 || x == 5 || x == 6, + { 3 C 4 C 5 C 6 }, { -3 C 0 C 1 C 2 C 7 C 8 C 12 C INT_MAX C INT_MIN }) +T(15, int, x == -3 || x == -4 || x == -5 || x == -6, + { -3 C -4 C -5 C -6 }, { -7 C -8 C -2 C -1 C 1 C 2 C INT_MAX C INT_MIN }) +T(16, int, x == -3 || x == -4 || x == -5, + { -3 C -4 C -5 }, { -6 C -7 C -8 C -2 C -1 C 1 C 2 C INT_MAX C INT_MIN }) +T(17, unsigned int, (x >= -8U && x <= -3U) || x == -2U || x == -1U || x == 0 || x == 1 || x == 2, + { -8U C -7U C -6U C -5U C -4U C -3U C -2U C -1U C 0 C 1 C 2 }, + { -9U C -10U C 3 C 4 C 12 C -54U C INT_MAX C INT_MIN }) +T(18, int, (x >= -8 && x <= -3) || x == -2 || x == -1 || x == 0 || x == 1 || x == 2, + { -8 C -7 C -6 C -5 C -4 C -3 C -2 C -1 C 0 C 1 C 2 }, + { -9 C -10 C 3 C 4 C 12 C -54 C INT_MAX C INT_MIN }) +T(19, unsigned long, x <= 16 || (x >= 18 && x <= -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { 17 }) +T(20, char *, x == (char *) -1UL || x == 0, + { (char *) -1UL C 0 }, { (char *) -6UL C (char *) -20UL C (char *) -2UL + C (char *) 1UL C (char *) 35UL C (char *) 0x7fffffffUL C (char *) 0x80000000UL }) +T(21, integers, x == int_zero || x == int_one, + { int_zero C int_one }, { int_minus1 C int_two C int_largest C int_smallest }) +T(22, int, x == INT_MIN || x == INT_MAX, + { INT_MIN C INT_MAX }, + { -1 C 0 C 1 C INT_MAX - 1 C INT_MAX - 2 C INT_MIN + 1 C INT_MIN + 2 }) +T(23, int, x == INT_MIN + 1 || x == INT_MIN + 2 || x == INT_MIN || x == INT_MAX, + { INT_MIN + 1 C INT_MIN + 2 C INT_MIN C INT_MAX }, + { -1 C 0 C 1 C INT_MAX - 1 C INT_MAX - 2 C INT_MIN + 3 C INT_MIN + 4 }) +T(24, signed char, x == SCHAR_MIN || x == SCHAR_MAX, + { SCHAR_MIN C SCHAR_MAX }, + { -1 C 0 C 1 C SCHAR_MAX - 1 C SCHAR_MAX - 2 C SCHAR_MIN + 1 C SCHAR_MIN + 2 }) +T(25, integers, x == int_smallest || x == int_largest, + { int_smallest C int_largest }, { int_minus1 C int_zero C int_one + C int_2ndsmallest C int_2ndlargest C int_3rdsmallest C int_3rdlargest }) + +/* These should be optimized into unconditional jumps. */ +T(o1, unsigned long, x <= 16 || (x >= 17 && x <= -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 17 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { }) +T(o2, unsigned long, x <= -3UL || (x == -2UL || x == -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 17 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { }) + +/* These should be eventually optimized into a single comparison. */ +T(td1, unsigned char, x == 0 || x == 4 || x == 1 || x == 5 || x == 2 || x == 6 || x == 3, + { 0 C 1 C 2 C 3 C 4 C 5 C 6 }, { 7 C 8 C 127 C 128 C 254 C 255 }) + +/* These should not be optimized into a single comparison. */ +T(n1, smallenum, x == smalle_minus4 || x == smalle_three, + { smalle_minus4 C smalle_three }, { smalle_minus3 C smalle_minus2 C smalle_minus1 + C smalle_zero C smalle_one C smalle_two }) +T(n2, enum2, x == enum2_two || x == enum2_five, + { enum2_two C enum2_five }, { enum2_three C enum2_four }) +T(n3, enum3, x == enum3_zero || x == enum3_seven, + { enum3_zero C enum3_seven }, { enum3_one C enum3_two C enum3_three C enum3_four + C enum3_five C enum3_six }) + +#endif + +#else + +int +main (void) +{ + return 0; +} + +#endif diff --git a/gcc/testsuite/g++.dg/opt/range-test-2.C b/gcc/testsuite/g++.dg/opt/range-test-2.C new file mode 100644 index 000000000..05690bfd0 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/range-test-2.C @@ -0,0 +1,96 @@ +// Test fold-const.c (fold_range_test) optimizations. +// { dg-do run } */ +// { dg-options "-O2" } */ + +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> + +#if (INT_MAX == 2147483647) && (INT_MIN == -2147483648) \ + && (SCHAR_MIN == -128) && (SCHAR_MAX == 127) \ + && (UCHAR_MIN == 0) && (UCHAR_MAX == 255) + +#ifndef T + +enum enum3 +{ + enum3_zero, + enum3_one, + enum3_two, + enum3_three, + enum3_four, + enum3_five, + enum3_six, + enum3_seven +}; + +int var; +void +check () +{ + ++var; +} + +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ +void __attribute__((noinline)) \ +test##IDX (TYPE x) \ +{ \ + if (TEST) \ + check (); \ +} +#include "range-test-2.C" +#undef T + +int +main () +{ + int i, fails = 0; + +#define C , +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ + { \ + static TYPE yesarr##IDX [] = YESARR; \ + static TYPE noarr##IDX [] = NOARR; \ + for (i = 0; i < (int) (sizeof (yesarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + var = 0; \ + test##IDX (yesarr##IDX [i]); \ + if (var != 1) \ + printf ("test" #IDX " failed for yesarr [%u]\n", i), ++fails; \ + } \ + var = 0; \ + for (i = 0; i < (int) (sizeof (noarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + test##IDX (noarr##IDX [i]); \ + if (var != 0) \ + printf ("test" #IDX " failed for noarr [%u]\n", i), ++fails; \ + } \ + } +#include "range-test-2.C" +#undef T + + if (fails) + abort (); + + exit (0); +} + +#else + +/* Use `C' instead of `,' below to separate array entries. */ + +T(26, enum3, x == enum3_one || x == enum3_two || x == enum3_three, + { enum3_one C enum3_two C enum3_three }, { enum3_zero C enum3_four + C enum3_five C enum3_six C enum3_seven }) + +#endif + +#else + +int +main (void) +{ + return 0; +} + +#endif diff --git a/gcc/testsuite/g++.dg/opt/reg-stack.C b/gcc/testsuite/g++.dg/opt/reg-stack.C new file mode 100644 index 000000000..76d3cee1b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reg-stack.C @@ -0,0 +1,47 @@ +// PR target/6087 +// The code that moves around insns emitted by reg-stack to cope with +// exception edges lost the REG_DEAD note indicating a pop. Which +// eventually fills up the register stack resulting in Z == NaN. + +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort (); + +struct Base +{ + virtual ~Base() {} +}; + +struct Foo : public Base +{ + Foo (); +}; + +double x = 3; +double y = 4; + +double bar () +{ + double z = x*x+y*y; + if (z != 25.0) + throw 1; + return z; +} + +Foo::Foo () +{ + bar (); +} + +int main () +{ + try { + int i; + for (i = 0; i < 10; ++i) + new Foo; + } catch (...) { + abort (); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/reg-stack2.C b/gcc/testsuite/g++.dg/opt/reg-stack2.C new file mode 100644 index 000000000..08cd590b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reg-stack2.C @@ -0,0 +1,34 @@ +// PR target/9786 +// Origin: <nick@ilm.com> + +// This used to fail on x86 because the reg-stack pass deleted +// an insn that could seemingly trap (but actually doesn't) +// without updating the CFG. + +// { dg-do compile } +// { dg-options "-O2 -fnon-call-exceptions" } + +struct D1 { + float l; + D1 GS() const {D1 d;float f=.299*l;d.l=f;return d;} + static D1 G() {return D1();} +}; + +struct D2 { + D1 g; + D2(const D1& gi) : g(gi) {} + D2 GS() const {return D2(g.GS());} +}; + +class A { + public: + virtual ~A() {} +}; + +class B : public A { + public: + B(const D2& mi); + D2 fm; +}; + +B::B(const D2 &mi) : fm(mi.GS()) {} diff --git a/gcc/testsuite/g++.dg/opt/reg-stack3.C b/gcc/testsuite/g++.dg/opt/reg-stack3.C new file mode 100644 index 000000000..48dcb335b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reg-stack3.C @@ -0,0 +1,21 @@ +// PR target/12712 +// Origin: Markus Schoder <gccbug@gammarayburst.de> + +// This used to segfault on x86 because the reg-stack pass +// created an unreachable basic block by purging an outgoing +// edge, and was not prepared to handle it. + +// { dg-do compile } + +struct A +{ + ~A(); + float f(float x); + float g() const {return 0;} +}; + +void h() +{ + A a, b; + a.f(b.g() + 1); +} diff --git a/gcc/testsuite/g++.dg/opt/reg-stack4.C b/gcc/testsuite/g++.dg/opt/reg-stack4.C new file mode 100644 index 000000000..b1b743416 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reg-stack4.C @@ -0,0 +1,29 @@ +// PR target/12900 +// Origin: <snyder@fnal.gov> + +// This used to fail on x86 because the reg-stack pass +// deleted a valid edge. + +// { dg-do compile } +// { dg-options "-mtune=i586 -O2" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } + +struct array { + double data; + virtual ~array(); +}; + +double glob; +double ext1(double); +int nmuons; + +void track_match() +{ + array vecdca; + if (glob < 10) return; + double p = glob*5; + double phi = vecdca.data; + ext1 (vecdca.data-glob); + ext1 (phi*2); + if (1 < p) + ++nmuons; +} diff --git a/gcc/testsuite/g++.dg/opt/reload1.C b/gcc/testsuite/g++.dg/opt/reload1.C new file mode 100644 index 000000000..0d8fb894e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reload1.C @@ -0,0 +1,43 @@ +// PR 7944 +// { dg-do compile } +// { dg-options -O2 } + +struct B +{ + B & operator << (short s) + { + int j; + if (j) + return operator << (s); + else + return operator << (s); + } +}; + +struct A +{ + int i; + static void bar (); + static int quux () + { + bar (); + return 0; + } + + A ():i (quux ()) + { + } + ~A () + { + } +}; + +void +foo () +{ + short s[4] = { 0, 0, 0, 1 }; + A a[2] = { A (), A () }; + + B b; + b << s[0] << s[2]; +} diff --git a/gcc/testsuite/g++.dg/opt/reload2.C b/gcc/testsuite/g++.dg/opt/reload2.C new file mode 100644 index 000000000..1af8aea65 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reload2.C @@ -0,0 +1,42 @@ +// PR 10352 +// { dg-do compile } +// { dg-options -O2 } + +extern double fabs(double x); + +typedef struct { float x, y; } S; +typedef struct _T T; + +extern void fT( T *p ); +extern T *h(); +extern S g( ); + +static +int f(void) +{ + T *t=0; + int c=0; + S s; + + const S exp_s = {0.,0.}; + + if(!(t = h())) + { + c++; + } + + if(!c) + { + s = g(); + if( (fabs( (s.x) - (exp_s.x) ) > 1 ) + || (fabs( (s.y) - (exp_s.y) ) > 1 ) ) + { + c++; + } + } + + if(t) + fT(t); + + return c; +} diff --git a/gcc/testsuite/g++.dg/opt/reload3.C b/gcc/testsuite/g++.dg/opt/reload3.C new file mode 100644 index 000000000..12f3e66f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/reload3.C @@ -0,0 +1,39 @@ +// PR target/38287 +// { dg-do run } +// { dg-options "-O2 -mcpu=v8 -fPIC" { target { { sparc*-*-* } && { ilp32 && fpic } } } } + +#include <cstdlib> + +class QTime +{ +public: + explicit QTime(int ms = 0) : ds(ms) {} + static QTime currentTime() { return QTime(); } + QTime addMSecs(int ms) const; + int msecs() const { return ds; } +private: + unsigned ds; +}; + +static const unsigned MSECS_PER_DAY = 86400000; + +QTime QTime::addMSecs(int ms) const +{ + QTime t; + if ( ms < 0 ) { + // % not well-defined for -ve, but / is. + int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY; + t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY) + % MSECS_PER_DAY; + } else { + t.ds = ((int)ds + ms) % MSECS_PER_DAY; + } + return t; +} + +int main() +{ + if (QTime(1).addMSecs(1).msecs() != 2) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/return-slot1.C b/gcc/testsuite/g++.dg/opt/return-slot1.C new file mode 100644 index 000000000..fcc6cea5a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/return-slot1.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-O2" } + +struct A +{ + A(); + virtual A foo() const; +}; + +void bar() +{ + const A& a=A(); + a.foo(); +} diff --git a/gcc/testsuite/g++.dg/opt/rtti1.C b/gcc/testsuite/g++.dg/opt/rtti1.C new file mode 100644 index 000000000..32daaefa6 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/rtti1.C @@ -0,0 +1,20 @@ +// Test that typeid sees through references even when optimizing. +// { dg-do run } +// { dg-options "-O2" } + +#include <typeinfo> + +struct A +{ + virtual ~A() { } +}; + +class B : public A { }; + +int main () +{ + B b; + A &aref = b; + + return typeid (aref) != typeid (b); +} diff --git a/gcc/testsuite/g++.dg/opt/rtti2.C b/gcc/testsuite/g++.dg/opt/rtti2.C new file mode 100644 index 000000000..ebbe3cdfd --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/rtti2.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-options "-O2" } +// We used to ICE in compare_values as the types for a comparison +// were not the same kind of types. + +struct class1 +{ + virtual ~class1 (); +}; +struct class2 : class1 { }; + +void f(class1 * oo) +{ + class2 * oj = dynamic_cast <class2 *>(oo) ; + if (oj) + delete oo; +} diff --git a/gcc/testsuite/g++.dg/opt/stack1.C b/gcc/testsuite/g++.dg/opt/stack1.C new file mode 100644 index 000000000..7fac18dac --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/stack1.C @@ -0,0 +1,135 @@ +// PR optimization/11198 +// Origin: Joerg Walter <jhr.walter@t-online.de> +// Reduced testcase by: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// The compiler used to allocate the same stack slot for two aggregates, +// overlooking that assignments to members given the same address on the +// stack may not alias and thus may be reordered by the scheduling passes. + +// { dg-do run } +// { dg-options "-O2 -frename-registers" } + + +double zero_; + +inline const int& +min(const int& a, const int& b) { + if (b < a) return b; return a; +} + +struct barrier { barrier () {} }; + +template <typename=void> struct unbounded_array { + inline unbounded_array (): data_ (new double [9]) {} + inline double& operator [] (int i) { return data_ [i]; } + double* data_; +}; + +inline int element (int i, int j) { + return i + j; +} + +template <typename=void> +struct matrix { + inline matrix () : size2_ (3) {} + + inline unbounded_array<> &data () { return data_; } + + inline double& el (int i, int j) { + int dead1 = j; + int dead2 = 1 + i - j; + if (j < size2_ && i-j < 2) + return data () [element (j,i-j+1)]; + barrier (); + return zero_; + } + + struct iterator2; + + inline iterator2 find () { + return iterator2 (*this); + } + + struct iterator1 { + inline iterator1 (matrix *m): + dead1 (m), i (0) {} + void *dead1; + int i; + int dead2; + }; + + const int size2_; + unbounded_array<> data_; +}; + + +template<typename=void> +struct adaptor { + adaptor (matrix<> &m) : m(&m), upper_ (1) {} + + int size1 () const; + int size2 () const { return 3; } + int lower () const { return 1; } + int upper () const { return upper_; } + matrix<> &data () { return *m; } + + double& el (int i, int j) { + int dead1, dead2; + if (j < size2 () && i-j < 1) + return data ().el (i, j); + + barrier (); + return zero_; + } + + struct a_iterator2; + + struct a_iterator1 { + a_iterator1 (adaptor &a, const matrix<>::iterator1 &it1): + a (&a), dead1 (it1) {} + + a_iterator2 begin () const { + return a_iterator2(*a); + } + adaptor *a; + matrix<>::iterator1 dead1; + }; + + struct a_iterator2 { + a_iterator2 (adaptor &a) : a (&a) {} + + double& f () const { + int i = 0; + int l = a->upper () + i; + int q = a->size2 (); + if (0 < q && + l < a->lower () + 1 + a->upper ()) + return a->m->el(0,0); + + return a->el (i, 0); + } + + adaptor *a; + }; + + matrix<> *m; + int upper_; +}; + +void matrix_swap (adaptor<> &bam1, adaptor<> &bam2) +{ + adaptor<>::a_iterator1 it1 (bam1,matrix<>::iterator1(bam1.m)), + it2 (bam2,matrix<>::iterator1(bam2.m)); + int dead; + double x = it1.begin().f(); + it2.begin().f() = x; +} + +int main () +{ + matrix<> m1,m2; + adaptor<> bam1 (m1), bam2 (m2); + matrix_swap (bam1, bam2); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/static1.C b/gcc/testsuite/g++.dg/opt/static1.C new file mode 100644 index 000000000..05429e18b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/static1.C @@ -0,0 +1,20 @@ +// PR c++/6073 +// This testcase ICEd because finish_struct_bits changed +// A's and const A's TYPE_MODE from QI to BLK, but did +// not change a's DECL_MODE because its mode was not +// TYPE_MAIN_VARIANT. + +struct A +{ + static const A a; + ~A (); +}; + +void bar (A x); +void foo (); + +void +foo () +{ + bar (A::a); +} diff --git a/gcc/testsuite/g++.dg/opt/static2.C b/gcc/testsuite/g++.dg/opt/static2.C new file mode 100644 index 000000000..e2ecd13c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/static2.C @@ -0,0 +1,13 @@ +// Origin: reichelt@igpm.rwth-aachen.de +// PR 5571 +// { dg-options "-O2" } + +template <class T> struct A {}; + +struct B +{ + static A<int> a; + void f() { a; } +}; + +A<int> B::a = A<int>(); diff --git a/gcc/testsuite/g++.dg/opt/static3.C b/gcc/testsuite/g++.dg/opt/static3.C new file mode 100644 index 000000000..4f8f7a9ba --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/static3.C @@ -0,0 +1,36 @@ +// { dg-do link } +// { dg-options "-O2" } + +class Foo { +public: + // No out-of-class definition is provided for these class members. + // That's technically a violation of the standard, but no diagnostic + // is required, and, as a QOI issue, we should optimize away all + // references. + static const int erf = 0; + static const int foo = 1; +}; + +int one() +{ + return Foo::foo; +} + +int two() +{ + return Foo::foo + Foo::erf; +} + +int three(int x) +{ + return x ? Foo::erf : Foo::foo; +} + +int i; + +int main () +{ + one (); + two (); + three (i); +} diff --git a/gcc/testsuite/g++.dg/opt/static4.C b/gcc/testsuite/g++.dg/opt/static4.C new file mode 100644 index 000000000..87e11b027 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/static4.C @@ -0,0 +1,15 @@ +// PR 13898 +// Make sure the two X variables get assigned unique assembler names +// if they are promoted to static storage. + +// { dg-do compile } + +int g(int i) { + if (i<1) { + const int x[3] = { 1,2,3 }; + return x[i]; + } else { + const int x[3] = { 4,5,6 }; + return x[i]; + } +} diff --git a/gcc/testsuite/g++.dg/opt/static5.C b/gcc/testsuite/g++.dg/opt/static5.C new file mode 100644 index 000000000..1daca6d71 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/static5.C @@ -0,0 +1,29 @@ +// PR c++/31809 +// { dg-do run } +// { dg-options "-O2" } + +struct S +{ + unsigned v; + static inline S f (unsigned a); +}; + +inline S +S::f (unsigned a) +{ + static S t = { a }; + return t; +} + +const static S s = S::f (26); + +extern "C" void abort (void); + +int +main () +{ + S t = s; + if (t.v != 26) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/static6.C b/gcc/testsuite/g++.dg/opt/static6.C new file mode 100644 index 000000000..00e76fb73 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/static6.C @@ -0,0 +1,35 @@ +// PR c++/31806 +// { dg-do run } +// { dg-options "-O2 -fno-inline -fno-threadsafe-statics" } + +extern "C" void abort(void); + +struct A +{ + void *d; +}; + +static const A& staticA() +{ + static A s_static; + return s_static; +} + +void assert_failed() +{ + abort(); +} + +A testMethod() +{ + static const A& s = staticA( ); + if (&s == 0) + assert_failed(); + return s; +} + +int main() +{ + testMethod(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/strength-reduce.C b/gcc/testsuite/g++.dg/opt/strength-reduce.C new file mode 100644 index 000000000..3fee937f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/strength-reduce.C @@ -0,0 +1,51 @@ +// This testcase was miscompiled on s390x, because strength-reduction +// did not see biv in C::foo as used after loop, but it was used +// in a REG_EQUAL note. +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (void); + +struct C +{ + int foo (char ch, int offset = __INT_MAX__) const; + int bar (int offset, char c) const; + const char *a; +}; + +int C::bar (int offset, char c) const +{ + char ch = a[offset]; + if (ch < c) + return -1; + if (ch > c) + return 1; + return 0; +} + +int C::foo (char ch, int offset) const +{ + int len = __builtin_strlen (a); + if (len == 0) + return __INT_MAX__; + if (offset >= len) + offset = len - 1; + + while (bar (offset, ch) != 0) + { + if (offset == 0) + return __INT_MAX__; + offset--; + } + + return offset; +} + +int main (void) +{ + C c; + c.a = "/some/dir/file.ext"; + if (c.foo ('/') != 9) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/switch1.C b/gcc/testsuite/g++.dg/opt/switch1.C new file mode 100644 index 000000000..c21630d75 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/switch1.C @@ -0,0 +1,23 @@ +// { dg-options "-O1" } + +template <typename T> +int f(T t) { + switch (t) { + case 1: + return 5; + case 2: + return 6; + case 3: + return -4; + case 4: + return 8; + case 5: + return 12; + case 6: + return 13; + default: + return -27; + } +} + +template int f(int); diff --git a/gcc/testsuite/g++.dg/opt/switch2.C b/gcc/testsuite/g++.dg/opt/switch2.C new file mode 100644 index 000000000..f7374cb74 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/switch2.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O2 -w" } + +extern int foo (int); + +void +bar (void) +{ + char tmp = foo (0); + switch (tmp) + { + case 1: foo (1); break; + case 2: foo (2); break; + case 3: foo (3); break; + case 4: foo (4); break; + case 5: foo (5); break; + case 6: foo (6); break; + case 7: foo (7); break; + case 255: foo (8); break; + default: break; + } +} + diff --git a/gcc/testsuite/g++.dg/opt/switch3.C b/gcc/testsuite/g++.dg/opt/switch3.C new file mode 100644 index 000000000..643cac323 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/switch3.C @@ -0,0 +1,16 @@ +// PR c++/20023 +// { dg-do compile } +// { dg-options "-O2" } + +void f (void); +typedef __SIZE_TYPE__ size_t; +void g (void *a) +{ + size_t b = (size_t) a; + switch (b) + { + case 1: + f (); + break; + } +} diff --git a/gcc/testsuite/g++.dg/opt/switch4.C b/gcc/testsuite/g++.dg/opt/switch4.C new file mode 100644 index 000000000..1542f310c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/switch4.C @@ -0,0 +1,31 @@ +// { dg-do compile } +// { dg-options "-fshort-enums -w" } + +// PR c++/20008 + +// We failed to compile this because CFG cleanup left the switch +// statement intact, whereas expand_case expected at least one +// in-range case to remain. + +typedef enum _SECStatus { + SECWouldBlock = -2, + SECFailure = -1, + SECSuccess = 0 +} SECStatus; + +typedef enum { + SEC_ERROR_BAD_SIGNATURE = (-0x2000) + 10 +} SECErrorCodes; + +void g(void); +void f(SECStatus status) +{ + switch( status ) + { + case SEC_ERROR_BAD_SIGNATURE : + // This case can be optimized away in C++ (but apparently not in + // C), because the enum type is defined with a narrow range. + g(); + break ; + } +} diff --git a/gcc/testsuite/g++.dg/opt/temp1.C b/gcc/testsuite/g++.dg/opt/temp1.C new file mode 100644 index 000000000..dc13f5162 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/temp1.C @@ -0,0 +1,50 @@ +// PR c++/16405 +// { dg-options "-O2" } +// { dg-do run } + +// There should be exactly one temporary generated for the code in "f" +// below when optimizing -- for the result of "b + c". We have no +// easy way of checking that directly, so we count the number of calls +// to "memcpy", which is used on (some?) targets to copy temporaries. +// If there is more than two calls (one for coping "*this" to "t", and +// one for copying the temporary to "a"), then there are too many +// temporaries. + +int i; + +extern "C" +void *memcpy (void *dest, const void *src, __SIZE_TYPE__ n) +{ + char *d = (char *) dest; + const char *s = (const char *) src; + while (n--) + d[n] = s[n]; + ++i; + return dest; +} + +struct T { +#ifdef __SPU__ + /* SPU returns aggregates up to 1172 bytes in registers. */ + int a[300]; +#else + int a[128]; +#endif + T &operator+=(T const &v) __attribute__((noinline)); + T operator+(T const &v) const { T t = *this; t += v; return t; } +}; + +T &T::operator+=(T const &v) { + return *this; +} + +T a, b, c; + +void f() { a = b + c; } + +int main () { + i = 0; + f(); + if (i > 2) + return 1; +} diff --git a/gcc/testsuite/g++.dg/opt/temp2.C b/gcc/testsuite/g++.dg/opt/temp2.C new file mode 100644 index 000000000..35520a242 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/temp2.C @@ -0,0 +1,62 @@ +// { dg-do run } + +// Copyright (C) 2006 Free Software Foundation, Inc. + +// Originally from PR 16681, found also in init/array15.C +// This variant of the testcase verifies that we do not create +// a temporary on the stack, which is PR 27620. + +int i; + +extern "C" +void *memcpy (void *dest, const void *src, __SIZE_TYPE__ n) +{ + char *d = (char *) dest; + const char *s = (const char *) src; + while (n--) + d[n] = s[n]; + ++i; + return dest; +} + +struct foo { + unsigned char buffer[41112]; + foo() ; + bool check () const; +}; + +foo::foo () + : buffer() +{} + +bool foo::check () const +{ + for (unsigned ix = sizeof (buffer); ix--;) + if (buffer[ix]) + return false; + return true; +} + +void *operator new (__SIZE_TYPE__ size, void *p) +{ + return p; +} + +char heap[50000]; + +int main () +{ + for (unsigned ix = sizeof (heap); ix--;) + heap[ix] = ix; + + i = 0; + foo *f = new (heap) foo (); + + if (i != 0) + return 1; + if (!f->check ()) + return 1; + return 0; +} + + diff --git a/gcc/testsuite/g++.dg/opt/template1.C b/gcc/testsuite/g++.dg/opt/template1.C new file mode 100644 index 000000000..f25434693 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/template1.C @@ -0,0 +1,19 @@ +// { dg-options "-O2" } +// { dg-final { scan-assembler-not "\n_?_ZN1AILi0EE4foo1Ev\[: \t\n\]" } } + +template <int> +struct A { + void foo1 () throw (); + void foo2 (); + + void UNRELATED (); +}; + +template <> void A<0>::UNRELATED (); + +template <int dim> inline void A<dim>::foo1 () throw () {} +template <int dim> inline void A<dim>::foo2 () {} + +void bar (A<0> &a) { + a.foo1 (); +} diff --git a/gcc/testsuite/g++.dg/opt/thunk1.C b/gcc/testsuite/g++.dg/opt/thunk1.C new file mode 100644 index 000000000..566c0f2fc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/thunk1.C @@ -0,0 +1,42 @@ +// PR 6788 +// Test that the thunk adjusts the this pointer properly. +// { dg-do run } + +extern "C" void abort (); + +struct A +{ + virtual void foo() = 0; + char large[33*1024]; +}; + +struct B +{ + virtual void foo() = 0; +}; + +struct C : public A, public B +{ + virtual void foo(); +}; + +static C *match; + +void C::foo() +{ + if (this != match) + abort (); +} + +void bar(B *x) +{ + x->foo(); +} + +int main() +{ + C obj; + match = &obj; + bar(&obj); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/thunk2.C b/gcc/testsuite/g++.dg/opt/thunk2.C new file mode 100644 index 000000000..52fcd74bc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/thunk2.C @@ -0,0 +1,44 @@ +// PR c++/20206 +// { dg-do run } +// { dg-options "-O0" } + +void +bar (int x) +{ + asm ("" : : "g" (x)); +} + +struct S { S () {}; virtual ~S () {}; }; +struct T { virtual void foo (int) = 0; }; +struct U : public S, public T +{ + bool a; + U () {} + virtual ~U () {} + virtual void foo (int x) + { + switch (x) + { + case 12: + break; + case 9: + bar (7); + break; + case 10: + bar (12); + break; + case 4: + bar (18); + break; + case 2: + bar (26); + break; + } + } +}; +U u; + +int +main () +{ +} diff --git a/gcc/testsuite/g++.dg/opt/thunk3-1.C b/gcc/testsuite/g++.dg/opt/thunk3-1.C new file mode 100644 index 000000000..c540b0fa2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/thunk3-1.C @@ -0,0 +1,6 @@ +// { dg-do compile } +// { dg-options "-O1" } +struct Foo { }; +struct Bar { virtual ~Bar(); }; +struct Baz: public virtual Bar { virtual void Func (Foo); }; +void unused() { Baz().Func(Foo()); } diff --git a/gcc/testsuite/g++.dg/opt/thunk3.C b/gcc/testsuite/g++.dg/opt/thunk3.C new file mode 100644 index 000000000..bfd68744a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/thunk3.C @@ -0,0 +1,48 @@ +// PR c++/39106 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" void abort (); + +struct A +{ + A (bool x = true); +}; +class B +{ + virtual bool bar (A &, int) const =0; +}; +class C : virtual public B +{ +}; +struct D : virtual public B +{ + bool bar (A &, int) const; +}; +template <int N> +struct E : public D +{ + bool bar (A &x, int y) const + { + return baz().bar (x, y); + } + const D & baz () const; +}; +extern template class E<0>; + +void +foo () +{ + try + { + A a; + abort (); + } catch (...) + { + } + A b; + E<0> c; + c.bar (b, 3); + E<0> d; + d.bar (b, 3); +} diff --git a/gcc/testsuite/g++.dg/opt/thunk4.C b/gcc/testsuite/g++.dg/opt/thunk4.C new file mode 100644 index 000000000..7dd5ea433 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/thunk4.C @@ -0,0 +1,63 @@ +// { dg-do compile } +// { dg-options "-O1" } +namespace std __attribute__ ((__visibility__ ("default"))) +{ + template < class _CharT > struct char_traits; +} +namespace std __attribute__ ((__visibility__ ("default"))) +{ + template < typename _CharT, typename _Traits = + char_traits < _CharT > >class basic_iostream; +} + +extern "C++" +{ + namespace std + { + class exception + { + public:exception () throw () + { + } + }; + } +} +namespace std __attribute__ ((__visibility__ ("default"))) +{ + class ios_base + { + public:class failure:public exception + { + }; + virtual ~ ios_base (); + }; +template < typename _CharT, typename _Traits > class basic_ios:public + ios_base + { + }; +template < typename _CharT, typename _Traits > class basic_ostream:virtual public basic_ios < _CharT, + _Traits + > + { + }; +} +namespace std __attribute__ ((__visibility__ ("default"))) +{ +template < typename _CharT, typename _Traits > class basic_istream:virtual public basic_ios < _CharT, + _Traits + > + { + }; +template < typename _CharT, typename _Traits > class basic_iostream:public basic_istream < _CharT, _Traits >, public basic_ostream < _CharT, + _Traits + > + { + }; + class strstream:public basic_iostream < char > + { + virtual ~ strstream (); + }; + strstream::~strstream () + { + } +} diff --git a/gcc/testsuite/g++.dg/opt/tmp1.C b/gcc/testsuite/g++.dg/opt/tmp1.C new file mode 100644 index 000000000..21665335e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/tmp1.C @@ -0,0 +1,48 @@ +// { dg-do run } + + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 30 Jul 2003 <nathan@codesourcery.com> + +// compound exprs were causing additional temporaries. + +extern "C" int printf (char const *, ...); +extern "C" void abort (); + + +static unsigned order[] = +{ + 1, 2, 502, 102, 101, + 0 +}; + +static unsigned point; + +static void Check (unsigned t, unsigned i, void const *ptr, char const *name) +{ + printf ("%d %d %p %s\n", t, i, ptr, name); + + if (order[point++] != i + t) + abort (); + +} + +template <int I> struct A +{ + A () { Check (0, I, this, __PRETTY_FUNCTION__); } + ~A () { Check (100, I, this, __PRETTY_FUNCTION__); } + A (A const &) { Check (200, I, this, __PRETTY_FUNCTION__); } + A &operator= (A const &) { Check (300, I, this, __PRETTY_FUNCTION__); } + void Foo () const { Check (400, I, this, __PRETTY_FUNCTION__); } +}; + +template <int I> void Foo (A<I> a) +{ + Check (500, I, &a, __PRETTY_FUNCTION__); +} + +int main () +{ + Foo ((A<1> (), A<2> ())); + Check (0, 0, 0, "end"); +} diff --git a/gcc/testsuite/g++.dg/opt/unroll1.C b/gcc/testsuite/g++.dg/opt/unroll1.C new file mode 100644 index 000000000..fd07f889a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/unroll1.C @@ -0,0 +1,420 @@ +// PR optimization/12340 +// Origin: Richard Guenther <richard.guenther@uni-tuebingen.de> +// Testcase by Eric Botcazou <ebotcazou@libertysurf.fr> + +// This used to segfault on x86 because the loop optimizer wrongly +// interpreted a double assignment to a biv as a double increment, +// which subsequently fooled the unroller. + +// { dg-do run } +// { dg-options "-O2 -fno-exceptions -funroll-loops" } + +typedef __SIZE_TYPE__ size_t; + +inline void* operator new(size_t, void* __p) throw() { return __p; } +inline void operator delete (void*, void*) throw() { }; + +class Loc; +class Interval; + +template<class DT> +class DomainBase +{ +public: + typedef typename DT::Domain_t Domain_t; + typedef typename DT::Storage_t Storage_t; + + Domain_t &unwrap() { return *static_cast<Domain_t *>(this); } + + const Domain_t &unwrap() const { + return *static_cast<Domain_t *>(const_cast<DomainBase<DT> *>(this)); + } + +protected: + Storage_t domain_m; +}; + +template<class DT> +class Domain : public DomainBase<DT> +{ + typedef DomainBase<DT> Base_t; + +public: + typedef typename DT::Size_t Size_t; + typedef typename DT::Element_t Element_t; + typedef typename Base_t::Domain_t Domain_t; + typedef typename Base_t::Storage_t Storage_t; + + Domain_t &operator[](int) { return this->unwrap(); } + + const Domain_t &operator[](int) const { return this->unwrap(); } + + template<class T> + void setDomain(const T &newdom) { + DT::setDomain(this->domain_m, newdom); + } + + Element_t first() const { return DT::first(this->domain_m); } + + Size_t length() const { return DT::length(this->domain_m); } + + Size_t size() const { return length(); } +}; + +template<class T> +struct DomainTraits; + +template<> +struct DomainTraits<Interval> +{ + typedef int Size_t; + typedef int Element_t; + typedef Interval Domain_t; + typedef Interval OneDomain_t; + typedef Loc AskDomain_t; + typedef int Storage_t[2]; + enum { dimensions = 1 }; + enum { wildcard = false }; + + static int first(const Storage_t &d) { return d[0]; } + + static int length(const Storage_t &d) { return d[1]; } + + static OneDomain_t &getDomain(Domain_t &d, int) { return d; } + + static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; } + + template<class T> + static void setDomain(Storage_t &dom, const T &newdom) { + dom[0] = newdom.first(); + dom[1] = newdom.length(); + } + + template<class T1, class T2> + static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) { + dom[0] = begval; + dom[1] = (endval - begval + 1); + } + +}; + +class Interval : public Domain<DomainTraits<Interval> > +{ +public: + Interval(const Interval &a) : Domain<DomainTraits<Interval> >() { + for (int i=0; i < DomainTraits<Interval>::dimensions; ++i) + DomainTraits<Interval>::getDomain(*this, i).setDomain( + DomainTraits<Interval>::getDomain(a, i)); + } + + Interval(int a) : Domain<DomainTraits<Interval> >() + { + DomainTraits<Interval>::setDomain(domain_m, 0, a - 1); + } +}; + +template<> +struct DomainTraits<Loc> +{ + typedef int Size_t; + typedef int Element_t; + typedef Loc Domain_t; + typedef Loc AskDomain_t; + typedef Loc MultResult_t; + typedef int Storage_t; + + static int first(int d) { return d; } + + template<class T> + static void setDomain(int &dom, const T &newdom) { + dom = DomainTraits<T>::getFirst(newdom); + } +}; + +template<> +struct DomainTraits<int> + { + enum { dimensions = 1 }; + enum { wildcard = false }; + + static int getPointDomain(int d, int) { return d; } + + static int getFirst(const int &d) { return d; } +}; + +class Loc : public Domain<DomainTraits<Loc> > +{ +public: + explicit Loc(const int &a) : Domain<DomainTraits<Loc> >() { + for (int i=0; i < 1; ++i) + (*this)[i].setDomain(DomainTraits<int>::getPointDomain(a, 0)); + } +}; + +struct ElementProperties +{ + enum { hasTrivialDefaultConstructor = false }; + enum { hasTrivialDestructor = false }; + + static void construct(double* addr) + { + new (addr) double(); + } + + static void construct(double* addr, const double& model) + { + new (addr) double(model); + } + + static void destruct(double *addr) {} +}; + +class RefCounted +{ +public: + RefCounted() : count_m(0) {} + + void addReference() { ++count_m; } + bool removeRefAndCheckGarbage() + { + return (--count_m == 0); + } + +private: + int count_m; +}; + +class RefBlockController : public RefCounted +{ +public: + explicit RefBlockController(unsigned int size) + : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false) + { + reallocateStorage(size, false); + + if (!ElementProperties::hasTrivialDefaultConstructor) + { + for (double * pt = begin(); pt != end(); ++pt) + ElementProperties::construct(pt); + } + } + + ~RefBlockController() + { + deleteStorage(); + } + + double *begin() const + { + return pBegin_m; + } + + double *end() const + { + return pEnd_m; + } + + bool isMine() const + { + return dealloc_m; + } + +private: + void deleteStorage() + { + if (isMine() && pBegin_m != 0) + { + if (!ElementProperties::hasTrivialDestructor) + for (double *pt = begin(); pt != end(); ++pt) + ElementProperties::destruct(pt); + + char *tmp = reinterpret_cast<char *>(pBegin_m); + delete [] tmp; + } + } + + void reallocateStorage(unsigned int newsize, bool copyold = false) + { + double *pBeginNew = 0; + double *pEndNew = 0; + double *pEndOfStorageNew = 0; + + if (newsize > 0) + { + int nsize = newsize * sizeof(double); + char *tmp = new char[nsize]; + pBeginNew = reinterpret_cast<double *>(tmp); + pEndNew = pBeginNew + newsize; + pEndOfStorageNew = pBeginNew + (nsize / sizeof(double)); + + if (copyold) + { + double * pOld = begin(); + double * pNew = pBeginNew; + while (pOld != end() && pNew != pEndNew) + ElementProperties::construct(pNew++,*pOld++); + } + } + + deleteStorage(); + + pBegin_m = pBeginNew; + pEnd_m = pEndNew; + pEndOfStorage_m = pEndOfStorageNew; + dealloc_m = true; + } + + double *pBegin_m; + double *pEnd_m; + double *pEndOfStorage_m; + bool dealloc_m; +}; + +class DataBlockController : public RefBlockController +{ +public: + explicit + DataBlockController(unsigned int size) + : RefBlockController(size), dataObjectPtr_m(new char), owned_m(true) {} + + ~DataBlockController() + { + if (owned_m) delete dataObjectPtr_m; + } + +private: + mutable char *dataObjectPtr_m; + bool owned_m; +}; + +class RefCountedPtr +{ +public: + RefCountedPtr(DataBlockController * const pT) : ptr_m(pT) + { if (isValid()) ptr_m->addReference(); } + + ~RefCountedPtr() { invalidate(); } + + DataBlockController* operator->() const { return ptr_m; } + void invalidate(); + bool isValid() const { return ptr_m != 0; } + +private: + friend class RefCountedBlockPtr; + DataBlockController * ptr_m; +}; + +inline void RefCountedPtr::invalidate() +{ + if ( isValid() && ptr_m->removeRefAndCheckGarbage() ) + delete ptr_m; + ptr_m = 0; +} + +class RefCountedBlockPtr +{ +public: + explicit RefCountedBlockPtr(unsigned int size) + : offset_m(0), + blockControllerPtr_m(new DataBlockController(size)) {} + + int offset() const + { + return offset_m; + } + + double *beginPointer() const + { + return blockControllerPtr_m->begin(); + } + + double *currentPointer() const + { + return beginPointer() + offset(); + } + +protected: + int offset_m; + RefCountedPtr blockControllerPtr_m; +}; + +class DataBlockPtr : public RefCountedBlockPtr +{ +public: + explicit DataBlockPtr(unsigned int size) : RefCountedBlockPtr(size) {} +}; + +class Node +{ +public: + Node(const Interval &owned, const Interval &allocated) + : domain_m(owned), allocated_m(allocated) {} + + const Interval &allocated() const { return allocated_m; } + +private: + Interval domain_m; + Interval allocated_m; +}; + +class DomainLayout +{ +public: + explicit DomainLayout(const Interval &dom) : node_m(0, dom) {} + + const Interval &domain() const + { + return node_m.allocated(); + } + +private: + Node node_m; +}; + +class BrickBase +{ +public: + explicit BrickBase(const Interval &domain); + + int offset(const Loc &dom) const { return off_m + dom[0].first(); } + +protected: + DomainLayout layout_m; + int firsts_m; + int off_m; +}; + +BrickBase::BrickBase(const Interval &dom) + : layout_m(dom) +{ + firsts_m = layout_m.domain()[0].first(); + off_m = -firsts_m; +} + +class Engine : public BrickBase +{ +public: + explicit Engine(const Interval &dom) + : BrickBase(dom), dataBlock_m(dom.size()), data_m(dataBlock_m.currentPointer()) {} + + double& operator()(const Loc &loc) const + { + return data_m[this->offset(loc)]; + } + +private: + DataBlockPtr dataBlock_m; + double *data_m; +}; + + +int main() +{ + Interval I(10); + Engine A(I); + + for (int i = 0; i < 10; i++) + A(Loc(i)) = 2.0 + i - i*i; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/unroll2.C b/gcc/testsuite/g++.dg/opt/unroll2.C new file mode 100644 index 000000000..82a1e7f56 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/unroll2.C @@ -0,0 +1,27 @@ +// PR tree-opt/28937 +// Complete unroll forgot to update the statement usage +// which meant we ICEd in add_virtual_operand. + +// { dg-do compile } +// { dg-options "-O2" } + + +class SHA256 +{ + unsigned m_digest; + unsigned long long m_count; + unsigned char _buffer[64]; + static void Transform (unsigned * data); + void WriteByteBlock (unsigned t); +}; +void SHA256::WriteByteBlock (unsigned t) +{ + unsigned data32[16]; + Transform (data32); + unsigned long long lenInBits = m_count; + if (t != (64 - 8)) + return; + for (int i = 0; i < 2; i++) + _buffer[t++] = (unsigned char)lenInBits; +} + diff --git a/gcc/testsuite/g++.dg/opt/vrp2.C b/gcc/testsuite/g++.dg/opt/vrp2.C new file mode 100644 index 000000000..b2066ae2e --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/vrp2.C @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* VRP was miscompiling the following as it thought &a->b was a dereference + and therfore a was non-null. + Reduced from Mozilla by Serge Belyshev <belyshev@depni.sinp.msu.ru>. */ + +extern "C" void abort (void); +struct T { int i; } t; +struct A : T { int j; } *p = __null; + +int main (void) +{ + if (p == &t) + return 0; + if (p) + abort (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/opt/vt1.C b/gcc/testsuite/g++.dg/opt/vt1.C new file mode 100644 index 000000000..ba871fba2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/vt1.C @@ -0,0 +1,13 @@ +// Test whether vtable for S is not put into read-only section. +// { dg-do compile { target fpic } } +// { dg-options "-O2 -fpic -fno-rtti" } +// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } } +// { dg-skip-if "No Windows PIC" { *-*-mingw* *-*-cygwin } { "*" } { "" } } +// Origin: Jakub Jelinek <jakub@redhat.com> + +struct S +{ + virtual void vm (void) {}; +} x; + +// { dg-final { scan-assembler-not "section\[^\n\r\]*_ZTV1S\[^\n\r\]*\"\[^w\"\n\r\]*\"" } } |