diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/ext | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/ext')
497 files changed, 13219 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/ext/alias-canon.C b/gcc/testsuite/g++.dg/ext/alias-canon.C new file mode 100644 index 000000000..843dec00c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-canon.C @@ -0,0 +1,41 @@ +// PR c++/34935 +/* { dg-do compile } */ +/* { dg-final { scan-assembler "_Z1fi" } } */ +/* { dg-final { scan-assembler "_Z1fb" } } */ +/* { dg-final { scan-assembler "_Z1fd" } } */ +/* { dg-final { scan-assembler "_Z1ff" } } */ +/* { dg-final { scan-assembler "_Z1fw" } } */ + +typedef int INT __attribute((may_alias)); + +void f(int); +void f(INT) { } + +typedef bool BOOL __attribute((may_alias)); + +void f(bool); +void f(BOOL) { } + +typedef float FLOAT __attribute((may_alias)); + +void f(float); +void f(FLOAT) { } + +typedef double DOUBLE __attribute((may_alias)); + +void f(double); +void f(DOUBLE) {} + +typedef wchar_t WCHAR_T __attribute((may_alias)); + +void f(wchar_t); +void f(WCHAR_T) {} + +void test() +{ + f(0); + f(true); + f(1.0f); + f(1.0); + f(L'f'); +} diff --git a/gcc/testsuite/g++.dg/ext/alias-canon2.C b/gcc/testsuite/g++.dg/ext/alias-canon2.C new file mode 100644 index 000000000..4833db852 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-canon2.C @@ -0,0 +1,36 @@ +// { dg-do compile } +// PR c++/37553 +typedef unsigned int ui32; +__extension__ typedef unsigned long long int ui64; + +typedef ui32 __attribute__ ((__may_alias__)) ui32a; +typedef ui64 __attribute__ ((__may_alias__)) ui64a; + +union u_u32 +{ + ui32a v; +} __attribute__ ((__may_alias__)); + +union u_u64 +{ + ui64a v; + struct + { + union u_u32 lo32, hi32; + } u; +} __attribute__ ((__may_alias__)); + +void +out_long (ui64 longVal) +{ + if ((*(union u_u64 *) &longVal).u.lo32.v < 0x10000000ul) + { + if ((ui32) ((*(union u_u64 *) &longVal).u.lo32.v) < 0x4000u) + { + /* do something useful */ + } + } +} + +void f(ui32 *) { } +void f(ui32a *) { } diff --git a/gcc/testsuite/g++.dg/ext/alias-mangle.C b/gcc/testsuite/g++.dg/ext/alias-mangle.C new file mode 100644 index 000000000..a7706e996 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alias-mangle.C @@ -0,0 +1,11 @@ +// PR c++/34936 +// { dg-do compile } +/* { dg-final { scan-assembler "_ZN1AIdEC1Ev" } } */ +typedef double X __attribute((may_alias)) ; + +template<typename> struct A +{ + A(); +}; + +A<X> a; diff --git a/gcc/testsuite/g++.dg/ext/align1.C b/gcc/testsuite/g++.dg/ext/align1.C new file mode 100644 index 000000000..6c960c396 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/align1.C @@ -0,0 +1,21 @@ +// Test that __attribute__ ((aligned)) is preserved. +// The alignment used to be 64 but Cygwin does not +// support an alignment greater than 16 and COFF +// not support an alignment greater than 4. + +extern "C" int printf (const char *, ...); + +typedef float at[4][4] __attribute__ ((aligned)); + +float dummy[4][4][15]; + +static volatile at a1[15]; + +float f1 __attribute__ ((aligned)); + +int +main (void) +{ + printf ("%d %d\n", __alignof (a1), __alignof (f1)); + return (__alignof (a1) < __alignof (f1)); +} diff --git a/gcc/testsuite/g++.dg/ext/align2.C b/gcc/testsuite/g++.dg/ext/align2.C new file mode 100644 index 000000000..da54bd938 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/align2.C @@ -0,0 +1,14 @@ +// PR c++/10179 + +struct __attribute((aligned(__alignof(double)))) A +{ /* empty */ }; + +struct T : public A +{ + char c; +}; + +template<bool> struct StaticAssert; +template<> struct StaticAssert<true> {}; + +StaticAssert<__alignof(T) == __alignof(double)> d; diff --git a/gcc/testsuite/g++.dg/ext/alignof1.C b/gcc/testsuite/g++.dg/ext/alignof1.C new file mode 100644 index 000000000..36661c1f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alignof1.C @@ -0,0 +1,19 @@ +// { dg-do run } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Gabriel Dos Reis <gdr@codesourcery.com>, 2002-07-20 +// Bug PR/7363. + +template<typename T> +int my_alignof() +{ + return __alignof__ (T); +} + +template<typename> + struct X { }; + +int main() +{ + return !my_alignof<X<void> >(); +} diff --git a/gcc/testsuite/g++.dg/ext/alignof2.C b/gcc/testsuite/g++.dg/ext/alignof2.C new file mode 100644 index 000000000..8bc8a9c01 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/alignof2.C @@ -0,0 +1,25 @@ +// PRs 16387 and 16389 +// We were treating alignof (sa.a) as alignof (typeof (sa.a)), which is +// wrong for some fields. + +// { dg-do run } + +extern "C" void abort(); + +struct A +{ + double a; +} sa; + +struct B +{ + char c; + double b; +} sb; + +int main() +{ + if (__alignof (sa) != __alignof (sa.a) + || __alignof (sb) != __alignof (sb.b)) + abort(); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-1.C b/gcc/testsuite/g++.dg/ext/altivec-1.C new file mode 100644 index 000000000..cd7c3aad2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-1.C @@ -0,0 +1,16 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +int main() +{ + return 0; +} + +class F32vec4 { +public: + vector float val; + vector float operator++(void) { return val;} +}; diff --git a/gcc/testsuite/g++.dg/ext/altivec-10.C b/gcc/testsuite/g++.dg/ext/altivec-10.C new file mode 100644 index 000000000..7f7d2b013 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-10.C @@ -0,0 +1,22 @@ +/* This is a compile-only test for interaction of "-maltivec" and "-save-temps". */ +/* Author: Ziemowit Laski <zlaski@apple.com>. */ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-save-temps -maltivec" } */ + +#include <altivec.h> + +#define vector_float vector float +#define vector_float_foo vector float foo +#define vector_float_bar_eq vector float bar = + +/* NB: Keep the following split across three lines. */ +vector +int +a1 = { 100, 200, 300, 400 }; + +vector_float f1 = { 1.0, 2.0, 3.0, 4.0 }; +vector_float_foo = { 3.0, 4.0, 5.0, 6.0 }; +vector_float_bar_eq { 8.0, 7.0, 6.0, 5.0 }; + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/g++.dg/ext/altivec-11.C b/gcc/testsuite/g++.dg/ext/altivec-11.C new file mode 100644 index 000000000..ff3016953 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-11.C @@ -0,0 +1,12 @@ +/* Test handling of literal constant for dss operation. */ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +void +foo () +{ + vec_dss (1); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-12.C b/gcc/testsuite/g++.dg/ext/altivec-12.C new file mode 100644 index 000000000..6f21da961 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-12.C @@ -0,0 +1,19 @@ +/* Test vec_dst* functions with float pointer as first argument. */ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +extern int i; +extern float *fp; +extern vector float vf; + +void +foo () +{ + vec_dst (fp, i, 1); + vec_dstst (fp, i, 1); + vec_dststt (fp, i, 1); + vec_dstt (fp, i, 1); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-13.C b/gcc/testsuite/g++.dg/ext/altivec-13.C new file mode 100644 index 000000000..abc05af62 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-13.C @@ -0,0 +1,59 @@ +/* Check that vec_step can be used with const vector types. This + test is derived from parts of gcc.dg/vmx/8-02.c from Motorola's + AltiVec testsuite. */ + +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +extern vector unsigned char vuc; +extern vector signed char vsc; +extern vector bool char vbc; +extern vector unsigned short vus; +extern vector signed short vss; +extern vector bool short vbs; +extern vector unsigned int vui; +extern vector signed int vsi; +extern vector bool int vbi; +extern vector pixel vp; +extern vector float vf; +extern const vector unsigned char cvuc; +extern const vector signed char cvsc; +extern const vector bool char cvbc; +extern const vector unsigned short cvus; +extern const vector signed short cvss; +extern const vector bool short cvbs; +extern const vector unsigned int cvui; +extern const vector signed int cvsi; +extern const vector bool int cvbi; +extern const vector pixel cvp; +extern const vector float cvf; + +void +foo (void) +{ + int i_vuc = vec_step (vuc); + int i_vsc = vec_step (vsc); + int i_vbc = vec_step (vbc); + int i_vus = vec_step (vus); + int i_vss = vec_step (vss); + int i_vbs = vec_step (vbs); + int i_vui = vec_step (vui); + int i_vsi = vec_step (vsi); + int i_vbi = vec_step (vbi); + int i_vp = vec_step (vp); + int i_vf = vec_step (vf); + int i_cvuc = vec_step (cvuc); + int i_cvsc = vec_step (cvsc); + int i_cvbc = vec_step (cvbc); + int i_cvus = vec_step (cvus); + int i_cvss = vec_step (cvss); + int i_cvbs = vec_step (cvbs); + int i_cvui = vec_step (cvui); + int i_cvsi = vec_step (cvsi); + int i_cvbi = vec_step (cvbi); + int i_cvp = vec_step (cvp); + int i_cvf = vec_step (cvf); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-14.C b/gcc/testsuite/g++.dg/ext/altivec-14.C new file mode 100644 index 000000000..e5dd81c75 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-14.C @@ -0,0 +1,13 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +void f (__attribute__((altivec (vector__))) signed int * a, + __attribute__((altivec (vector__))) signed int * const b); + +int +foo (void) +{ + __attribute__((altivec (vector__))) signed int a[1], b[1]; + f (a, b); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-15.C b/gcc/testsuite/g++.dg/ext/altivec-15.C new file mode 100644 index 000000000..d8e982db4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-15.C @@ -0,0 +1,16 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -mno-vsx" } */ + +/* This test was added for an internal compiler error. The number and + content of error messages is irrelevant. */ + +struct SubData +{ + inline const Float Clamp(Float f, Float f0, Float f1) // { dg-error "" } + } + inline const void SinCos(Float angle, Float& sine, Float& cosine) // { dg-error "" } + { + C0 = __builtin_vec_splat(_simdCosEstCoefficients, 0); + C1 = __builtin_vec_splat(_simdCosEstCoefficients, 1); + diff --git a/gcc/testsuite/g++.dg/ext/altivec-16.C b/gcc/testsuite/g++.dg/ext/altivec-16.C new file mode 100644 index 000000000..91230d261 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-16.C @@ -0,0 +1,19 @@ +// PR c++/36662 +// { dg-do compile { target powerpc*-*-* } } +// { dg-require-effective-target powerpc_altivec_ok } +// { dg-options "-maltivec" } + +#define vector __attribute__((altivec (vector__))) + +template <typename c> struct S {}; + +template <> struct S<vector float> +{ + static vector float zero; +}; + +template <int> +void g (void) +{ + vector float t = S<vector float>::zero; +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-17.C b/gcc/testsuite/g++.dg/ext/altivec-17.C new file mode 100644 index 000000000..099f8742e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-17.C @@ -0,0 +1,16 @@ +// { dg-do compile { target powerpc*-*-* } } +// { dg-require-effective-target powerpc_altivec_ok } +// { dg-options "-maltivec" } + +// Make sure that bool vectors have distinct names to int vectors + +#define vector__ __attribute__((altivec (vector__))) +#define bool__ __attribute__((altivec(bool__))) + +typedef vector__ unsigned int simd_type; +typedef vector__ bool__ int bool_simd_type; + +void Foo (bool_simd_type const &a) +{ + simd_type const &v = a; // { dg-error "invalid initialization of reference of type" } +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-2.C b/gcc/testsuite/g++.dg/ext/altivec-2.C new file mode 100644 index 000000000..eb8a92942 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-2.C @@ -0,0 +1,25 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -Wall -Wno-unused-but-set-variable" } */ + +/* This test checks if AltiVec builtins accept const-qualified + arguments. */ + +#include <altivec.h> + +vector unsigned char use_lvsl; + +int main (int argc, const char * argv[]) +{ + int i = 0; + const float cf = 1.0; + vector float v; + const vector float cv = (vector float){1.0, 2.0, 3.0, 4.0}; + + vec_dst(&cv, i, 0); + v = vec_ld(0, &cv); + v = vec_lde(0, &cf); + use_lvsl = vec_lvsl(0, &cf); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-3.C b/gcc/testsuite/g++.dg/ext/altivec-3.C new file mode 100644 index 000000000..151132059 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-3.C @@ -0,0 +1,137 @@ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +/* Test for correct handling of AltiVec constants passed + through '...' (va_arg). */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include <altivec.h> + +#define CHECK_INVARIANT(expr) \ + if (!(expr)) { \ + printf ("ASSERT FAILED: %d: %s\n", __LINE__, #expr); \ + abort (); \ + } + +struct foo { int x; int y; }; +struct vfoo { int x; __vector signed int v; int y; }; +union u { __vector signed int v; signed int i[4]; }; + +struct foo x_g = { 3, 4}; +struct vfoo vx_g = { 10, {11, 12, 13, 14}, 15 }; +__vector signed int v_g = {22, 23, 24, 25}; +struct vfoo vx2_g = { 30, {31, 32, 33, 34}, 35 }; +__vector signed int v2_g = {40, 41, 42, 43}; +int i_1 = 99, i_2 = 33; +double d_2 = 1.5, d_3 = 1.75; +double ld_1 = 1.25; + +void bar (int i, ... ) +{ + struct foo xi; + double d; + double ld; + float f; + char c; + short s; + va_list ap; + va_start(ap, i); + xi = va_arg(ap, struct foo); + s = (short)va_arg(ap, int); + f = (float)va_arg(ap, double); + ld = va_arg(ap, double); + c = (char)va_arg(ap, int); + d = va_arg(ap, double); + va_end(ap); + + CHECK_INVARIANT (xi.x == x_g.x && xi.y == x_g.y); + CHECK_INVARIANT (s == (short)i_2); + CHECK_INVARIANT (f == (float)d_2); + CHECK_INVARIANT (ld == ld_1); + CHECK_INVARIANT (c == (char)i_1); + CHECK_INVARIANT (d == d_3); +} + +void baz (int i, ... ) +{ + struct vfoo vx, vx2; + __vector signed int v_i, v2_i; + int j, k, l; + va_list ap; + va_start(ap, i); + v_i = va_arg(ap, __vector signed int); + j = va_arg(ap, int); + vx = va_arg(ap, struct vfoo); + k = va_arg(ap, int); + v2_i = va_arg(ap, __vector signed int); + l = va_arg(ap, int); + vx2 = va_arg(ap, struct vfoo); + va_end(ap); + + CHECK_INVARIANT (vec_all_eq (v_i, v_g)); + CHECK_INVARIANT (j == i_1); + CHECK_INVARIANT (vx.x == vx_g.x); + CHECK_INVARIANT (vec_all_eq (vx.v, vx_g.v)); + CHECK_INVARIANT (vx.y == vx_g.y); + CHECK_INVARIANT (k == i_1); + CHECK_INVARIANT (vec_all_eq (v2_i, v2_g)); + CHECK_INVARIANT (l == i_1); + CHECK_INVARIANT (vx2.x == vx2_g.x); + CHECK_INVARIANT (vec_all_eq (vx2.v, vx2_g.v)); + CHECK_INVARIANT (vx2.y == vx2_g.y); +} + +void quux (int i, ... ) +{ + __vector signed int v_i, v2_i; + union u vi, v2i; + va_list ap; + va_start(ap, i); + v_i = va_arg(ap, __vector signed int); + v2_i = va_arg(ap, __vector signed int); + va_end(ap); + vi.v = v_i; + v2i.v = v2_i; + + CHECK_INVARIANT (vec_all_eq (v_i, v_g)); + CHECK_INVARIANT (vec_all_eq (v2_i, v_g)); + CHECK_INVARIANT (vec_all_eq (vi.v, v_g)); + CHECK_INVARIANT (vec_all_eq (v2i.v, v_g)); +} + +void baz2 (int i, ... ) +{ + struct vfoo vx; + union u vxi; + va_list ap; + va_start(ap, i); + vx = va_arg(ap, struct vfoo); + va_end(ap); + vxi.v = vx.v; + + CHECK_INVARIANT (vx.x == vx_g.x); + CHECK_INVARIANT (vec_all_eq (vx.v, vx_g.v)); + CHECK_INVARIANT (vx.y == vx_g.y); + CHECK_INVARIANT (vec_all_eq (vxi.v, vx_g.v)); +} + +void main1(void) +{ + CHECK_INVARIANT (sizeof(struct foo) == 8 && sizeof(struct vfoo) == 48); + + bar(i_1, x_g, (short)i_2, (float)d_2, ld_1, (char)i_1, d_3); + baz(i_1, v_g, i_1, vx_g, i_1, v2_g, i_1, vx2_g); + quux(i_1, v_g, v_g); + baz2(i_1, vx_g); +} + +int main(void) +{ + main1(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-4.C b/gcc/testsuite/g++.dg/ext/altivec-4.C new file mode 100644 index 000000000..86a2615dc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-4.C @@ -0,0 +1,12 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +/* PR c++/14425 */ + +#include <altivec.h> + +vector unsigned int splat0(vector unsigned int x) +{ + return vec_splat(x, 0); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-5.C b/gcc/testsuite/g++.dg/ext/altivec-5.C new file mode 100644 index 000000000..04c26e80f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-5.C @@ -0,0 +1,16 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +/* PR c++/14426 */ + +#include <altivec.h> + +vector unsigned int splat0u() +{ + return vec_splat_u32(0); +} +vector int splat0s() +{ + return vec_splat_s32(0); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-6.C b/gcc/testsuite/g++.dg/ext/altivec-6.C new file mode 100644 index 000000000..63ae0b0b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-6.C @@ -0,0 +1,28 @@ +/* Test for correct handling of literal arguments. */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +void foo(void) { + const unsigned char *buf; + vector pixel vp = { 3, 4, 5, 6 }; + vector bool int vbi = { 1, 0, 1, 0 }; + vector bool short vbs = { 1, 0, 1, 0, 1, 0, 1, 0 }; + vector bool char vbc = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; + vector signed char vsc; + int a = 3; + + vec_dst(buf, a, 1); + vec_dstst(buf, a, 2); + vec_dststt(buf, a, 3); + vec_dststt(buf, a, 2); + + vp = vec_sld(vp, vp, 5); + vbc = vec_splat(vbc, 7); + vbs = vec_splat(vbs, 12); + vp = vec_splat(vp, 17); + vbi = vec_splat(vbi, 31); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-7.C b/gcc/testsuite/g++.dg/ext/altivec-7.C new file mode 100644 index 000000000..7c458fb00 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-7.C @@ -0,0 +1,36 @@ +/* Test for AltiVec type overloading and name mangling. */ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +void foo(vector unsigned char) { } +void foo(vector signed char) { } +void foo(vector bool char) { } +void foo(vector unsigned short) { } +void foo(vector signed short) { } +void foo(vector bool short) { } +void foo(vector unsigned int) { } +void foo(vector signed int) { } +void foo(vector bool int) { } +void foo(vector float) { } +void foo(vector pixel) { } +void foo(int) { } +void foo(unsigned int) { } +void foo(float) { } + +/* { dg-final { scan-assembler "_Z3fooU8__vectorh" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectora" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectorU6__boolc" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectort" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectors" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectorU6__bools" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectorj" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectori" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectorU6__booli" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectorf" } } */ +/* { dg-final { scan-assembler "_Z3fooU8__vectoru7__pixel" } } */ +/* { dg-final { scan-assembler "_Z3fooi" } } */ +/* { dg-final { scan-assembler "_Z3fooj" } } */ +/* { dg-final { scan-assembler "_Z3foof" } } */ diff --git a/gcc/testsuite/g++.dg/ext/altivec-8.C b/gcc/testsuite/g++.dg/ext/altivec-8.C new file mode 100644 index 000000000..3c5a76e06 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-8.C @@ -0,0 +1,21 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ +/* Author: Ziemowit Laski <zlaski@apple.com> */ + +/* This test case exercises intrinsic/argument combinations that, + while not in the Motorola AltiVec PIM, have nevertheless crept + into the AltiVec vernacular over the years. */ + +#include <altivec.h> + +void foo (void) +{ + vector bool int boolVec1 = (vector bool int) vec_splat_u32(3); + vector bool short boolVec2 = (vector bool short) vec_splat_u16(3); + vector bool char boolVec3 = (vector bool char) vec_splat_u8(3); + + boolVec1 = vec_sld( boolVec1, boolVec1, 4 ); + boolVec2 = vec_sld( boolVec2, boolVec2, 2 ); + boolVec3 = vec_sld( boolVec3, boolVec3, 1 ); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-9.C b/gcc/testsuite/g++.dg/ext/altivec-9.C new file mode 100644 index 000000000..174ae63ed --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-9.C @@ -0,0 +1,14 @@ +/* Test for AltiVec function vec_ld, passing a pointer to const vector */ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +#include <altivec.h> + +typedef vector unsigned char vuc_t; +const vuc_t* p; +vector unsigned char test_vec_ld() +{ + return vec_ld(0,p); +} + diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-1.C b/gcc/testsuite/g++.dg/ext/altivec-cell-1.C new file mode 100644 index 000000000..16d311c3b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-1.C @@ -0,0 +1,94 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +/* Basic test for the new VMX intrinsics. */ +#include <altivec.h> + +int f(vector int a, int b) +{ + return vec_extract (a, b); +} +short f1(vector short a, int b) +{ + return vec_extract (a, b); +} +vector short f2(vector short a, int b) +{ + return vec_insert (b, a, b); +} +vector float f3(vector float a, int b) +{ + return vec_insert (b, a, b); +} + +float g(void); + +vector float f4(float b, int t) +{ + return vec_promote (g(), t); +} +vector float f5(float b) +{ + return vec_splats (g()); +} + + + + +template <int> +int tf(vector int a, int b) +{ + return vec_extract (a, b); +} +template <int> +short tf1(vector short a, int b) +{ + return vec_extract (a, b); +} +template <int> +vector short tf2(vector short a, int b) +{ + return vec_insert (b, a, b); +} +template <int> +vector float tf3(vector float a, int b) +{ + return vec_insert (b, a, b); +} + +template <int> +vector float tf4(float b, int t) +{ + return vec_promote (g(), t); +} +template <int> +vector float tf5(float b) +{ + return vec_splats (g()); +} + +int t(vector int a, int b) +{ + return tf<1>(a, b); +} +short t1(vector short a, int b) +{ + return tf1<1>(a, b); +} +vector short t2(vector short a, int b) +{ + return tf2<1>(a, b); +} +vector float t3(vector float a, int b) +{ + return tf3<1>(a, b); +} +vector float t4(float b, int t) +{ + return tf4<1>(b, t); +} +vector float t5(float b) +{ + return tf5<1>(b); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-2.C b/gcc/testsuite/g++.dg/ext/altivec-cell-2.C new file mode 100644 index 000000000..f0d3433cd --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-2.C @@ -0,0 +1,141 @@ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ +/* Test the vec_extract VMX intrinsics. */ +#include <altivec.h> + +extern "C" void abort (void); + +vector int a = {0, 1, 2, 3}; +vector short b = {0, 1, 2, 3, 4, 5, 6, 7}; + +int f(vector int a, int b) +{ + return vec_extract (a, b); +} + +int f0 (vector int a) +{ + return vec_extract (a, 0); +} +int f1 (vector int a) +{ + return vec_extract (a, 1); +} +int f2 (vector int a) +{ + return vec_extract (a, 2); +} +int f3 (vector int a) +{ + return vec_extract (a, 3); +} +int f4 (vector int a) +{ + return vec_extract (a, 4); +} + +int g(vector short a, int b) +{ + return vec_extract (a, b); +} + +int g0 (vector short a) +{ + return vec_extract (a, 0); +} +int g1 (vector short a) +{ + return vec_extract (a, 1); +} +int g2 (vector short a) +{ + return vec_extract (a, 2); +} +int g3 (vector short a) +{ + return vec_extract (a, 3); +} + +int g4 (vector short a) +{ + return vec_extract (a, 4); +} +int g5 (vector short a) +{ + return vec_extract (a, 5); +} +int g6 (vector short a) +{ + return vec_extract (a, 6); +} +int g7 (vector short a) +{ + return vec_extract (a, 7); +} +int g8 (vector short a) +{ + return vec_extract (a, 8); +} +int main1(void) __attribute__((noinline)); +int main1(void) +{ + int i; + /* Check vec_extract with a non constant element numbering */ + for(i=0;i<10;i++) + { + if (f(a, i) != (i&0x3)) + abort (); + } + + /* Check vec_extract with a constant element numbering */ + if (f0(a) != 0) + abort (); + if (f1(a) != 1) + abort (); + if (f2(a) != 2) + abort (); + if (f3(a) != 3) + abort (); + /* Check that vec_extract works with a constant element higher than + the number of elements. */ + if (f4(a) != 0) + abort (); + + /* Check vec_extract with a non constant element numbering */ + for(i=0;i<10;i++) + { + if (g(b, i) != (i&0x7)) + abort (); + } + + /* Check vec_extract with a constant element numbering */ + if (g0(b) != 0) + abort (); + if (g1(b) != 1) + abort (); + if (g2(b) != 2) + abort (); + if (g3(b) != 3) + abort (); + if (g4(b) != 4) + abort (); + if (g5(b) != 5) + abort (); + if (g6(b) != 6) + abort (); + if (g7(b) != 7) + abort (); + /* Check that vec_extract works with a constant element higher than + the number of elements. */ + if (g8(b) != 0) + abort (); + + return 0; +} + +int main(void) +{ + return main1 (); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-3.C b/gcc/testsuite/g++.dg/ext/altivec-cell-3.C new file mode 100644 index 000000000..bd7e774e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-3.C @@ -0,0 +1,37 @@ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ +/* Test the vec_splats and vec_promote VMX intrinsics. */ +#include <altivec.h> + +extern "C" void abort (void); + +vector int a = {0, 0, 0, 0}; +int main1(int t) __attribute__((noinline)); +int main1(int t) +{ + int i; + vector int b = vec_splats(0); + if (__builtin_memcmp (&a, &b, sizeof(vector int))) + abort (); + + b = vec_splats(t); + if (__builtin_memcmp (&a, &b, sizeof(vector int))) + abort (); + + b = vec_promote(0, 1); + if (vec_extract (b, 1) != 0) + abort (); + + b = vec_promote(t, t); + if (vec_extract (b, t) != 0) + abort (); + + return 0; +} + +int main(void) +{ + return main1 (0); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-4.C b/gcc/testsuite/g++.dg/ext/altivec-cell-4.C new file mode 100644 index 000000000..7d91adbb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-4.C @@ -0,0 +1,42 @@ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +/* Test the vec_splats and vec_promote VMX intrinsics. */ +#include <altivec.h> + +extern "C" void abort (void); + +vector int a[] = {{0, 0, 0, 0}, {1,0,0,0}, {1,2,0,0},{1,2,3,0},{1,2,3,4},{5,2,3,4},{5,6,3,4}}; +vector int c = {0,6,3,4}; +vector int d = {0,0,3,4}; +int main1(int t) __attribute__((noinline)); +int main1(int t) +{ + int i; + vector int b = vec_splats(0); + for(i = 0;i<sizeof(a)/sizeof(a[0])-1;i++) + { + if (__builtin_memcmp (&b, &a[i], sizeof(vector int))) + abort (); + b = vec_insert(i+1, b, i); + } + if (__builtin_memcmp (&b, &a[i], sizeof(vector int))) + abort (); + + b = vec_insert(0, b, 0); + if (__builtin_memcmp (&b, &c, sizeof(vector int))) + abort (); + + b = vec_insert(0, b, 1); + if (__builtin_memcmp (&b, &d, sizeof(vector int))) + abort (); + + return 0; +} + +int main(void) +{ + return main1 (0); +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-5.C b/gcc/testsuite/g++.dg/ext/altivec-cell-5.C new file mode 100644 index 000000000..95f109d1a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-cell-5.C @@ -0,0 +1,25 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec" } */ + +/* Basic test for the new VMX intrinsics and error messages. */ +#include <altivec.h> + +int main(int argc, char **argv) +{ +vector float t; + vec_promote(); /* { dg-error "vec_promote only accepts 2" } */ + vec_promote(1.0f); /* { dg-error "vec_promote only accepts 2" } */ + vec_promote(1.0f, 2, 3); /* { dg-error "vec_promote only accepts 2" } */ + vec_extract (); /* { dg-error "vec_extract only accepts 2" } */ + vec_extract (t); /* { dg-error "vec_extract only accepts 2" } */ + vec_extract (t, 2); + vec_extract (t, 2, 5, 6); /* { dg-error "vec_extract only accepts 2" } */ + vec_splats (); /* { dg-error "vec_splats only accepts 1" } */ + vec_splats (t, 3); /* { dg-error "vec_splats only accepts 1" } */ + vec_insert (); /* { dg-error "vec_insert only accepts 3" } */ + vec_insert (t); /* { dg-error "vec_insert only accepts 3" } */ + vec_insert (t, 3); /* { dg-error "vec_insert only accepts 3" } */ + vec_insert (t, 3, 2, 4, 6, 6); /* { dg-error "vec_insert only accepts 3" } */ + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/altivec-types-1.C b/gcc/testsuite/g++.dg/ext/altivec-types-1.C new file mode 100644 index 000000000..f54aeec46 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-types-1.C @@ -0,0 +1,88 @@ +/* { dg-do compile { target powerpc*-*-linux* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -mno-vsx -std=c++98" } */ + +/* Valid AltiVec vector types should be accepted with no warnings. */ + +__vector char vc; +__vector unsigned char vuc; +__vector signed char vsc; +__vector __bool char vbc; +__vector short vh; +__vector signed short vsh; +__vector unsigned short vuh; +__vector short int vhi; +__vector signed short int vshi; +__vector unsigned short int vuhi; +__vector __bool short vbh; +__vector __bool short int vbhi; +__vector int vi; +__vector unsigned int vui; +__vector signed int vsi; +__vector __bool int vbi; +__vector unsigned vuj; +__vector signed vsj; +__vector __bool vbj; +__vector float vf; + +/* These should be rejected as invalid AltiVec types. */ + +__vector bool vb; /* { dg-error "AltiVec types" "" } */ +__vector long long vll; /* { dg-error "AltiVec types" "" } */ +__vector unsigned long long vull; /* { dg-error "AltiVec types" "" } */ +__vector signed long long vsll; /* { dg-error "AltiVec types" "" } */ +__vector __bool long long vbll; /* { dg-error "AltiVec types" "" } */ +__vector long long int vlli; /* { dg-error "AltiVec types" "" } */ +__vector unsigned long long int vulli; /* { dg-error "AltiVec types" "" } */ +__vector signed long long int vslli; /* { dg-error "AltiVec types" "" } */ +__vector __bool long long int vblli; /* { dg-error "AltiVec types" "" } */ +__vector double vd1; /* { dg-error "AltiVec types" "" } */ +__vector long double vld; /* { dg-error "AltiVec types" "" } */ +__vector _Complex float vcf; /* { dg-error "AltiVec types" "" } */ +__vector _Complex double vcd; /* { dg-error "AltiVec types" "" } */ +__vector _Complex long double vcld; /* { dg-error "AltiVec types" "" } */ +__vector _Complex signed char vcsc; /* { dg-error "AltiVec types" "" } */ +__vector _Complex unsigned char vcuc; /* { dg-error "AltiVec types" "" } */ +__vector _Complex short vcss; /* { dg-error "AltiVec types" "" } */ +__vector _Complex unsigned short vcus; /* { dg-error "AltiVec types" "" } */ +__vector _Complex int vcsi; /* { dg-error "AltiVec types" "" } */ +__vector _Complex unsigned int vcui; /* { dg-error "AltiVec types" "" } */ +__vector _Complex long vcsl; /* { dg-error "AltiVec types" "" } */ +__vector _Complex unsigned long vcul; /* { dg-error "AltiVec types" "" } */ +__vector _Complex long long vcsll; /* { dg-error "AltiVec types" "" } */ +__vector _Complex unsigned long long vcull; /* { dg-error "AltiVec types" "" } */ +__vector __complex float v_cf; /* { dg-error "AltiVec types" "" } */ +__vector __complex double v_cd; /* { dg-error "AltiVec types" "" } */ +__vector __complex long double v_cld; /* { dg-error "AltiVec types" "" } */ +__vector __complex signed char v_csc; /* { dg-error "AltiVec types" "" } */ +__vector __complex unsigned char v_cuc; /* { dg-error "AltiVec types" "" } */ +__vector __complex short v_css; /* { dg-error "AltiVec types" "" } */ +__vector __complex unsigned short v_cus; /* { dg-error "AltiVec types" "" } */ +__vector __complex int v_csi; /* { dg-error "AltiVec types" "" } */ +__vector __complex unsigned int v_cui; /* { dg-error "AltiVec types" "" } */ +__vector __complex long v_csl; /* { dg-error "AltiVec types" "" } */ +__vector __complex unsigned long v_cul; /* { dg-error "AltiVec types" "" } */ +__vector __complex long long v_csll; /* { dg-error "AltiVec types" "" } */ +__vector __complex unsigned long long v_cull; /* { dg-error "AltiVec types" "" } */ + +/* These should be rejected because the component types are invalid. We + don't care about the actual error messages here. */ + +__vector __bool unsigned char vbuc; /* { dg-error "" "" } */ +__vector __bool signed char vbsc; /* { dg-error "" "" } */ +__vector __bool unsigned short vbuh; /* { dg-error "" "" } */ +__vector __bool signed short vbsh; /* { dg-error "" "" } */ +__vector __bool unsigned int vbui; /* { dg-error "" "" } */ +__vector __bool signed int vbsi; /* { dg-error "" "" } */ +__vector __bool unsigned vbuj; /* { dg-error "" "" } */ +__vector __bool signed vbsj; /* { dg-error "" "" } */ +__vector signed float vsf; /* { dg-error "" "" } */ +__vector unsigned float vuf; /* { dg-error "" "" } */ +__vector short float vsf; /* { dg-error "" "" } */ +__vector signed double vsd; /* { dg-error "" "" } */ +__vector unsigned double vud; /* { dg-error "" "" } */ +__vector short double vsd; /* { dg-error "" "" } */ +__vector __bool float vbf; /* { dg-error "" "" } */ +__vector __bool double vbd; /* { dg-error "" "" } */ +__vector __bool short float blf; /* { dg-error "" "" } */ +__vector __bool short double vlbd; /* { dg-error "" "" } */ diff --git a/gcc/testsuite/g++.dg/ext/altivec-types-2.C b/gcc/testsuite/g++.dg/ext/altivec-types-2.C new file mode 100644 index 000000000..cee6c8f26 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-types-2.C @@ -0,0 +1,14 @@ +/* { dg-do compile { target powerpc*-*-linux* } } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -mno-vsx" } */ + +/* These should get warnings for 32-bit code. */ + +__vector long vl; /* { dg-warning "deprecated" "" } */ +__vector unsigned long vul; /* { dg-warning "deprecated" "" } */ +__vector signed long vsl; /* { dg-warning "deprecated" "" } */ +__vector __bool long int vbli; /* { dg-warning "deprecated" "" } */ +__vector long int vli; /* { dg-warning "deprecated" "" } */ +__vector unsigned long int vuli; /* { dg-warning "deprecated" "" } */ +__vector signed long int vsli; /* { dg-warning "deprecated" "" } */ diff --git a/gcc/testsuite/g++.dg/ext/altivec-types-3.C b/gcc/testsuite/g++.dg/ext/altivec-types-3.C new file mode 100644 index 000000000..6bea9a145 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-types-3.C @@ -0,0 +1,14 @@ +/* { dg-do compile { target powerpc*-*-linux* } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-maltivec -mno-vsx" } */ + +/* These should be rejected for 64-bit code. */ + +__vector long vl; /* { dg-error "invalid for 64" "" } */ +__vector unsigned long vul; /* { dg-error "invalid for 64" "" } */ +__vector signed long vsl; /* { dg-error "invalid for 64" "" } */ +__vector __bool long int vbli; /* { dg-error "invalid for 64" "" } */ +__vector long int vli; /* { dg-error "invalid for 64" "" } */ +__vector unsigned long int vuli; /* { dg-error "invalid for 64" "" } */ +__vector signed long int vsli; /* { dg-error "invalid for 64" "" } */ diff --git a/gcc/testsuite/g++.dg/ext/altivec-types-4.C b/gcc/testsuite/g++.dg/ext/altivec-types-4.C new file mode 100644 index 000000000..b937f3cf1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/altivec-types-4.C @@ -0,0 +1,15 @@ +/* { dg-do compile { target powerpc*-*-linux* } } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -mno-vsx -mno-warn-altivec-long" } */ + +/* These should not get warnings for 32-bit code when the warning is + disabled. */ + +__vector long vl; +__vector unsigned long vul; +__vector signed long vsl; +__vector __bool long int vbli; +__vector long int vli; +__vector unsigned long int vuli; +__vector signed long int vsli; diff --git a/gcc/testsuite/g++.dg/ext/always_inline-1.C b/gcc/testsuite/g++.dg/ext/always_inline-1.C new file mode 100644 index 000000000..284fd17a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/always_inline-1.C @@ -0,0 +1,26 @@ +// { dg-options "-O0" } +// { dg-do compile } +// PR C++/34715 + + +namespace X +{ + template <class T> + const T& min(const T& a, const T& b); + + template <class T> + inline __attribute__ ((always_inline)) const T& min(const T& a, const T& b) + { + return a < b ? a : b; + } +} +template <class T> +inline __attribute__ ((always_inline)) T y(const T& a, const T& b) +{ + return X::min(a, b); +} +int main() +{ + int a = 0, b = 0; + return y(a, b); +} diff --git a/gcc/testsuite/g++.dg/ext/always_inline-2.C b/gcc/testsuite/g++.dg/ext/always_inline-2.C new file mode 100644 index 000000000..31123c192 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/always_inline-2.C @@ -0,0 +1,26 @@ +// { dg-options "-O0" } +// { dg-do compile } +// PR C++/34715 + + +namespace X +{ + template <class T> + const T& min123(const T& a, const T& b); +} + + +template <class T> +inline __attribute__ ((always_inline)) const T& X::min123(const T& a, const T& b) +{ + return a < b ? a : b; +} +int main() +{ + int a, b; + return X::min123(a, b); +} + + + +// { dg-final { scan-assembler-not "min123" } } diff --git a/gcc/testsuite/g++.dg/ext/always_inline-3.C b/gcc/testsuite/g++.dg/ext/always_inline-3.C new file mode 100644 index 000000000..e008932bf --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/always_inline-3.C @@ -0,0 +1,26 @@ +// { dg-options "-O0" } +// { dg-do compile } +// PR C++/34715 + + +namespace X +{ + template <class T> + inline __attribute__ ((always_inline)) const T& min123(const T& a, const T& b); +} + + +template <class T> +inline __attribute__ ((always_inline)) const T& X::min123(const T& a, const T& b) +{ + return a < b ? a : b; +} +int main() +{ + int a, b; + return X::min123(a, b); +} + + + +// { dg-final { scan-assembler-not "min123" } } diff --git a/gcc/testsuite/g++.dg/ext/always_inline-4.C b/gcc/testsuite/g++.dg/ext/always_inline-4.C new file mode 100644 index 000000000..e95076193 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/always_inline-4.C @@ -0,0 +1,20 @@ +// { dg-options "-O0" } +// { dg-do compile } +// PR C++/34715 + + template <class T> + const T& min123(const T& a, const T& b); +template <class T> +inline __attribute__ ((always_inline)) const T& +min123(const T& a, const T& b) +{ + return a < b ? a : b; +} +int main() +{ + int a, b; + return min123(a, b); +} + + +// { dg-final { scan-assembler-not "min123" } } diff --git a/gcc/testsuite/g++.dg/ext/always_inline-5.C b/gcc/testsuite/g++.dg/ext/always_inline-5.C new file mode 100644 index 000000000..73caa094f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/always_inline-5.C @@ -0,0 +1,28 @@ +// { dg-do compile } +struct f +{ + inline f(void); + inline void f1(void); + int a; +}; + +inline __attribute__((always_inline)) f::f(void) +{ + a++; +} + +inline __attribute__((always_inline)) void f::f1(void) +{ + a++; +} + +void g(void) +{ + f a, b, c, d; + a.f1(); +} + +// f::f() should be inlined even at -O0 +// { dg-final { scan-assembler-not "_ZN1fC1Ev" } } +// Likewise for f::f1() +// { dg-final { scan-assembler-not "_ZN1f2f1Ev" } } diff --git a/gcc/testsuite/g++.dg/ext/anon-struct1.C b/gcc/testsuite/g++.dg/ext/anon-struct1.C new file mode 100644 index 000000000..0a682db1a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct1.C @@ -0,0 +1,50 @@ +/* { dg-options "-ansi -pedantic -pedantic-errors" } */ +/* In strict ISO C++ mode, we don't recognize the anonymous struct + extension or any Microsoft C extensions. */ + +struct A { char a; }; + +struct B { + struct A; /* forward decl of B::A. */ + char b; +}; +char testB[sizeof(B) == sizeof(A) ? 1 : -1]; + +struct C { + struct D { char d; }; /* decl of C::D. */ + char c; +}; +char testC[sizeof(C) == sizeof(A) ? 1 : -1]; +char testD[sizeof(C::D) == sizeof(A) ? 1 : -1]; + +/* GNU extension. */ +struct E { + struct { char z; }; /* { dg-error "prohibits anonymous structs" } */ + char e; +}; + +typedef struct A typedef_A; +struct F { + typedef_A; /* { dg-error "does not declare anything" } */ + char f; +}; +char testF[sizeof(struct F) == sizeof(struct A) ? 1 : -1]; + +/* __extension__ enables GNU C mode for the duration of the declaration. */ +__extension__ struct G { + struct { char z; }; + char g; +}; +char testG[sizeof(G) == 2 * sizeof(A) ? 1 : -1]; + +struct H { + __extension__ struct { char z; }; + char h; +}; +char testH[sizeof(H) == 2 * sizeof(A) ? 1 : -1]; + +/* Make sure __extension__ gets turned back off. */ +struct I { + struct { char z; }; /* { dg-error "prohibits anonymous structs" } */ + char i; +}; diff --git a/gcc/testsuite/g++.dg/ext/anon-struct2.C b/gcc/testsuite/g++.dg/ext/anon-struct2.C new file mode 100644 index 000000000..0c629ed48 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct2.C @@ -0,0 +1,46 @@ +/* { dg-options "" } */ +/* In GNU C++ mode, we recognize the anonymous struct extension, + but not Microsoft C extensions. */ + +struct A { char a; }; + +struct B { + struct A; /* forward decl of B::A. */ + char b; +}; +char testB[sizeof(B) == sizeof(A) ? 1 : -1]; + +struct C { + struct D { char d; }; /* decl of C::D. */ + char c; +}; +char testC[sizeof(C) == sizeof(A) ? 1 : -1]; +char testD[sizeof(C::D) == sizeof(A) ? 1 : -1]; + +/* GNU extension. */ +struct E { + struct { char z; }; + char e; +}; +char testE[sizeof(E) == 2 * sizeof(A) ? 1 : -1]; +char testEz[sizeof( ((E *)0)->z )]; + +typedef struct A typedef_A; +struct F { + typedef_A; /* { dg-error "does not declare anything" } */ + char f; +}; +char testF[sizeof(F) == sizeof(A) ? 1 : -1]; + +/* Test that __extension__ does the right thing coming _from_ GNU C mode. */ +__extension__ struct G { + struct { char z; }; + char g; +}; +char testG[sizeof(G) == 2 * sizeof(A) ? 1 : -1]; + +struct H { + struct { char z; }; + char h; +}; +char testH[sizeof(H) == 2 * sizeof(A) ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/anon-struct3.C b/gcc/testsuite/g++.dg/ext/anon-struct3.C new file mode 100644 index 000000000..1460d6c12 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct3.C @@ -0,0 +1,34 @@ +/* { dg-options "-fms-extensions" } */ +/* Verify that enabling Microsoft mode doesn't twist C++ as much as + their corresponding C extensions. Checked vs + Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86 + */ + +struct A { char a; }; + +struct B { + struct A; /* forward decl of B::A. */ + char b; +}; +char testB[sizeof(B) == sizeof(A) ? 1 : -1]; + +struct C { + struct D { char d; }; /* decl of C::D. */ + char c; +}; +char testC[sizeof(C) == sizeof(A) ? 1 : -1]; +char testD[sizeof(C::D) == sizeof(A) ? 1 : -1]; + +struct E { + struct { char z; }; + char e; +}; +char testE[sizeof(E) == 2 * sizeof(A) ? 1 : -1]; +char testEz[sizeof( ((E *)0)->z )]; + +typedef struct A typedef_A; +struct F { + typedef_A; /* { dg-error "does not declare anything" } */ + char f; +}; +char testF[sizeof(F) == sizeof(A) ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/anon-struct4.C b/gcc/testsuite/g++.dg/ext/anon-struct4.C new file mode 100644 index 000000000..fa5bd4b3d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct4.C @@ -0,0 +1,5 @@ +// PR c++/14401 + +struct { struct { int& i ; } bar ; } foo ; // { dg-error "uninitialized" "uninit" } +// { dg-warning "anonymous" "anon" { target *-*-* } 3 } +// { dg-message "should be initialized" "ref-uninit" { target *-*-* } 3 } diff --git a/gcc/testsuite/g++.dg/ext/anon-struct5.C b/gcc/testsuite/g++.dg/ext/anon-struct5.C new file mode 100644 index 000000000..8b697ccbc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct5.C @@ -0,0 +1,13 @@ +// PR c++/30302 + +struct A +{ + struct { static int i; }; // { dg-error "prohibits anonymous structs|an anonymous struct" } + void foo() { i; } +}; + +struct B +{ + union { static int i; }; // { dg-error "an anonymous union|member of a union" } + void foo() { i; } +}; diff --git a/gcc/testsuite/g++.dg/ext/anon-struct6.C b/gcc/testsuite/g++.dg/ext/anon-struct6.C new file mode 100644 index 000000000..11a7bbd60 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/anon-struct6.C @@ -0,0 +1,10 @@ +// PR c++/33460 + +struct A +{ + struct + { // { dg-error "anonymous struct cannot have function members" } + struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members" } + void foo() { i; } + }; // { dg-error "prohibits anonymous structs" } +}; diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-1.C new file mode 100644 index 000000000..0c601e68c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-1.C @@ -0,0 +1,5 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do run { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=ieee" } */ + +#include "arm-fp16-ops.h" diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-2.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-2.C new file mode 100644 index 000000000..244e31082 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-2.C @@ -0,0 +1,5 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do run { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=ieee -ffast-math" } */ + +#include "arm-fp16-ops.h" diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-3.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-3.C new file mode 100644 index 000000000..8f9ab64bc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-3.C @@ -0,0 +1,5 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do run { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=alternative" } */ + +#include "arm-fp16-ops.h" diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-4.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-4.C new file mode 100644 index 000000000..4877f392c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-4.C @@ -0,0 +1,5 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do run { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=alternative -ffast-math" } */ + +#include "arm-fp16-ops.h" diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-5.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-5.C new file mode 100644 index 000000000..92bc8a9c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-5.C @@ -0,0 +1,15 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-require-effective-target arm_fp16_ok } */ +/* { dg-options "-mfp16-format=ieee" } */ +/* { dg-add-options arm_fp16 } */ + +#include "arm-fp16-ops.h" + +/* We've specified options for hardware float, including fp16 support, so + we should not see any calls to libfuncs here. */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_h2f_ieee" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_f2h_ieee" } } */ diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-6.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-6.C new file mode 100644 index 000000000..ae40b1e86 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-6.C @@ -0,0 +1,15 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-require-effective-target arm_fp16_ok } */ +/* { dg-options "-mfp16-format=ieee -ffast-math" } */ +/* { dg-add-options arm_fp16 } */ + +#include "arm-fp16-ops.h" + +/* We've specified options for hardware float, including fp16 support, so + we should not see any calls to libfuncs here. */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_h2f_ieee" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_f2h_ieee" } } */ diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-7.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-7.C new file mode 100644 index 000000000..ed8089bd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-7.C @@ -0,0 +1,13 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-mfp16-format=ieee" } */ +/* { dg-add-options arm_neon } */ + +#include "arm-fp16-ops.h" + +/* We've specified options for hardware float, so we should not see any + calls to libfuncs here except for those to the conversion functions. */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */ diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-8.C b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-8.C new file mode 100644 index 000000000..b138ca187 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops-8.C @@ -0,0 +1,13 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-mfp16-format=ieee -ffast-math" } */ +/* { dg-add-options arm_neon } */ + +#include "arm-fp16-ops.h" + +/* We've specified options for hardware float, so we should not see any + calls to libfuncs here except for those to the conversion functions. */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf2" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__.*hf3" } } */ +/* { dg-final { scan-assembler-not "\tbl\t__gnu_h\[a-z\]*_ieee" } } */ diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops.h b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops.h new file mode 100644 index 000000000..320494ee7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/arm-fp16-ops.h @@ -0,0 +1,135 @@ +/* Test various operators on __fp16 and mixed __fp16/float operands. */ + +#include <assert.h> + +#define CHECK(e,r) assert ((e) == r) +#define CHECK2(e,r) (assert ((e) == r), temp = (e), assert (temp == r)) +#define TEST(e) assert (e) +#define TESTNOT(e) assert (!(e)) + +volatile __fp16 h0 = 0.0; +volatile __fp16 h1 = 1.0; +volatile __fp16 h42 = 42.0; +volatile __fp16 hm2 = -2.0; +volatile __fp16 temp; + +volatile float f0 = 0.0; +volatile float f1 = 1.0; +volatile float f42 = 42.0; +volatile float fm2 = -2.0; + +int main (void) +{ + TEST (h1); + TESTNOT (h0); + TEST (!h0); + TESTNOT (!h1); + + CHECK2 (-h1, -1.0); + CHECK2 (+h1, 1.0); + + CHECK (h1++, 1.0); + CHECK (h1, 2.0); + CHECK (++h1, 3.0); + CHECK (h1, 3.0); + + CHECK (--h1, 2.0); + CHECK (h1, 2.0); + CHECK (h1--, 2.0); + CHECK (h1, 1.0); + + CHECK2 (h42 * hm2, -84.0); + CHECK2 (h42 * (__fp16) -2.0, -84.0); + CHECK2 (h42 * fm2, -84.0); + CHECK2 (f42 * hm2, -84.0); + + CHECK2 (h42 / hm2, -21.0); + CHECK2 (h42 / (__fp16) -2.0, -21.0); + CHECK2 (h42 / fm2, -21.0); + CHECK2 (f42 / hm2, -21.0); + + CHECK2 (hm2 + h42, 40.0); + CHECK2 ((__fp16)-2.0 + h42, 40.0); + CHECK2 (hm2 + f42, 40.0); + CHECK2 (fm2 + h42, 40.0); + + CHECK2 (hm2 - h42, -44.0); + CHECK2 ((__fp16)-2.0 - h42, -44.0); + CHECK2 (hm2 - f42, -44.0); + CHECK2 (fm2 - h42, -44.0); + + TEST (hm2 < h42); + TEST (hm2 < (__fp16)42.0); + TEST (hm2 < f42); + TEST (fm2 < h42); + + TEST (h42 > hm2); + TEST ((__fp16)42.0 > hm2); + TEST (h42 > fm2); + TEST (f42 > hm2); + + TEST (hm2 <= h42); + TEST (hm2 <= (__fp16)42.0); + TEST (hm2 <= f42); + TEST (fm2 <= h42); + + TEST (h42 >= hm2); + TEST (h42 >= (__fp16)-2.0); + TEST (h42 >= fm2); + TEST (f42 >= hm2); + + TESTNOT (h1 == hm2); + TEST (h1 == h1); + TEST (h1 == (__fp16)1.0); + TEST (h1 == f1); + TEST (f1 == h1); + + TEST (h1 != hm2); + TESTNOT (h1 != h1); + TESTNOT (h1 != (__fp16)1.0); + TESTNOT (h1 != f1); + TESTNOT (f1 != h1); + + CHECK2 ((h1 ? hm2 : h42), -2.0); + CHECK2 ((h0 ? hm2 : h42), 42.0); + + CHECK (h0 = h42, 42.0); + CHECK (h0, 42.0); + CHECK (h0 = (__fp16)-2.0, -2.0); + CHECK (h0, -2.0); + CHECK (h0 = f0, 0.0); + CHECK (h0, 0.0); + + CHECK (h0 += h1, 1.0); + CHECK (h0, 1.0); + CHECK (h0 += (__fp16)1.0, 2.0); + CHECK (h0, 2.0); + CHECK (h0 += fm2, 0.0); + CHECK (h0, 0.0); + + CHECK (h0 -= h1, -1.0); + CHECK (h0, -1.0); + CHECK (h0 -= (__fp16)1.0, -2.0); + CHECK (h0, -2.0); + CHECK (h0 -= fm2, 0.0); + CHECK (h0, 0.0); + + h0 = hm2; + CHECK (h0 *= hm2, 4.0); + CHECK (h0, 4.0); + CHECK (h0 *= (__fp16)-2.0, -8.0); + CHECK (h0, -8.0); + CHECK (h0 *= fm2, 16.0); + CHECK (h0, 16.0); + + CHECK (h0 /= hm2, -8.0); + CHECK (h0, -8.0); + CHECK (h0 /= (__fp16)-2.0, 4.0); + CHECK (h0, 4.0); + CHECK (h0 /= fm2, -2.0); + CHECK (h0, -2.0); + + CHECK ((h0, h1), 1.0); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-mangle-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-mangle-1.C new file mode 100644 index 000000000..25a872af6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-mangle-1.C @@ -0,0 +1,14 @@ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=ieee" } */ + +/* Test mangling */ + +/* { dg-final { scan-assembler "\t.global\t_Z1fPDh" } } */ +void f (__fp16 *x) { } + +/* { dg-final { scan-assembler "\t.global\t_Z1gPDhS_" } } */ +void g (__fp16 *x, __fp16 *y) { } + +/* { dg-final { scan-assembler "\t.global\t_ZN1SIDhDhE1iE" } } */ +template <typename T, typename U> struct S { static int i; }; +template <> int S<__fp16, __fp16>::i = 3; diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-overload-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-overload-1.C new file mode 100644 index 000000000..bf0139d7c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-overload-1.C @@ -0,0 +1,16 @@ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=ieee" } */ + +/* __fp16 values are autoconverted to float and should therefore be treated + * just like float for overloading purposes. */ + +extern int frobnify (float x); +extern int frobnify (double x); + +int g (void) +{ + return frobnify ((__fp16)1.0); +} + +/* { dg-final { scan-assembler "_Z8frobnifyf" } } */ +/* { dg-final { scan-assembler-not " _Z8frobnifyd" } } */ diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C new file mode 100644 index 000000000..03feb1a4d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C @@ -0,0 +1,10 @@ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=ieee" } */ + +/* Functions cannot have parameters of type __fp16. */ +extern void f (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */ +extern void (*pf) (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */ + +/* These should be OK. */ +extern void g (__fp16 *); +extern void (*pg) (__fp16 *); diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C new file mode 100644 index 000000000..406dfacd3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C @@ -0,0 +1,10 @@ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-options "-mfp16-format=ieee" } */ + +/* Functions cannot return type __fp16. */ +extern __fp16 f (void); /* { dg-error "cannot return __fp16" } */ +extern __fp16 (*pf) (void); /* { dg-error "cannot return __fp16" } */ + +/* These should be OK. */ +extern __fp16 *g (void); +extern __fp16 *(*pg) (void); diff --git a/gcc/testsuite/g++.dg/ext/array1.C b/gcc/testsuite/g++.dg/ext/array1.C new file mode 100644 index 000000000..7e54dc919 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/array1.C @@ -0,0 +1,14 @@ +// PR c++/13574 +// { dg-options "" } + +class A { +public: + A() : argc(0), argv() { }; +private: + int argc; + char* argv[]; +}; + +int main() { + A y; +} diff --git a/gcc/testsuite/g++.dg/ext/array2.C b/gcc/testsuite/g++.dg/ext/array2.C new file mode 100644 index 000000000..2d645ca94 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/array2.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Avoid -pedantic-error default +// { dg-options "" } + +// PR 19989 - dependent array of size 0 fails to compile. + +template<int I> struct A +{ + static const int zero = 0; +}; + +template<int N> struct B +{ + int x[A<N>::zero]; +}; + +B<0> b; diff --git a/gcc/testsuite/g++.dg/ext/asm1.C b/gcc/testsuite/g++.dg/ext/asm1.C new file mode 100644 index 000000000..dd4aede24 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm1.C @@ -0,0 +1,56 @@ +// Check that the 3.1 named operand syntax can be used in template functions. + +struct arg1 { + int value; + static const int info = 99; +}; + +struct arg2 { + int value; + static const int info = 11; +}; + +template<int j> +int foo (void) +{ + int i; + asm ("# foo on %[third] %[second] %[fourth] %[first]" + : [first] "=r" (i) + : [second] "i" (j), + [third] "i" (j + 2), + [fourth] "i" (100)); + return i; +} + +template<class TYPE> +TYPE bar (TYPE t) +{ + asm ("# bar on %[first] %[second] %[third]" + : [first] "=r" (t.value) + : [second] "i[first]" (t.value), + [third] "i" (t.info)); + return t; +} + +template<class TYPE> +struct S { + static void frob (TYPE t) + { + asm ("# frob on %[arg]" :: [arg] "i" (t.info)); + } +}; + +void test () +{ + arg1 x; + arg2 y; + + foo<42> (); + bar (x); + bar (y); + S<arg1>::frob (x); +} + +// { dg-final { scan-assembler "foo on" } } +// { dg-final { scan-assembler "bar on" } } +// { dg-final { scan-assembler "frob on" } } diff --git a/gcc/testsuite/g++.dg/ext/asm10.C b/gcc/testsuite/g++.dg/ext/asm10.C new file mode 100644 index 000000000..b95027c8c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm10.C @@ -0,0 +1,14 @@ +// PR inline-asm/32109 +// { dg-do compile } +// { dg-options "-O2" } + +struct A { int i[3]; ~A (); }; +struct A a; +struct B { struct A c; int i; B (); } b; + +B::B () +{ + __asm ("" : : "r" (a)); // { dg-error "impossible constraint|non-memory input" } + __asm ("" : : "r" (b.c)); // { dg-error "impossible constraint|non-memory input" } + __asm ("" : : "r" (c)); // { dg-error "impossible constraint|non-memory input" } +} diff --git a/gcc/testsuite/g++.dg/ext/asm11.C b/gcc/testsuite/g++.dg/ext/asm11.C new file mode 100644 index 000000000..7939aacc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm11.C @@ -0,0 +1,20 @@ +// PR c/37772 +// { dg-do compile } +// { dg-options "" } + +void +foo () +{ + int i; + asm (); // { dg-error "expected string-literal before" } + asm (1); // { dg-error "expected string-literal before" } + asm (int); // { dg-error "expected string-literal before" } + asm (: "=r" (i)); // { dg-error "expected string-literal before" } + asm (1 : "=r" (i)); // { dg-error "expected string-literal before" } + asm (int : "=r" (i)); // { dg-error "expected string-literal before" } + asm (: : "r" (i)); // { dg-error "expected string-literal before" } + asm (1 : : "r" (i)); // { dg-error "expected string-literal before" } + asm (int : : "r" (i)); // { dg-error "expected string-literal before" } + asm (: : : "memory"); // { dg-error "expected string-literal before" } + asm (1 : : : "memory"); // { dg-error "expected string-literal before" } +} diff --git a/gcc/testsuite/g++.dg/ext/asm2.C b/gcc/testsuite/g++.dg/ext/asm2.C new file mode 100644 index 000000000..6cec382c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm2.C @@ -0,0 +1,12 @@ +// Bug: in a template, we forgot that this was a simple asm, and decided +// that %edi was a malformed operand specifier. + +template <class T> class I { +public: + void f() { asm ("# mov %edi, %esi" ); } +}; + +int main () { + I<int> x; + x.f(); +} diff --git a/gcc/testsuite/g++.dg/ext/asm3.C b/gcc/testsuite/g++.dg/ext/asm3.C new file mode 100644 index 000000000..090218fe6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm3.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 16 Sep 2002 <nathan@codesourcery.com> + +// PR 7015. ICE with asms + +int two(int in) +{ + register int out; + __asm__ ("" : "r" (out) : "r" (in)); + return out; +} + +// { dg-message "error:" "" { target *-*-* } 11 } diff --git a/gcc/testsuite/g++.dg/ext/asm4.C b/gcc/testsuite/g++.dg/ext/asm4.C new file mode 100644 index 000000000..2726d8e42 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm4.C @@ -0,0 +1,4 @@ +void f () +{ + __asm__ __volatile__ ("" : : ); +} diff --git a/gcc/testsuite/g++.dg/ext/asm5.C b/gcc/testsuite/g++.dg/ext/asm5.C new file mode 100644 index 000000000..9395395ed --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm5.C @@ -0,0 +1,35 @@ +void f (int i) +{ + __asm__("" : ); + __asm__("" : "+g" (i)); + + __asm__("" :: ); + __asm__("" :: "g" (i)); + + __asm__("" : : ); + __asm__("" : "+g" (i) : ); + __asm__("" : : "g" (i)); + __asm__("" : "+g" (i) : "g" (i)); + + __asm__("" ::: ); + __asm__("" ::: "memory"); + + __asm__("" : :: ); + __asm__("" : "+g" (i) :: ); + __asm__("" : :: "memory"); + __asm__("" : "+g" (i) :: "memory"); + + __asm__("" :: : ); + __asm__("" :: "g" (i) : ); + __asm__("" :: : "memory"); + __asm__("" :: "g" (i) : "memory"); + + __asm__("" : : : ); + __asm__("" : "+g" (i) : : ); + __asm__("" : : "g" (i) : ); + __asm__("" : : : "memory"); + __asm__("" : "+g" (i) : "g" (i) : ); + __asm__("" : "+g" (i) : : "memory"); + __asm__("" : : "g" (i) : "memory"); + __asm__("" : "+g" (i) : "g" (i) : "memory"); +} diff --git a/gcc/testsuite/g++.dg/ext/asm6.C b/gcc/testsuite/g++.dg/ext/asm6.C new file mode 100644 index 000000000..96ef9d385 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm6.C @@ -0,0 +1,11 @@ +struct A +{ + ~A(); +}; +int foo(A); +void bar() +{ + A a; + asm("" : : "r"(foo(a)) );//<-- cleanup needed here. +} + diff --git a/gcc/testsuite/g++.dg/ext/asm7.C b/gcc/testsuite/g++.dg/ext/asm7.C new file mode 100644 index 000000000..a5cad0073 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm7.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +const int i = 0; + +void f(void) +{ + __asm__ __volatile__ ("" : "=m" (i)); /* { dg-error "read-only variable" } */ +} + +void g(const int set) +{ + __asm__ __volatile__ ("" : "=r" (set)); /* { dg-error "read-only parameter" } */ +} + + diff --git a/gcc/testsuite/g++.dg/ext/asm8.C b/gcc/testsuite/g++.dg/ext/asm8.C new file mode 100644 index 000000000..0b1be7da7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm8.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +/* Test that asm with no outputs are treated as volatile. */ + +void f(int x) +{ + __asm__ ("extended asm not discarded" : : "r" (x)); +} + +void g (void) +{ + __asm__ ("simple asm not discarded"); +} +/* { dg-final { scan-assembler "extended asm not discarded" } } */ +/* { dg-final { scan-assembler "simple asm not discarded" } } */ + diff --git a/gcc/testsuite/g++.dg/ext/asm9.C b/gcc/testsuite/g++.dg/ext/asm9.C new file mode 100644 index 000000000..9daa01bbf --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asm9.C @@ -0,0 +1,7 @@ +// PR 27451 +// { dg-do compile } + +void foo() +{ + asm("" ::: X); // { dg-error "before" } +} diff --git a/gcc/testsuite/g++.dg/ext/asmgoto1.C b/gcc/testsuite/g++.dg/ext/asmgoto1.C new file mode 100644 index 000000000..dda516797 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asmgoto1.C @@ -0,0 +1,32 @@ +// PR middle-end/44102 +// { dg-do compile } +// { dg-options "-O2" } + +void baz (void); +struct A { A (); ~A (); }; + +static inline int +foo (void) +{ + asm goto ("" : : : : l1, l2); + __builtin_unreachable (); + l1: + return 1; + l2: + return 0; +} + +int +bar (int x) +{ + if (x == 5) + { + A a, b; + baz (); + } + if (foo () || x == 6) + x = 1; + else + x = 2; + return x; +} diff --git a/gcc/testsuite/g++.dg/ext/asmspec1.C b/gcc/testsuite/g++.dg/ext/asmspec1.C new file mode 100644 index 000000000..0661136fe --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asmspec1.C @@ -0,0 +1,8 @@ +// PR c++/28343 +// { dg-do compile } + +struct A +{ + int i __asm__(int); // { dg-error "expected" } + static int j __asm__(int); // { dg-error "expected" } +}; diff --git a/gcc/testsuite/g++.dg/ext/asmspecInvalid.C b/gcc/testsuite/g++.dg/ext/asmspecInvalid.C new file mode 100644 index 000000000..4c528a0f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asmspecInvalid.C @@ -0,0 +1,18 @@ +// tests that the asm directive is correctly handled for static fields +// in structures and classes. This only applies to C++; such +// directives generate errors in C. Assembler directives for local +// variables should be tested by the C test suite. +// +// Contributed by Robert Bowdidge (bowdidge@apple.com) 14 Oct 2003 + +// { dg-do compile } + +struct Foo { + // This should reference a variable called bar + int i __asm__("bar"); /* { dg-error "specifiers are not permitted" } */ +}; + +int main (void ) { + int j = 0; + return j; +} diff --git a/gcc/testsuite/g++.dg/ext/asmspecValid.C b/gcc/testsuite/g++.dg/ext/asmspecValid.C new file mode 100644 index 000000000..98d98b46f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/asmspecValid.C @@ -0,0 +1,43 @@ +// tests that the asm directive is correctly handled for static fields +// in structures and classes. This only applies to C++; such +// directives generate errors in C. Assembler directives for local +// variables should be tested by the C test suite. +// +// Contributed by Robert Bowdidge (bowdidge@apple.com) 14 Oct 2003 + +// { dg-do compile } + +struct Foo { + // This should reference a variable called bar + static int i __asm__("bar"); +}; + + +class Bar { +public: + static int i __asm__("theRealI"); + static int j __asm__("theRealJ"); + int boof; +}; + +class Baz : public Bar { +public: + static char *ptr __asm__ ("theRealString"); +}; + +int main (int argc, char **argv) { + struct Foo myFoo; + Bar b; + myFoo.i = 1; + Foo::i = 2; + Baz::j = 10; + Baz::ptr = 0; + b.i = 1; + return (b.i); +} + + +/* { dg-final {scan-assembler "bar"} } */ +/* { dg-final {scan-assembler "theRealString"} } */ +/* { dg-final {scan-assembler "theRealI" } } */ +/* { dg-final {scan-assembler "theRealJ" } } */ diff --git a/gcc/testsuite/g++.dg/ext/attr-alias-1.C b/gcc/testsuite/g++.dg/ext/attr-alias-1.C new file mode 100644 index 000000000..1427267e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-alias-1.C @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-require-alias "" } */ + +#include <typeinfo> + +struct Klass +{ + int implementation () const; + int magic () const; +}; + +int Klass::implementation (void) const +{ + return 0; +} + +int Klass::magic () const + __attribute__ ((alias ("_ZNK5Klass14implementationEv"))); + +int __attribute__ ((noinline)) + Foo (Klass const *ptr) +{ + if (ptr->magic () != 0) + return 1; + + if (typeid (*ptr) != typeid (Klass)) + return 2; + + return 0; +} + +int main () +{ + Klass obj; + + return Foo (&obj); +} diff --git a/gcc/testsuite/g++.dg/ext/attr-alias-2.C b/gcc/testsuite/g++.dg/ext/attr-alias-2.C new file mode 100644 index 000000000..61a132f77 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-alias-2.C @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-require-alias "" } */ + +#include <typeinfo> + +struct Klass +{ + int implementation () const; + virtual int magic () const; +}; + +int Klass::implementation (void) const +{ + return 0; +} + +int Klass::magic () const + __attribute__ ((alias ("_ZNK5Klass14implementationEv"))); + +int __attribute__ ((noinline)) + Foo (Klass const *ptr) +{ + if (ptr->magic () != 0) + return 1; + + if (typeid (*ptr) != typeid (Klass)) + return 2; + + return 0; +} + +int main () +{ + Klass obj; + + return Foo (&obj); +} diff --git a/gcc/testsuite/g++.dg/ext/attr-ifunc-1.C b/gcc/testsuite/g++.dg/ext/attr-ifunc-1.C new file mode 100644 index 000000000..d41fa7d32 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-ifunc-1.C @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-Wno-pmf-conversions" } */ + +#include <stdio.h> + +struct Klass +{ + int implementation (); + int magic (); + static void *resolver (); +}; + +int Klass::implementation (void) +{ + printf ("'ere I am JH\n"); + return 0; +} + +void *Klass::resolver (void) +{ + int (Klass::*pmf) () = &Klass::implementation; + + return (void *)(int (*)(Klass *))(((Klass *)0)->*pmf); +} + +int Klass::magic (void) __attribute__ ((ifunc ("_ZN5Klass8resolverEv"))); + +int main () +{ + Klass obj; + + return obj.magic () != 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attr-ifunc-2.C b/gcc/testsuite/g++.dg/ext/attr-ifunc-2.C new file mode 100644 index 000000000..e205a2a6a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-ifunc-2.C @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-Wno-pmf-conversions" } */ + +#include <stdio.h> + +struct Klass +{ + int implementation (); + int magic (); + static void *resolver (); +}; + +int Klass::implementation (void) +{ + printf ("'ere I am JH\n"); + return 0; +} + +void *Klass::resolver (void) +{ + int (Klass::*pmf) () = &Klass::implementation; + + return (void *)(int (*)(Klass *))(((Klass *)0)->*pmf); +} + +int Klass::magic (void) __attribute__ ((ifunc ("_ZN5Klass8resolverEv"))); + +struct Klassier : Klass +{ +}; + +int main () +{ + Klassier obj; + + return obj.magic () != 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attr-ifunc-3.C b/gcc/testsuite/g++.dg/ext/attr-ifunc-3.C new file mode 100644 index 000000000..ba65976b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-ifunc-3.C @@ -0,0 +1,39 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-Wno-pmf-conversions" } */ + +#include <stdio.h> + +struct Klass +{ + int implementation (); + int magic (); + static void *resolver (); +}; + +int Klass::implementation (void) +{ + printf ("'ere I am JH\n"); + return 0; +} + +void *Klass::resolver (void) +{ + int (Klass::*pmf) () = &Klass::implementation; + + return (void *)(int (*)(Klass *))(((Klass *)0)->*pmf); +} + +int Klass::magic (void) __attribute__ ((ifunc ("_ZN5Klass8resolverEv"))); + +int Foo (Klass &obj, int (Klass::*pmf) ()) +{ + return (obj.*pmf) (); +} + +int main () +{ + Klass obj; + + return Foo (obj, &Klass::magic) != 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attr-ifunc-4.C b/gcc/testsuite/g++.dg/ext/attr-ifunc-4.C new file mode 100644 index 000000000..0cae41028 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-ifunc-4.C @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-Wno-pmf-conversions" } */ + +#include <stdio.h> + +struct Klass +{ + virtual int magic () = 0; +}; + +struct Klassier : Klass +{ + int implementation (); + int magic (); + static void *resolver (); +}; + +int Klassier::implementation (void) +{ + printf ("'ere I am JH\n"); + return 0; +} + +void *Klassier::resolver (void) +{ + int (Klassier::*pmf) () = &Klassier::implementation; + + return (void *)(int (*)(Klassier *))(((Klassier *)0)->*pmf); +} + +int Klassier::magic (void) __attribute__ ((ifunc ("_ZN8Klassier8resolverEv"))); + +int __attribute__ ((weak)) Foo (Klass &base) +{ + return base.magic (); +} + +int main () +{ + Klassier obj; + + return Foo (obj) != 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attrib1.C b/gcc/testsuite/g++.dg/ext/attrib1.C new file mode 100644 index 000000000..2bd69e82a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib1.C @@ -0,0 +1,10 @@ +// Test for interpretation of attribute immediately before function name. +// Origin: Joseph Myers <jsm28@cam.ac.uk> +// { dg-do compile } + +// An attribute immediately before the function name should in this +// case properly apply to the return type, but compatibility with +// existing code using this form requires it to apply to the function +// type instead in the case of attributes applying to function types, +// and to the declaration in the case of attributes applying to declarations. +int ****__attribute__((format(printf, 1, 2))) foo(const char *, ...); diff --git a/gcc/testsuite/g++.dg/ext/attrib10.C b/gcc/testsuite/g++.dg/ext/attrib10.C new file mode 100644 index 000000000..42d967dde --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib10.C @@ -0,0 +1,8 @@ +// PR c++/12795 +// { dg-require-alias "" } + +void foo() +{ + extern void bar () __attribute__ ((__alias__ ("BAR"))); // { dg-warning "ignored" } + bar (); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib11.C b/gcc/testsuite/g++.dg/ext/attrib11.C new file mode 100644 index 000000000..26bc7907c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib11.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-options "-Wall" } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 30 Dec 2003 <nathan@codesourcery.com> + + +// PR c++/13507, spurious warning due to attribute clobbering +extern "C" { + extern int printf (__const char *__restrict __format, ...) throw (); + extern int scanf (__const char *__restrict __format, ...) throw (); +} + +void foo(unsigned int x) +{ + printf ("%d\n", x); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib12.C b/gcc/testsuite/g++.dg/ext/attrib12.C new file mode 100644 index 000000000..aea93781d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib12.C @@ -0,0 +1,16 @@ +// PR c++/13791 + +template <typename T> struct O { + struct __attribute__((packed)) I { + int i; + char c; + }; + + I* foo(); +}; + +template <typename T> +typename O<T>::I* +O<T>::foo() { return 0; } + +template class O<int>; diff --git a/gcc/testsuite/g++.dg/ext/attrib13.C b/gcc/testsuite/g++.dg/ext/attrib13.C new file mode 100644 index 000000000..22ea97ae7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib13.C @@ -0,0 +1,4 @@ +// PR c++/13854 + +extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__)); +extern char *rindex (__const char *__s, int __c) throw () __attribute__ ((__pure__)); diff --git a/gcc/testsuite/g++.dg/ext/attrib14.C b/gcc/testsuite/g++.dg/ext/attrib14.C new file mode 100644 index 000000000..c7e5f7a9f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib14.C @@ -0,0 +1,13 @@ +// PR c++/13170 +// The bogus attribute is ignored, but was in TYPE_ATTRIBUTES during +// parsing of the class, causing some variants to have it and some not. + +struct __attribute__((bogus)) A +{ // { dg-warning "ignored" "" } + virtual ~A(); + void foo(const A&); + void bar(const A&); +}; + +void A::foo(const A&) {} +void A::bar(const A& a) { foo(a); } diff --git a/gcc/testsuite/g++.dg/ext/attrib15.C b/gcc/testsuite/g++.dg/ext/attrib15.C new file mode 100644 index 000000000..05de12cce --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib15.C @@ -0,0 +1,9 @@ +// PR c++/15317 + +struct A +{ + A(char); +}; +A::A(__attribute__((unused)) char i2) +{} + diff --git a/gcc/testsuite/g++.dg/ext/attrib16.C b/gcc/testsuite/g++.dg/ext/attrib16.C new file mode 100644 index 000000000..2e73fca70 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib16.C @@ -0,0 +1,8 @@ +// { dg-do compile } +// Origin: <rguenth at tat dot physik dot uni-tuebingen dot de> +// PR c++/10479: use of non dependent expressions in attributes in templates + +template <int i> +struct foo2 { + float bar __attribute__((aligned(__alignof__(double)))); +}; diff --git a/gcc/testsuite/g++.dg/ext/attrib17.C b/gcc/testsuite/g++.dg/ext/attrib17.C new file mode 100644 index 000000000..43cf264f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib17.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// Origin: Benjamin Kosnik <bkoz at gcc dot gnu dot org> +// PR c++/17743: Attributes applied to typedefs. + +struct A { + typedef char layout_type[sizeof(double)] + __attribute__((aligned(__alignof__(double)))); + layout_type data; +}; + +struct B { + typedef char layout_type[sizeof(double)]; + layout_type data __attribute__((aligned(__alignof__(double)))); +}; + +template<bool> struct StaticAssert; +template<> struct StaticAssert<true> {}; + +StaticAssert<__alignof__(A) == __alignof__(B)> a1; diff --git a/gcc/testsuite/g++.dg/ext/attrib18.C b/gcc/testsuite/g++.dg/ext/attrib18.C new file mode 100644 index 000000000..ab9fea095 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib18.C @@ -0,0 +1,10 @@ +// PR c++/17542 +// Test that we warn when an attribute preceding the class-key is ignored. +// { dg-do compile } + +__attribute__ ((packed)) struct A // { dg-warning "attribute" } +{ + char c; + int x; + void f(); +}; diff --git a/gcc/testsuite/g++.dg/ext/attrib19.C b/gcc/testsuite/g++.dg/ext/attrib19.C new file mode 100644 index 000000000..f1362c3b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib19.C @@ -0,0 +1,10 @@ +// PR c++/19739 + +void Dummy() __attribute__(( , )); +void Dummy() {} + +int main (int argc, char **argv) +{ + Dummy(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attrib2.C b/gcc/testsuite/g++.dg/ext/attrib2.C new file mode 100644 index 000000000..a7563f388 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib2.C @@ -0,0 +1,12 @@ +// Test that an early attribute doesn't confuse uses of a class. +// { dg-do compile } + +struct __attribute__ ((packed)) A +{ + void f () const; +}; + +void +A::f () const +{ +} diff --git a/gcc/testsuite/g++.dg/ext/attrib20.C b/gcc/testsuite/g++.dg/ext/attrib20.C new file mode 100644 index 000000000..25b27f307 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib20.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-g" } +// Origin: <jan at etpmod dot phys dot tue dot nl> +// PR c++/19508: avoid attributes for template parameters + +template <typename T> +struct BVector +{ + typedef T T2; + typedef T value_type __attribute__ ((aligned(8))); // { dg-bogus "attribute" "attribute" } + typedef T2 value_type2 __attribute__ ((aligned(8))); // { dg-bogus "attribute" "attribute" } + value_type v; +}; +BVector<int> m; + +template <template <class> class T> +struct BV2 +{ + typedef T<float> value_type __attribute__((aligned(8))); // { dg-bogus "attribute" "attribute" } + value_type v; +}; +BV2<BVector> m2; + diff --git a/gcc/testsuite/g++.dg/ext/attrib21.C b/gcc/testsuite/g++.dg/ext/attrib21.C new file mode 100644 index 000000000..2fc5800b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib21.C @@ -0,0 +1,17 @@ +// PR c++/20763 + +typedef void *voidp; + +struct S +{ + char a; + voidp __attribute__ ((aligned (16))) b; +}; + +struct T +{ + char a; + void *__attribute__ ((aligned (16))) b; +}; + +int f[sizeof (struct S) != sizeof (struct T) ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/ext/attrib22.C b/gcc/testsuite/g++.dg/ext/attrib22.C new file mode 100644 index 000000000..5304a35d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib22.C @@ -0,0 +1,6 @@ +// PR c++/27648 + +void f() +{ + static_cast<float *__attribute((unused))>(0); // { dg-error "expected" } +} diff --git a/gcc/testsuite/g++.dg/ext/attrib23.C b/gcc/testsuite/g++.dg/ext/attrib23.C new file mode 100644 index 000000000..0a2c58689 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib23.C @@ -0,0 +1,11 @@ +// PR c++/28112 +// { dg-do compile } + +int i __attribute__((init_priority(;))); // { dg-error "before" } +int j __attribute__((vector_size(;))); // { dg-error "before" } +int k __attribute__((visibility(;))); // { dg-error "before" } +struct A {} __attribute__((aligned(;))); // { dg-error "before" } +struct B {} __attribute__((mode(;))); // { dg-error "before" } +void foo() __attribute__((alias(;))); // { dg-error "before" } +void bar() __attribute__((nonnull(;))); // { dg-error "before" } +void baz() __attribute__((section(;))); // { dg-error "before" } diff --git a/gcc/testsuite/g++.dg/ext/attrib24.C b/gcc/testsuite/g++.dg/ext/attrib24.C new file mode 100644 index 000000000..208809a3f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib24.C @@ -0,0 +1,4 @@ +// PR c++/28387 +// { dg-do compile } + +enum __attribute__((unused)) E; // { dg-error "without previous declaration" } diff --git a/gcc/testsuite/g++.dg/ext/attrib25.C b/gcc/testsuite/g++.dg/ext/attrib25.C new file mode 100644 index 000000000..aeffdffe3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib25.C @@ -0,0 +1,11 @@ +// PR c++/28559 + +template<typename T> struct A +{ + struct B; +}; + +struct C +{ + template<typename T> friend struct __attribute__((packed)) A<T>::B; // { dg-warning "uninstantiated" } +}; diff --git a/gcc/testsuite/g++.dg/ext/attrib26.C b/gcc/testsuite/g++.dg/ext/attrib26.C new file mode 100644 index 000000000..dedf43a02 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib26.C @@ -0,0 +1,14 @@ +// PR c++/28659 +// The attribute was causing us to get confused in merge_types when +// combining the template type with an uninstantiated version. + +template<class T> +struct __attribute__((aligned(1))) A +{ + A& operator=(const A &t); +}; + +template<class T> +A<T>& A<T>::operator=(const A<T> &t) +{ +} diff --git a/gcc/testsuite/g++.dg/ext/attrib27.C b/gcc/testsuite/g++.dg/ext/attrib27.C new file mode 100644 index 000000000..4f629aa53 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib27.C @@ -0,0 +1,5 @@ +//PR c++/29980 + +struct A { typedef int X; }; // { dg-error "previous declaration" } + +struct __attribute__((unused)) A::X; // { dg-error "typedef-name" } diff --git a/gcc/testsuite/g++.dg/ext/attrib28.C b/gcc/testsuite/g++.dg/ext/attrib28.C new file mode 100644 index 000000000..2f18d4184 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib28.C @@ -0,0 +1,12 @@ +// PR c++/28558 +// { dg-options "" } + +struct A +{ + A(int) { } +}; + +int main() +{ + A a = (A __attribute__((unused)))0; // { dg-warning "attribute" } +} diff --git a/gcc/testsuite/g++.dg/ext/attrib29.C b/gcc/testsuite/g++.dg/ext/attrib29.C new file mode 100644 index 000000000..710a5ce27 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib29.C @@ -0,0 +1,10 @@ +// PR c++/33506 +// { dg-do compile } + +extern int f1 (char *) __attribute__ ((warn_unused_result)); +extern int f2 (char *) throw () __attribute__ ((warn_unused_result)); +extern int f2 (char *) throw (); + +extern int f3 (char *) __attribute__ ((nonnull (1))); +extern int f4 (char *) throw () __attribute__ ((nonnull (1))); +extern int f4 (char *) throw (); diff --git a/gcc/testsuite/g++.dg/ext/attrib3.C b/gcc/testsuite/g++.dg/ext/attrib3.C new file mode 100644 index 000000000..17a904c09 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib3.C @@ -0,0 +1,21 @@ +// Test that attributes work in a variety of situations. +// { dg-options -O } +// { dg-do run } + +#define attrib __attribute ((mode (QI))) + +attrib signed int a; // attributes before type are broken +static attrib unsigned int b; + +int foo(attrib int o) // attribute arguments are broken +{ + return (sizeof (a) != 1 + || sizeof (b) != 1 + || sizeof (o) != 1 + || sizeof ((attrib signed int) b) != 1); +} + +int main () +{ + return foo (42); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib30.C b/gcc/testsuite/g++.dg/ext/attrib30.C new file mode 100644 index 000000000..fd2826a60 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib30.C @@ -0,0 +1,8 @@ +// { dg-do compile } +// PR c++/35074 +template<typename T> struct A +{ + void foo() const; +} __attribute((aligned(4))); + +template<typename T> void A<T>::foo() const {} diff --git a/gcc/testsuite/g++.dg/ext/attrib31.C b/gcc/testsuite/g++.dg/ext/attrib31.C new file mode 100644 index 000000000..c614ed4f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib31.C @@ -0,0 +1,15 @@ +// PR c++/35097 + +template<int> struct A; + +template<> struct A<0> +{ + typedef int X __attribute((aligned(4))); +}; + +template<typename T> void foo(const A<0>::X&, T); + +void bar() +{ + foo(A<0>::X(), 0); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib32.C b/gcc/testsuite/g++.dg/ext/attrib32.C new file mode 100644 index 000000000..77f71ded8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib32.C @@ -0,0 +1,36 @@ +// PR c++/35315 + +typedef union { int i; } U __attribute__((transparent_union)); + +static void foo(U) {} +static void foo(int) {} + +void bar() +{ + foo(0); +} + +typedef union U1 { int i; } U2 __attribute__((transparent_union)); + +static void foo2(U1) {} +static void foo2(U2) {} + +void bar2(U1 u1, U2 u2) +{ + foo2(u1); + foo2(u2); +} + +// PR c++/36410 +struct A +{ + typedef union + { + int i; + } B __attribute__((transparent_union)); +}; + +void foo(A::B b) +{ + b.i; +} diff --git a/gcc/testsuite/g++.dg/ext/attrib33.C b/gcc/testsuite/g++.dg/ext/attrib33.C new file mode 100644 index 000000000..55bfc4cad --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib33.C @@ -0,0 +1,19 @@ +// PR c++/35546 +// { dg-do compile } +// { dg-options "-g" } + +template <int N> +struct T +{ + void foo (char const * ...) __attribute__ ((format (printf,2,3))); +}; + +template struct T<3>; + +template <typename T> +struct U +{ + typedef T __attribute__((mode (SI))) V; +}; + +U<int>::V v; diff --git a/gcc/testsuite/g++.dg/ext/attrib34.C b/gcc/testsuite/g++.dg/ext/attrib34.C new file mode 100644 index 000000000..f4794143d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib34.C @@ -0,0 +1,19 @@ +// PR c/37171 +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-optimized" } + +unsigned int f1 () __attribute__((const)); +unsigned int f2 () __attribute__((__const)); +unsigned int f3 () __attribute__((__const__)); + +unsigned int f4 () +{ + return f1 () + f1 () + f1 () + f1 () + + f2 () + f2 () + f2 () + f2 () + + f3 () + f3 () + f3 () + f3 (); +} + +// { dg-final { scan-tree-dump-times "= f1 \\(\\)" 1 "optimized" } } +// { dg-final { scan-tree-dump-times "= f2 \\(\\)" 1 "optimized" } } +// { dg-final { scan-tree-dump-times "= f3 \\(\\)" 1 "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/ext/attrib35.C b/gcc/testsuite/g++.dg/ext/attrib35.C new file mode 100644 index 000000000..e60a59dff --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib35.C @@ -0,0 +1,20 @@ +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-options "-O3 -msse2" } +// { dg-require-effective-target sse2 } + +// You can make NON-template typedefs with a large alignment. +typedef double AlignedDoubleType __attribute__((aligned(16))); + +template <typename RealType> +RealType f(const RealType* p) +{ + // But if you use a template parameter it complains. + typedef RealType AlignedRealType __attribute__((aligned(16))); + + return p[0]; +} + +double f2(const double* p) +{ + return f<double>(p); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib36.C b/gcc/testsuite/g++.dg/ext/attrib36.C new file mode 100644 index 000000000..5434cb9ef --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib36.C @@ -0,0 +1,20 @@ +// PR c++/43031 +// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } + +class T; +class L { }; +class P : public L +{ + typedef void (__attribute__((__stdcall__)) T::*F) (L*); + void f(bool aAdd); +}; +class T +{ +public: + virtual void __attribute__((__stdcall__)) A(L *listener) = 0; + virtual void __attribute__((__stdcall__)) R(L *listener) = 0; +}; +void P::f(bool aAdd) +{ + F addRemoveEventListener = (aAdd ? &T::A : &T::R); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib37.C b/gcc/testsuite/g++.dg/ext/attrib37.C new file mode 100644 index 000000000..d12c176af --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib37.C @@ -0,0 +1,14 @@ +// PR c++/43093 +// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } + +struct S { + int x; + S(const S &s) {} +}; + +S __attribute__((__stdcall__)) getS(); + +void test() +{ + S s = getS(); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib38.C b/gcc/testsuite/g++.dg/ext/attrib38.C new file mode 100644 index 000000000..be3c7f2ba --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib38.C @@ -0,0 +1,11 @@ +// PR c++/36625 + +template <int N> +struct A { + struct S { short f[3]; } __attribute__ ((aligned (N))); +}; + +int main () +{ + A<4>::S s; +} diff --git a/gcc/testsuite/g++.dg/ext/attrib39.C b/gcc/testsuite/g++.dg/ext/attrib39.C new file mode 100644 index 000000000..22a742942 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib39.C @@ -0,0 +1,9 @@ +// PR debug/43370 +// { dg-options "-g" } + +int fragile_block(void) { + typedef __attribute__ ((aligned (16))) struct { + int i; + } XmmUint16; + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/attrib4.C b/gcc/testsuite/g++.dg/ext/attrib4.C new file mode 100644 index 000000000..68cc74155 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib4.C @@ -0,0 +1,31 @@ +// Test for syntax support of various attribute permutations. + +int +__attribute__((noreturn)) +__attribute__((unused)) +one(void); // OK + +__attribute__((noreturn)) +__attribute__((unused)) +int +two(void); // OK + +int +__attribute__((unused)) +three (void) +__attribute__((noreturn)); // OK + +__attribute__((unused)) +int +four (void) +__attribute__((noreturn)); // OK + +int +five(void) +__attribute__((noreturn)) +__attribute__((unused)); // OK + +__attribute__((noreturn)) +int +__attribute__((unused)) // parse error before '__attribute__' in C++ +six (void); // OK in C diff --git a/gcc/testsuite/g++.dg/ext/attrib40.C b/gcc/testsuite/g++.dg/ext/attrib40.C new file mode 100644 index 000000000..9c3f76159 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib40.C @@ -0,0 +1,4 @@ +// PR c++/46803 + +int strftime(char *, int, const char *, const struct tm *) + __attribute__ ((__bounded__(__string__,1,2))); // { dg-warning "ignored" } diff --git a/gcc/testsuite/g++.dg/ext/attrib5.C b/gcc/testsuite/g++.dg/ext/attrib5.C new file mode 100644 index 000000000..f67510dab --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib5.C @@ -0,0 +1,21 @@ +// There were two related problems here, depending on the vintage. At +// one time: +// +// typedef struct A { ... } A __attribute__ ((aligned (16))); +// +// would cause original_types to go into an infinite loop. At other +// times, the attributes applied to an explicit typedef would be lost +// (check_b3 would have a negative size). + +// First check that the declaration is accepted and has an effect. +typedef struct A { int i; } A __attribute__ ((aligned (16))); +int check_A[__alignof__ (A) >= 16 ? 1 : -1]; + +// Check that the alignment is only applied to the typedef. +struct B { int i; }; +struct B b1; +typedef struct B B __attribute__((aligned (16))); +struct B b2; +B b3; +int check_b1[__alignof__ (b1) == __alignof__ (b2) ? 1 : -1]; +int check_b3[__alignof__ (b3) >= 16 ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/attrib6.C b/gcc/testsuite/g++.dg/ext/attrib6.C new file mode 100644 index 000000000..2bdb180d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib6.C @@ -0,0 +1,21 @@ +// Copyright (C) 2002 Free Software Foundation. +// +// Test that the nothrow attribute is working correctly. +// +// Written by Richard Henderson, 26 May 2002. + +// { dg-do link } +extern void foo() __attribute__((nothrow)); +extern void link_error(); + +int main() +{ + try { + foo(); + } catch (...) { + link_error(); + } +} + +void foo() { } + diff --git a/gcc/testsuite/g++.dg/ext/attrib7.C b/gcc/testsuite/g++.dg/ext/attrib7.C new file mode 100644 index 000000000..fa16fdd98 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib7.C @@ -0,0 +1,3 @@ +// { dg-options "-Wunused-parameter" } + +void f (int i __attribute__((__unused__))) {} diff --git a/gcc/testsuite/g++.dg/ext/attrib8.C b/gcc/testsuite/g++.dg/ext/attrib8.C new file mode 100644 index 000000000..7d99132c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib8.C @@ -0,0 +1,11 @@ +// PR 8656 +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target ilp32 } + +extern int * (__attribute__((stdcall)) *fooPtr)( void); +int * __attribute__((stdcall)) myFn01( void) { return 0; } + +void snafu( void) +{ + fooPtr = myFn01; +} diff --git a/gcc/testsuite/g++.dg/ext/attrib9.C b/gcc/testsuite/g++.dg/ext/attrib9.C new file mode 100644 index 000000000..6672f7525 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib9.C @@ -0,0 +1,10 @@ +class __attribute__((unused)) C; +struct __attribute__((unused)) S; +union __attribute__((unused)) U; +enum e {}; +enum __attribute__((unused)) e; // { dg-warning "already defined" } + +struct __attribute((unused)) B *p; // { dg-warning "attributes" } + +template <class T> struct A { }; +struct __attribute((unused)) A<int>; // { dg-warning "attributes" } diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-1.C b/gcc/testsuite/g++.dg/ext/attribute-test-1.C new file mode 100644 index 000000000..7df68930f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-1.C @@ -0,0 +1,38 @@ +// { dg-do run } +// { dg-options "" } +// PR c++/13989 + +extern "C" void abort(); + +#define vector __attribute__((vector_size(16))) + +struct Constants { + inline vector unsigned int deadbeef(void) const { + return (vector unsigned int){0xdeadbeef, 0xabababab, 0x55555555, 0x12345678}; + }; +}; + +inline vector unsigned int const_deadbeef(Constants &C) +{ + return C.deadbeef(); +} + +union u { + unsigned int f[4]; + vector unsigned int v; +} data; + +int main() +{ + Constants c; + data.v = const_deadbeef(c); + + if (data.f[0] != 0xdeadbeef || data.f[1] != 0xabababab + || data.f[2] != 0x55555555 || data.f[3] != 0x12345678) + abort(); + + return 0; +} + +/* Ignore a warning that is irrelevant to the purpose of this test. */ +/* { dg-prune-output ".*GCC vector returned by reference.*" } */ diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-2.C b/gcc/testsuite/g++.dg/ext/attribute-test-2.C new file mode 100644 index 000000000..187067318 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-2.C @@ -0,0 +1,52 @@ +// { dg-do run } +// { dg-options "-Wno-abi" } +// PR c++/9844 + +extern "C" void abort(); + +#define vector __attribute__((vector_size(16))) + +class vector_holder +{ + char __attribute__((vector_size(16))) vec; + char __attribute__((vector_size(16))) vec1; +public: + operator __attribute__((vector_size(16))) short (void) { + return (__attribute__((vector_size(16))) short) vec; + } + + operator __attribute__((vector_size(16))) unsigned int (void) { + return (__attribute__((vector_size(16))) unsigned int) vec1; + } + + vector_holder () { + vec = (__attribute__((vector_size(16))) char) {'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', + 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'}; + vec1 = (__attribute__((vector_size(16))) char) {'m', 'n', 'o', 'q', 'm', 'n', 'o', 'p', + 'm', 'n', 'o', 'q', 'm', 'n', 'o', 'p'}; + } +}; + +union u { + char f[16]; + vector unsigned int v; + vector short vs; +} data; + + +vector_holder vh; + +int main() +{ + data.vs = (__attribute__((vector_size(16))) short) vh; + if (data.f[0] != 'a' || data.f[15] != 'd') + abort(); + data.v = (__attribute__((vector_size(16))) unsigned int) vh; + if (data.f[0] != 'm' || data.f[15] != 'p') + abort(); + + return 0; +} + +/* Ignore a warning that is irrelevant to the purpose of this test. */ +/* { dg-prune-output ".*GCC vector returned by reference.*" } */ diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-3.C b/gcc/testsuite/g++.dg/ext/attribute-test-3.C new file mode 100644 index 000000000..050cbb4ed --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-3.C @@ -0,0 +1,54 @@ +// { dg-do run } + +#define vector __attribute__((vector_size(16))) + +extern "C" void abort(); + +class Star +{ + public: + inline vector float foo() const; + + Star() + { + data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0; + } + + private: + union { + float f[4]; + vector float v; + } data; + + friend vector float fTest(const Star &); +}; + +vector float Star::foo() const +{ + return data.v; +} + +vector float fTest(const Star & val) +{ + vector float vf = val.foo(); + return vf; +} + +int main() { + + Star s; + + union u { + float f[4]; + vector float v; + } data; + + data.v = fTest(s); + for (int i=0 ; i < 4; i++) + if (data.f[i] != (float)(i+1)) + abort(); + return 0; +} + +/* Ignore a warning that is irrelevant to the purpose of this test. */ +/* { dg-prune-output ".*GCC vector returned by reference.*" } */ diff --git a/gcc/testsuite/g++.dg/ext/attribute-test-4.C b/gcc/testsuite/g++.dg/ext/attribute-test-4.C new file mode 100644 index 000000000..4783ee8a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attribute-test-4.C @@ -0,0 +1,51 @@ +// { dg-do run } + +#define vector __attribute__((vector_size(16))) + +extern "C" void abort(); + +union U { + float f[4]; + vector float v; +} data; + +class Star +{ + public: + static vector float foo(); + + Star() + { + data.f[0] = 1.0; data.f[1] = 2.0; data.f[2] = 3.0, data.f[3] = 4.0; + } + + private: + friend vector float fTest(); +}; + +vector float Star::foo() +{ + return data.v; +} + +vector float fTest() +{ + vector float vf = Star::foo(); + return vf; +} + +int main() { + + U data; + Star s; + + + data.v = fTest(); + for (int i=0 ; i < 4; i++) + if (data.f[i] != (float)(i+1)) + abort(); + return 0; +} + +/* Ignore a warning that is irrelevant to the purpose of this test. */ +/* { dg-prune-output ".*GCC vector returned by reference.*" } */ diff --git a/gcc/testsuite/g++.dg/ext/bitfield1.C b/gcc/testsuite/g++.dg/ext/bitfield1.C new file mode 100644 index 000000000..25c90df41 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/bitfield1.C @@ -0,0 +1,22 @@ +// PR c++/30328 +// { dg-do link } +// { dg-options "" } + +struct S +{ + signed int a:17; +} x; + +typedef typeof (x.a) foo; + +template <class T> +T* inc(T* p) { return p+1; } + +int main () +{ + foo x[2] = { 1,2 }; + int y[2] = { 1,2 }; + *inc(x); + *inc(y); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/bitfield2.C b/gcc/testsuite/g++.dg/ext/bitfield2.C new file mode 100644 index 000000000..753492ce9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/bitfield2.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* Remove pedantic. Allow the GCC extension to use char for bitfields. */ +/* { dg-options "" } */ +/* { dg-options "-mno-ms-bitfields" { target i?86-*-netware } } */ + +struct t /* { dg-message "note: offset of packed bit-field 't::b' has changed in GCC 4.4" "" { target pcc_bitfield_type_matters } } */ +{ + char a:4; + char b:8; + char c:4; +} __attribute__ ((packed)); + +int assrt[sizeof (struct t) == 2 ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/bitfield3.C b/gcc/testsuite/g++.dg/ext/bitfield3.C new file mode 100644 index 000000000..0a89bdab1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/bitfield3.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-packed-bitfield-compat" } */ +/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target i?86-*-netware } } */ + +struct t +{ + char a:4; + char b:8; + char c:4; +} __attribute__ ((packed)); + +int assrt[sizeof (struct t) == 2 ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/bitfield4.C b/gcc/testsuite/g++.dg/ext/bitfield4.C new file mode 100644 index 000000000..7bf855331 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/bitfield4.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-options "-mno-ms-bitfields" { target i?86-*-netware } } */ + +struct t /* { dg-message "note: offset of packed bit-field 't::b' has changed in GCC 4.4" "" { target pcc_bitfield_type_matters } } */ +{ + char a:4; + char b:8 __attribute__ ((packed)); + char c:4; +}; + +int assrt[sizeof (struct t) == 2 ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/bitfield5.C b/gcc/testsuite/g++.dg/ext/bitfield5.C new file mode 100644 index 000000000..cb24c65d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/bitfield5.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-packed-bitfield-compat" } */ +/* { dg-options "-Wno-packed-bitfield-compat -mno-ms-bitfields" { target i?86-*-netware } } */ + +struct t +{ + char a:4; + char b:8 __attribute__ ((packed)); + char c:4; +}; + +int assrt[sizeof (struct t) == 2 ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/boolcomplex-1.c b/gcc/testsuite/g++.dg/ext/boolcomplex-1.c new file mode 100644 index 000000000..d05d9bbd8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/boolcomplex-1.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ +bool b = --0i == 0; /* { dg-error "lvalue required as decrement operand" } */ diff --git a/gcc/testsuite/g++.dg/ext/builtin-object-size1.C b/gcc/testsuite/g++.dg/ext/builtin-object-size1.C new file mode 100644 index 000000000..8590a0bbe --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-object-size1.C @@ -0,0 +1,435 @@ +// { dg-do run } +// { dg-options "-O2" } + +typedef __SIZE_TYPE__ size_t; +extern "C" void abort (); +extern "C" void exit (int); +extern "C" void *malloc (size_t); +extern "C" void free (void *); + +struct A +{ + char a[10]; + int b; + char c[10]; +}; + +void +__attribute__ ((noinline)) +test1 (A *p) +{ + char *c; + if (__builtin_object_size (&p->a, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a[0], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->b, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->c, 0) != (size_t) -1) + abort (); + c = p->a; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a, 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 1) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 1) != (size_t) -1) + abort (); + c = p->a; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 1) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 1) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 1) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a, 2) != 0) + abort (); + if (__builtin_object_size (&p->a[0], 2) != 0) + abort (); + if (__builtin_object_size (&p->a[3], 2) != 0) + abort (); + if (__builtin_object_size (&p->b, 2) != 0) + abort (); + if (__builtin_object_size (&p->c, 2) != 0) + abort (); + c = p->a; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 2) != 0) + abort (); + if (__builtin_object_size (&p->a, 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 3) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 3) != 0) + abort (); + c = p->a; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 3) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 3) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 3) != 0) + abort (); +} + +void +__attribute__ ((noinline)) +test2 (void) +{ + char *c; + size_t s = 2 * sizeof (A); + A *p = (A *) malloc (2 * sizeof (A)); + if (__builtin_object_size (&p->a, 0) != s) + abort (); + if (__builtin_object_size (&p->a[0], 0) != s) + abort (); + if (__builtin_object_size (&p->a[3], 0) != s - 3) + abort (); + if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (A, b)) + abort (); + if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 0) != s) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 0) != s) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 0) != s - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 0) != s - __builtin_offsetof (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 0) != s - __builtin_offsetof (A, c)) + abort (); + if (__builtin_object_size (&p->a, 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 1) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 1) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 1) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 1) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 1) != s - __builtin_offsetof (A, c)) + abort (); + if (__builtin_object_size (&p->a, 2) != s) + abort (); + if (__builtin_object_size (&p->a[0], 2) != s) + abort (); + if (__builtin_object_size (&p->a[3], 2) != s - 3) + abort (); + if (__builtin_object_size (&p->b, 2) != s - __builtin_offsetof (A, b)) + abort (); + if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 2) != s) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 2) != s) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 2) != s - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 2) != s - __builtin_offsetof (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 2) != s - __builtin_offsetof (A, c)) + abort (); + if (__builtin_object_size (&p->a, 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 3) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 3) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 3) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 3) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 3) != s - __builtin_offsetof (A, c)) + abort (); + free (p); +} + +void +__attribute__ ((noinline)) +test3 (void) +{ + char *c; + size_t s; + A *p = (A *) malloc (4); + if (__builtin_object_size (&p->a, 0) != 4) + abort (); + if (__builtin_object_size (&p->a[0], 0) != 4) + abort (); + if (__builtin_object_size (&p->a[3], 0) != 1) + abort (); + if (__builtin_object_size (&p->b, 0) != 0) + abort (); + if (__builtin_object_size (&p->c, 0) != 0) + abort (); + if (__builtin_object_size (&p->a, 1) != 4) + abort (); + if (__builtin_object_size (&p->a[0], 1) != 4) + abort (); + if (__builtin_object_size (&p->a[3], 1) != 1) + abort (); + if (__builtin_object_size (&p->b, 1) != 0) + abort (); + if (__builtin_object_size (&p->c, 1) != 0) + abort (); + free (p); + s = __builtin_offsetof (A, c) + 4; + p = (A *) malloc (s); + if (__builtin_object_size (&p->a, 0) != s) + abort (); + if (__builtin_object_size (&p->a[0], 0) != s) + abort (); + if (__builtin_object_size (&p->a[3], 0) != s - 3) + abort (); + if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (A, b)) + abort (); + if (__builtin_object_size (&p->c, 0) != 4) + abort (); + if (__builtin_object_size (&p->a, 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 1) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 1) != 4) + abort (); + free (p); +} + +struct B +{ + A a[4]; +}; + +void +__attribute__ ((noinline)) +test4 (struct B *q, int i) +{ + if (__builtin_object_size (&q->a[2].a[2], 1) != sizeof (q->a[0].a) - 2) + abort (); + if (__builtin_object_size (&q->a[2].c[2], 1) != sizeof (q->a[0].c) - 2) + abort (); + if (__builtin_object_size (&q->a[3].a[2], 1) != sizeof (q->a[0].a) - 2) + abort (); + if (__builtin_object_size (&q->a[3].c[2], 1) != sizeof (q->a[0].c) - 2) + abort (); + if (__builtin_object_size (&q->a[i].a[2], 1) != sizeof (q->a[0].a) - 2) + abort (); + if (__builtin_object_size (&q->a[i].c[2], 1) != sizeof (q->a[0].c) - 2) + abort (); +} + +struct C +{ + char a[10]; + char b; +}; + +void +__attribute__ ((noinline)) +test5 (struct C *c) +{ + if (__builtin_object_size (&c->b, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&c->b, 1) != 1) + abort (); + if (__builtin_object_size (&c->b, 2) != 0) + abort (); + if (__builtin_object_size (&c->b, 3) != 1) + abort (); +} + +struct D +{ + int i; + struct D1 + { + char b; + char a[10]; + } j; +}; + +void +__attribute__ ((noinline)) +test6 (struct D *d) +{ + if (__builtin_object_size (&d->j.a[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&d->j.a[3], 1) != sizeof (d->j.a) - 3) + abort (); + if (__builtin_object_size (&d->j.a[3], 2) != 0) + abort (); + if (__builtin_object_size (&d->j.a[3], 3) != sizeof (d->j.a) - 3) + abort (); +} + +struct E +{ + int i; + struct E1 + { + char b; + char a[10]; + } j[1]; +}; + +void +__attribute__ ((noinline)) +test7 (struct E *e) +{ + if (__builtin_object_size (&e->j[0].a[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&e->j[0].a[3], 1) != sizeof (e->j[0].a) - 3) + abort (); + if (__builtin_object_size (&e->j[0].a[3], 2) != 0) + abort (); + if (__builtin_object_size (&e->j[0].a[3], 3) != sizeof (e->j[0].a) - 3) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 0) != (size_t) -1) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 1) != (size_t) -1) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 2) != 0) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 3) != 0) + abort (); +} + +union F +{ + char a[1]; + struct F1 + { + char b; + char c[10]; + } d; +}; + +void +__attribute__ ((noinline)) +test8 (union F *f) +{ + if (__builtin_object_size (&f->d.c[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&f->d.c[3], 1) != (size_t) -1) + abort (); + if (__builtin_object_size (&f->d.c[3], 2) != 0) + abort (); + if (__builtin_object_size (&f->d.c[3], 3) != 0) + abort (); +} + +int +main (void) +{ + A a, *p = &a; + int i = 1; + __asm ("" : "+r" (p)); + test1 (p); + test2 (); + test3 (); + struct B b, *q = &b; + __asm ("" : "+r" (q), "+r" (i)); + test4 (q, i); + struct C c, *cp = &c; + __asm ("" : "+r" (cp)); + test5 (cp); + struct D d, *dp = &d; + __asm ("" : "+r" (dp)); + test6 (dp); + struct E e, *ep = &e; + __asm ("" : "+r" (ep)); + test7 (ep); + union F f, *fp = &f; + __asm ("" : "+r" (fp)); + test8 (fp); + exit (0); +} diff --git a/gcc/testsuite/g++.dg/ext/builtin-object-size2.C b/gcc/testsuite/g++.dg/ext/builtin-object-size2.C new file mode 100644 index 000000000..d79b1b833 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-object-size2.C @@ -0,0 +1,438 @@ +// { dg-do run } +// { dg-options "-O2" } + +typedef __SIZE_TYPE__ size_t; +extern "C" void abort (); +extern "C" void exit (int); +extern "C" void *malloc (size_t); +extern "C" void free (void *); + +typedef struct A +{ + char a[10]; + int b; + char c[10]; + static int d; +} AT; + +int A::d = 6; + +void +__attribute__ ((noinline)) +test1 (A *p) +{ + char *c; + if (__builtin_object_size (&p->a, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a[0], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->b, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->c, 0) != (size_t) -1) + abort (); + c = p->a; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a, 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 1) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 1) != (size_t) -1) + abort (); + c = p->a; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 1) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 1) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 1) != (size_t) -1) + abort (); + if (__builtin_object_size (&p->a, 2) != 0) + abort (); + if (__builtin_object_size (&p->a[0], 2) != 0) + abort (); + if (__builtin_object_size (&p->a[3], 2) != 0) + abort (); + if (__builtin_object_size (&p->b, 2) != 0) + abort (); + if (__builtin_object_size (&p->c, 2) != 0) + abort (); + c = p->a; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 2) != 0) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 2) != 0) + abort (); + if (__builtin_object_size (&p->a, 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 3) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 3) != 0) + abort (); + c = p->a; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 3) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 3) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 3) != 0) + abort (); +} + +void +__attribute__ ((noinline)) +test2 (void) +{ + char *c; + size_t s = 2 * sizeof (A); + A *p = (A *) malloc (2 * sizeof (A)); + if (__builtin_object_size (&p->a, 0) != s) + abort (); + if (__builtin_object_size (&p->a[0], 0) != s) + abort (); + if (__builtin_object_size (&p->a[3], 0) != s - 3) + abort (); + if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (A, b)) + abort (); + if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 0) != s) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 0) != s) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 0) != s - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 0) != s - __builtin_offsetof (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 0) != s - __builtin_offsetof (A, c)) + abort (); + if (__builtin_object_size (&p->a, 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 1) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 1) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 1) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 1) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 1) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 1) != s - __builtin_offsetof (A, c)) + abort (); + if (__builtin_object_size (&p->a, 2) != s) + abort (); + if (__builtin_object_size (&p->a[0], 2) != s) + abort (); + if (__builtin_object_size (&p->a[3], 2) != s - 3) + abort (); + if (__builtin_object_size (&p->b, 2) != s - __builtin_offsetof (A, b)) + abort (); + if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 2) != s) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 2) != s) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 2) != s - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 2) != s - __builtin_offsetof (A, b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 2) != s - __builtin_offsetof (A, c)) + abort (); + if (__builtin_object_size (&p->a, 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 3) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 3) != s - __builtin_offsetof (A, c)) + abort (); + c = p->a; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[0]; + if (__builtin_object_size (c, 3) != sizeof (p->a)) + abort (); + c = &p->a[3]; + if (__builtin_object_size (c, 3) != sizeof (p->a) - 3) + abort (); + c = (char *) &p->b; + if (__builtin_object_size (c, 3) != sizeof (p->b)) + abort (); + c = (char *) &p->c; + if (__builtin_object_size (c, 3) != s - __builtin_offsetof (A, c)) + abort (); + free (p); +} + +void +__attribute__ ((noinline)) +test3 (void) +{ + char *c; + size_t s; + A *p = (A *) malloc (4); + if (__builtin_object_size (&p->a, 0) != 4) + abort (); + if (__builtin_object_size (&p->a[0], 0) != 4) + abort (); + if (__builtin_object_size (&p->a[3], 0) != 1) + abort (); + if (__builtin_object_size (&p->b, 0) != 0) + abort (); + if (__builtin_object_size (&p->c, 0) != 0) + abort (); + if (__builtin_object_size (&p->a, 1) != 4) + abort (); + if (__builtin_object_size (&p->a[0], 1) != 4) + abort (); + if (__builtin_object_size (&p->a[3], 1) != 1) + abort (); + if (__builtin_object_size (&p->b, 1) != 0) + abort (); + if (__builtin_object_size (&p->c, 1) != 0) + abort (); + free (p); + s = __builtin_offsetof (A, c) + 4; + p = (A *) malloc (s); + if (__builtin_object_size (&p->a, 0) != s) + abort (); + if (__builtin_object_size (&p->a[0], 0) != s) + abort (); + if (__builtin_object_size (&p->a[3], 0) != s - 3) + abort (); + if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (A, b)) + abort (); + if (__builtin_object_size (&p->c, 0) != 4) + abort (); + if (__builtin_object_size (&p->a, 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a)) + abort (); + if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3) + abort (); + if (__builtin_object_size (&p->b, 1) != sizeof (p->b)) + abort (); + if (__builtin_object_size (&p->c, 1) != 4) + abort (); + free (p); +} + +struct B +{ + A a[4]; +}; + +void +__attribute__ ((noinline)) +test4 (struct B *q, int i) +{ + if (__builtin_object_size (&q->a[2].a[2], 1) != sizeof (q->a[0].a) - 2) + abort (); + if (__builtin_object_size (&q->a[2].c[2], 1) != sizeof (q->a[0].c) - 2) + abort (); + if (__builtin_object_size (&q->a[3].a[2], 1) != sizeof (q->a[0].a) - 2) + abort (); + if (__builtin_object_size (&q->a[3].c[2], 1) != sizeof (q->a[0].c) - 2) + abort (); + if (__builtin_object_size (&q->a[i].a[2], 1) != sizeof (q->a[0].a) - 2) + abort (); + if (__builtin_object_size (&q->a[i].c[2], 1) != sizeof (q->a[0].c) - 2) + abort (); +} + +struct C +{ + char a[10]; + char b; +}; + +void +__attribute__ ((noinline)) +test5 (struct C *c) +{ + if (__builtin_object_size (&c->b, 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&c->b, 1) != 1) + abort (); + if (__builtin_object_size (&c->b, 2) != 0) + abort (); + if (__builtin_object_size (&c->b, 3) != 1) + abort (); +} + +struct D +{ + int i; + struct D1 + { + char b; + char a[10]; + } j; +}; + +void +__attribute__ ((noinline)) +test6 (struct D *d) +{ + if (__builtin_object_size (&d->j.a[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&d->j.a[3], 1) != sizeof (d->j.a) - 3) + abort (); + if (__builtin_object_size (&d->j.a[3], 2) != 0) + abort (); + if (__builtin_object_size (&d->j.a[3], 3) != sizeof (d->j.a) - 3) + abort (); +} + +struct E +{ + int i; + struct E1 + { + char b; + char a[10]; + } j[1]; +}; + +void +__attribute__ ((noinline)) +test7 (struct E *e) +{ + if (__builtin_object_size (&e->j[0].a[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&e->j[0].a[3], 1) != sizeof (e->j[0].a) - 3) + abort (); + if (__builtin_object_size (&e->j[0].a[3], 2) != 0) + abort (); + if (__builtin_object_size (&e->j[0].a[3], 3) != sizeof (e->j[0].a) - 3) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 0) != (size_t) -1) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 1) != (size_t) -1) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 2) != 0) + abort (); + if (__builtin_object_size ((char *) &e->j[0], 3) != 0) + abort (); +} + +union F +{ + char a[1]; + struct F1 + { + char b; + char c[10]; + } d; +}; + +void +__attribute__ ((noinline)) +test8 (union F *f) +{ + if (__builtin_object_size (&f->d.c[3], 0) != (size_t) -1) + abort (); + if (__builtin_object_size (&f->d.c[3], 1) != (size_t) -1) + abort (); + if (__builtin_object_size (&f->d.c[3], 2) != 0) + abort (); + if (__builtin_object_size (&f->d.c[3], 3) != 0) + abort (); +} + +int +main (void) +{ + A a, *p = &a; + int i = 1; + __asm ("" : "+r" (p)); + test1 (p); + test2 (); + test3 (); + struct B b, *q = &b; + __asm ("" : "+r" (q), "+r" (i)); + test4 (q, i); + struct C c, *cp = &c; + __asm ("" : "+r" (cp)); + test5 (cp); + struct D d, *dp = &d; + __asm ("" : "+r" (dp)); + test6 (dp); + struct E e, *ep = &e; + __asm ("" : "+r" (ep)); + test7 (ep); + union F f, *fp = &f; + __asm ("" : "+r" (fp)); + test8 (fp); + exit (0); +} diff --git a/gcc/testsuite/g++.dg/ext/builtin1.C b/gcc/testsuite/g++.dg/ext/builtin1.C new file mode 100644 index 000000000..9947c85bf --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin1.C @@ -0,0 +1,10 @@ +// Test whether alternate 'asm' name is applied correctly to +// builtin in global namespace + +// { dg-do compile } +// { dg-options "" } +// { dg-final { scan-assembler "fancy_printf" } } + +extern "C" int printf(const char*, ...) __asm("_fancy_printf"); + +void foo() { printf("abc"); } diff --git a/gcc/testsuite/g++.dg/ext/builtin10.C b/gcc/testsuite/g++.dg/ext/builtin10.C new file mode 100644 index 000000000..8742223a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin10.C @@ -0,0 +1,56 @@ +// { dg-do compile { target correct_iso_cpp_string_wchar_protos } } +// { dg-options "-O2 -fdump-tree-optimized" } + +#include <cstring> + +const void *cv1; +const char *cc1, *cc2, *cc3, *cc4; +void *v1; +char *c1, *c2, *c3, *c4; + +void +f1 (void) +{ + cv1 = memchr ("abcba", 'b', 3); + cc1 = strchr ("abcba", 'b'); + cc2 = strrchr ("abcba", 'b'); + cc3 = strpbrk ("dabc", "abc"); + cc4 = strstr ("aaabc", "abc"); +} + +void +f2 (void) +{ + cv1 = std::memchr ("abcba", 'b', 3); + cc1 = std::strchr ("abcba", 'b'); + cc2 = std::strrchr ("abcba", 'b'); + cc3 = std::strpbrk ("dabc", "abc"); + cc4 = std::strstr ("aaabc", "abc"); +} + +void +f3 (void) +{ + v1 = memchr ((char *)"abcba", 'b', 3); + c1 = strchr ((char *)"abcba", 'b'); + c2 = strrchr ((char *)"abcba", 'b'); + c3 = strpbrk ((char *)"dabc", "abc"); + c4 = strstr ((char *)"aaabc", "abc"); +} + +void +f4 (void) +{ + v1 = std::memchr ((char *)"abcba", 'b', 3); + c1 = std::strchr ((char *)"abcba", 'b'); + c2 = std::strrchr ((char *)"abcba", 'b'); + c3 = std::strpbrk ((char *)"dabc", "abc"); + c4 = std::strstr ((char *)"aaabc", "abc"); +} + +// { dg-final { scan-tree-dump-not "memchr" "optimized" } } +// { dg-final { scan-tree-dump-not "strchr" "optimized" } } +// { dg-final { scan-tree-dump-not "strrchr" "optimized" } } +// { dg-final { scan-tree-dump-not "strpbrk" "optimized" } } +// { dg-final { scan-tree-dump-not "strstr" "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/ext/builtin11.C b/gcc/testsuite/g++.dg/ext/builtin11.C new file mode 100644 index 000000000..2749671fb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin11.C @@ -0,0 +1,9 @@ +// PR c++/40138 +// { dg-options "-Wall" } + +void foo(int i, ...) +{ + V v; // { dg-error "not declared|expected" } + __builtin_va_start(v, i); // { dg-error "not declared" } + i = __builtin_va_arg(v, int); +} diff --git a/gcc/testsuite/g++.dg/ext/builtin2.C b/gcc/testsuite/g++.dg/ext/builtin2.C new file mode 100644 index 000000000..ffa25285b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin2.C @@ -0,0 +1,13 @@ +// PR c++/18514 +// Test whether alternate 'asm' name is applied correctly to +// builtin imported into namespace std. + +// { dg-do compile } +// { dg-options "" } +// { dg-final { scan-assembler "fancy_printf" } } + +extern "C" int printf(const char*, ...) __asm("_fancy_printf"); + +namespace std { using ::printf; } + +namespace std { void foo() { printf("abc"); } } diff --git a/gcc/testsuite/g++.dg/ext/builtin3.C b/gcc/testsuite/g++.dg/ext/builtin3.C new file mode 100644 index 000000000..001d5f784 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin3.C @@ -0,0 +1,14 @@ +// Verify that declaring builtin in namespace std doesn't give us +// declaration in global namespace + +// { dg-do compile } +// { dg-options "" } + +namespace std { +extern "C" int printf(char*, ...); // { dg-message "std::printf" } +} + +void foo() { + printf("abc"); // { dg-error "not declared" } + // { dg-message "suggested alternative" "suggested alternative" { target *-*-* } 12 } +} diff --git a/gcc/testsuite/g++.dg/ext/builtin4.C b/gcc/testsuite/g++.dg/ext/builtin4.C new file mode 100644 index 000000000..8804b53bd --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin4.C @@ -0,0 +1,10 @@ +// Verify that builtin is used when declared in global namespace + +// { dg-do compile } +// { dg-options "-Wall" } + +extern "C" int printf(const char*,...); + +void foo() { + printf("%d"); // { dg-warning "expects a matching" } +} diff --git a/gcc/testsuite/g++.dg/ext/builtin5.C b/gcc/testsuite/g++.dg/ext/builtin5.C new file mode 100644 index 000000000..051224ffd --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin5.C @@ -0,0 +1,12 @@ +// Verify that builtin is used when declared in namespace std + +// { dg-do compile } +// { dg-options "-Wall" } + +namespace std { + extern "C" int printf(const char*,...); +} + +void foo() { + std::printf("%d"); // { dg-warning "expects a matching" } +} diff --git a/gcc/testsuite/g++.dg/ext/builtin6.C b/gcc/testsuite/g++.dg/ext/builtin6.C new file mode 100644 index 000000000..8f405b095 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin6.C @@ -0,0 +1,11 @@ +// PR c++/19044 +// Verify that alternate asm name for builtin named "foo" also gets +// applied to its sibling "__builtin_foo". + +// { dg-do compile } +// { dg-final { scan-assembler "fancy_sin" } } + +extern "C" double sin(double) __asm("_fancy_sin"); + +double foo(double x) { return __builtin_sin(x); } + diff --git a/gcc/testsuite/g++.dg/ext/builtin7.C b/gcc/testsuite/g++.dg/ext/builtin7.C new file mode 100644 index 000000000..dae658abc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin7.C @@ -0,0 +1,14 @@ +// PR c++/19628 +// Verify that __builtin_constant_p may appear in a constant-expression. + +// { dg-do run } + +int main() +{ + switch (3) { + case (__builtin_constant_p(7) ? 3 : 8): + return 0; + default: + return 1; + } +} diff --git a/gcc/testsuite/g++.dg/ext/builtin8.C b/gcc/testsuite/g++.dg/ext/builtin8.C new file mode 100644 index 000000000..dd4997725 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin8.C @@ -0,0 +1,16 @@ +// PR c++/19628 +// Verify that __builtin_constant_p may appear in a constant-expression. + +// { dg-do compile } + +template <int I> +int f(int x[__builtin_constant_p(I)]) +{ + return x[0]; +} + +int g() +{ + int a[1] = { 7 }; + return f<32>(a); +} diff --git a/gcc/testsuite/g++.dg/ext/builtin9.C b/gcc/testsuite/g++.dg/ext/builtin9.C new file mode 100644 index 000000000..6b2b712de --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin9.C @@ -0,0 +1,3 @@ +// PR c++/21619 +// { dg-options "" } +int f[__builtin_constant_p(&"Hello"[0])?1:-1]; diff --git a/gcc/testsuite/g++.dg/ext/c99struct1.C b/gcc/testsuite/g++.dg/ext/c99struct1.C new file mode 100644 index 000000000..93e84b460 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/c99struct1.C @@ -0,0 +1,12 @@ +// { dg-options "" } +// C99 anon struct variable with array accesses. + +struct s { int a[1]; }; + +void +foo5 (void) +{ + ((struct s) { { 0 } }).a[0] = 1; +} + + diff --git a/gcc/testsuite/g++.dg/ext/case-range1.C b/gcc/testsuite/g++.dg/ext/case-range1.C new file mode 100644 index 000000000..0e313d6b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/case-range1.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// Tests if case ranges (a GNU extension) are accepted +// { dg-options "" } +const int low = -2; +const int high = 15; + +template <typename T> +T f2 (T i) +{ + switch (i) + { + case low ... high : return i + 1; + default : return 0; + } +} + +int f (int i) +{ + switch (i) { + case 1 ... 10: return i + 1; + default: return f2 (i); + } +} diff --git a/gcc/testsuite/g++.dg/ext/case-range2.C b/gcc/testsuite/g++.dg/ext/case-range2.C new file mode 100644 index 000000000..de1f2a7e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/case-range2.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// Tests if case ranges (a GNU extension) correctly emit messages +// about overlapping ranges. +// { dg-options "" } + +const int low = -2; +const int high = 15; + +template <typename T> +T f2 (T i) +{ + switch (i) + { + case low ... high : return i + 1; // { dg-error "previously" } + case 5 : return i + 2; // { dg-error "duplicate" } + default : return 0; + } +} + +int f (int i) +{ + switch (i) { + case 1 ... 10: return i + 1; // { dg-error "first entry" } + case 3 ... 5 : return i + 3; // { dg-error "duplicate" } + default: return f2 (i); // { dg-message "instantiated" } + } +} diff --git a/gcc/testsuite/g++.dg/ext/case-range3.C b/gcc/testsuite/g++.dg/ext/case-range3.C new file mode 100644 index 000000000..5a09c12d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/case-range3.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// Tests if case ranges (a GNU extension) emit errors in ISO mode +// { dg-options "-pedantic" } +const int low = -2; +const int high = 15; + +template <typename T> +T f2 (T i) +{ + switch (i) + { + case low ... high : return i + 1; // { dg-warning "non-standard" } + default : return 0; + } +} + +int f (int i) +{ + switch (i) { + case 1 ... 10: return i + 1; // { dg-warning "non-standard" } + default: return f2 (i); // { dg-message "instantiated" } + } +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-1.C b/gcc/testsuite/g++.dg/ext/cleanup-1.C new file mode 100644 index 000000000..8e8353754 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-1.C @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ +/* Validate expected warnings and errors. */ + +#define U __attribute__((unused)) +#define C(x) __attribute__((cleanup(x))) + +static int f1(void *x U) { return 0; } +static void f2() { } /* { dg-message "note: declared here" } */ +static void f3(void) { } /* { dg-message "note: declared here" } */ +static void f4(void *x U) { } +static void f5(int *x U) { } +static void f6(double *x U) { } +static void f7(const int *x U) { } +static void f8(const int *x U, int y U) { } /* { dg-message "note: declared here" } */ +static void f9(int x U) { } + +void test(void) +{ + int o1 C(f1); + int o2 C(f2); /* { dg-error "too many arguments" } */ + int o3 C(f3); /* { dg-error "too many arguments" } */ + int o4 C(f4); + int o5 C(f5); + int o6 C(f6); /* { dg-error "cannot convert" } */ + int o7 C(f7); + int o8 C(f8); /* { dg-error "too few arguments" } */ + int o9 C(f9); /* { dg-error "conversion" } */ + int o10 U C(undef); /* { dg-error "not a function" } */ + int o11 U C(o1); /* { dg-error "not a function" } */ + int o12 U C("f1"); /* { dg-error "not an identifier" } */ + static int o13 U C(f1); /* { dg-warning "attribute ignored" } */ +} + +int o14 C(f1); /* { dg-warning "attribute ignored" } */ +void t15(int o U C(f1)) {} /* { dg-warning "attribute ignored" } */ diff --git a/gcc/testsuite/g++.dg/ext/cleanup-10.C b/gcc/testsuite/g++.dg/ext/cleanup-10.C new file mode 100644 index 000000000..eeb607b29 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-10.C @@ -0,0 +1,117 @@ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ +/* Verify that cleanups work with exception handling through signal frames + on alternate stack. */ + +#include <unwind.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc + = (struct _Unwind_Exception *) malloc (sizeof (*exc)); + memset (&exc->exception_class, 0, sizeof (exc->exception_class)); + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +int count; +char *null; + +static void counter (void *p __attribute__((unused))) +{ + ++count; +} + +static void handler (void *p __attribute__((unused))) +{ + if (count != 2) + abort (); + exit (0); +} + +static int __attribute__((noinline)) fn5 () +{ + char dummy __attribute__((cleanup (counter))); + force_unwind (); + return 0; +} + +static void fn4 (int sig, siginfo_t *info, void *ctx) +{ + char dummy __attribute__((cleanup (counter))); + fn5 (); + null = NULL; +} + +static void fn3 () +{ + abort (); +} + +static int __attribute__((noinline)) fn2 () +{ + *null = 0; + fn3 (); + return 0; +} + +static int __attribute__((noinline)) fn1 () +{ + stack_t ss; + struct sigaction s; + + ss.ss_size = 4 * sysconf (_SC_PAGESIZE); + if (ss.ss_size < SIGSTKSZ) + ss.ss_size = SIGSTKSZ; + ss.ss_sp = malloc (ss.ss_size); + if (ss.ss_sp == NULL) + exit (1); + ss.ss_flags = 0; + if (sigaltstack (&ss, NULL) < 0) + exit (1); + + sigemptyset (&s.sa_mask); + s.sa_sigaction = fn4; + s.sa_flags = SA_RESETHAND | SA_ONSTACK; + sigaction (SIGSEGV, &s, NULL); + sigaction (SIGBUS, &s, NULL); + fn2 (); + return 0; +} + +static int __attribute__((noinline)) fn0 () +{ + char dummy __attribute__((cleanup (handler))); + fn1 (); + null = 0; + return 0; +} + +int main() +{ + fn0 (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-11.C b/gcc/testsuite/g++.dg/ext/cleanup-11.C new file mode 100644 index 000000000..0b6d11ce2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-11.C @@ -0,0 +1,117 @@ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ +/* Verify that cleanups work with exception handling through realtime signal + frames on alternate stack. */ + +#include <unwind.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc + = (struct _Unwind_Exception*) malloc (sizeof (*exc)); + memset (&exc->exception_class, 0, sizeof (exc->exception_class)); + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +int count; +char *null; + +static void counter (void *p __attribute__((unused))) +{ + ++count; +} + +static void handler (void *p __attribute__((unused))) +{ + if (count != 2) + abort (); + exit (0); +} + +static int __attribute__((noinline)) fn5 () +{ + char dummy __attribute__((cleanup (counter))); + force_unwind (); + return 0; +} + +static void fn4 (int sig, siginfo_t *info, void *ctx) +{ + char dummy __attribute__((cleanup (counter))); + fn5 (); + null = NULL; +} + +static void fn3 () +{ + abort (); +} + +static int __attribute__((noinline)) fn2 () +{ + *null = 0; + fn3 (); + return 0; +} + +static int __attribute__((noinline)) fn1 () +{ + stack_t ss; + struct sigaction s; + + ss.ss_size = 4 * sysconf (_SC_PAGESIZE); + if (ss.ss_size < SIGSTKSZ) + ss.ss_size = SIGSTKSZ; + ss.ss_sp = malloc (ss.ss_size); + if (ss.ss_sp == NULL) + exit (1); + ss.ss_flags = 0; + if (sigaltstack (&ss, NULL) < 0) + exit (1); + + sigemptyset (&s.sa_mask); + s.sa_sigaction = fn4; + s.sa_flags = SA_RESETHAND | SA_ONSTACK | SA_SIGINFO; + sigaction (SIGSEGV, &s, NULL); + sigaction (SIGBUS, &s, NULL); + fn2 (); + return 0; +} + +static int __attribute__((noinline)) fn0 () +{ + char dummy __attribute__((cleanup (handler))); + fn1 (); + null = 0; + return 0; +} + +int main() +{ + fn0 (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-2.C b/gcc/testsuite/g++.dg/ext/cleanup-2.C new file mode 100644 index 000000000..d9033b454 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-2.C @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-options "" } */ +/* Verify that cleanup works in the most basic of ways. */ + +extern "C" void exit(int); +extern "C" void abort(void); + +static void handler(void *p __attribute__((unused))) +{ + exit (0); +} + +static void doit(void) +{ + int x __attribute__((cleanup (handler))); +} + +int main() +{ + doit (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-3.C b/gcc/testsuite/g++.dg/ext/cleanup-3.C new file mode 100644 index 000000000..5367c496e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-3.C @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-options "" } */ +/* Verify that the cleanup handler receives the proper contents + of the variable. */ + +extern "C" void exit(int); +extern "C" void abort(void); + +static int expected; + +static void +handler(int *p) +{ + if (*p != expected) + abort (); +} + +static void __attribute__((noinline)) +bar(void) +{ +} + +static void doit(int x, int y) +{ + int r __attribute__((cleanup (handler))); + if (x < y) + { + r = 0; + return; + } + + bar(); + r = x + y; +} + +int main() +{ + expected = 0; + doit (1, 2); + + expected = 3; + doit (2, 1); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-4.C b/gcc/testsuite/g++.dg/ext/cleanup-4.C new file mode 100644 index 000000000..ae9a6e40f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-4.C @@ -0,0 +1,39 @@ +/* { dg-do run } */ +/* { dg-options "" } */ +/* Verify cleanup execution on non-trivial exit from a block. */ + +extern "C" void exit(int); +extern "C" void abort(void); + +static int counter; + +static void +handler(int *p) +{ + counter += *p; +} + +static void __attribute__((noinline)) +bar(void) +{ +} + +static void doit(int n, int n2) +{ + int i; + for (i = 0; i < n; ++i) + { + int dummy __attribute__((cleanup (handler))) = i; + if (i == n2) + break; + bar(); + } +} + +int main() +{ + doit (10, 6); + if (counter != 0 + 1 + 2 + 3 + 4 + 5 + 6) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-5.C b/gcc/testsuite/g++.dg/ext/cleanup-5.C new file mode 100644 index 000000000..db4c2bbc8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-5.C @@ -0,0 +1,54 @@ +/* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */ +/* { dg-do run } */ +/* { dg-options "-fexceptions" } */ +/* { dg-skip-if "" { "ia64-*-hpux11.*" } { "*" } { "" } } */ +/* Verify that cleanups work with exception handling. */ + +#include <unwind.h> +#include <stdlib.h> +#include <string.h> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc + = (struct _Unwind_Exception *) malloc (sizeof (*exc)); + memset (&exc->exception_class, 0, sizeof (exc->exception_class)); + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +static void handler (void *p __attribute__((unused))) +{ + exit (0); +} + +static void doit () +{ + char dummy __attribute__((cleanup (handler))); + force_unwind (); +} + +int main() +{ + doit (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-6.C b/gcc/testsuite/g++.dg/ext/cleanup-6.C new file mode 100644 index 000000000..4e3d53893 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-6.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ +/* Verify that a cleanup marked "inline" gets inlined. */ + +static inline void xyzzy(void *p __attribute__((unused))) +{ +} + +void doit(void) +{ + int x __attribute__((cleanup (xyzzy))); +} + +/* { dg-final { scan-assembler-not "xyzzy" } } */ diff --git a/gcc/testsuite/g++.dg/ext/cleanup-8.C b/gcc/testsuite/g++.dg/ext/cleanup-8.C new file mode 100644 index 000000000..be6676848 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-8.C @@ -0,0 +1,100 @@ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ +/* Verify that cleanups work with exception handling through signal + frames. */ + +#include <unwind.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc + = (struct _Unwind_Exception *) malloc (sizeof (*exc)); + memset (&exc->exception_class, 0, sizeof (exc->exception_class)); + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +int count; +char *null; + +static void counter (void *p __attribute__((unused))) +{ + ++count; +} + +static void handler (void *p __attribute__((unused))) +{ + if (count != 2) + abort (); + exit (0); +} + +static int __attribute__((noinline)) fn5 () +{ + char dummy __attribute__((cleanup (counter))); + force_unwind (); + return 0; +} + +static void fn4 (int sig) +{ + char dummy __attribute__((cleanup (counter))); + fn5 (); + null = NULL; +} + +static void fn3 () +{ + abort (); +} + +static int __attribute__((noinline)) fn2 () +{ + *null = 0; + fn3 (); + return 0; +} + +static int __attribute__((noinline)) fn1 () +{ + signal (SIGSEGV, fn4); + signal (SIGBUS, fn4); + fn2 (); + return 0; +} + +static int __attribute__((noinline)) fn0 () +{ + char dummy __attribute__((cleanup (handler))); + fn1 (); + null = 0; + return 0; +} + +int main() +{ + fn0 (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-9.C b/gcc/testsuite/g++.dg/ext/cleanup-9.C new file mode 100644 index 000000000..87f828399 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-9.C @@ -0,0 +1,104 @@ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ +/* Verify that cleanups work with exception handling through realtime + signal frames. */ + +#include <unwind.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> + +static _Unwind_Reason_Code +force_unwind_stop (int version, _Unwind_Action actions, + _Unwind_Exception_Class exc_class, + struct _Unwind_Exception *exc_obj, + struct _Unwind_Context *context, + void *stop_parameter) +{ + if (actions & _UA_END_OF_STACK) + abort (); + return _URC_NO_REASON; +} + +static void force_unwind () +{ + struct _Unwind_Exception *exc + = (struct _Unwind_Exception *) malloc (sizeof (*exc)); + memset (&exc->exception_class, 0, sizeof (exc->exception_class)); + exc->exception_cleanup = 0; + +#ifndef __USING_SJLJ_EXCEPTIONS__ + _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); +#else + _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); +#endif + + abort (); +} + +int count; +char *null; + +static void counter (void *p __attribute__((unused))) +{ + ++count; +} + +static void handler (void *p __attribute__((unused))) +{ + if (count != 2) + abort (); + exit (0); +} + +static int __attribute__((noinline)) fn5 () +{ + char dummy __attribute__((cleanup (counter))); + force_unwind (); + return 0; +} + +static void fn4 (int sig, siginfo_t *info, void *ctx) +{ + char dummy __attribute__((cleanup (counter))); + fn5 (); + null = NULL; +} + +static void fn3 () +{ + abort (); +} + +static int __attribute__((noinline)) fn2 () +{ + *null = 0; + fn3 (); + return 0; +} + +static int __attribute__((noinline)) fn1 () +{ + struct sigaction s; + sigemptyset (&s.sa_mask); + s.sa_sigaction = fn4; + s.sa_flags = SA_RESETHAND | SA_SIGINFO; + sigaction (SIGSEGV, &s, NULL); + sigaction (SIGBUS, &s, NULL); + fn2 (); + return 0; +} + +static int __attribute__((noinline)) fn0 () +{ + char dummy __attribute__((cleanup (handler))); + fn1 (); + null = 0; + return 0; +} + +int main() +{ + fn0 (); + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/cleanup-dtor.C b/gcc/testsuite/g++.dg/ext/cleanup-dtor.C new file mode 100644 index 000000000..58da64670 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cleanup-dtor.C @@ -0,0 +1,28 @@ +// Check that destructors are run after cleanup functions. +// { dg-do run } + +extern "C" void abort (); + +int i; + +struct S { + ~S() { + if (i != 1) + abort (); + i = 2; + } +}; + +void f(void *) { + if (i != 0) + abort (); + i = 1; +} + +int main () { + { + S s __attribute__((cleanup (f))); + } + if (i != 2) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/complex1.C b/gcc/testsuite/g++.dg/ext/complex1.C new file mode 100644 index 000000000..ac6771106 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex1.C @@ -0,0 +1,6 @@ +/* { dg-options "" } */ +/* { dg-do compile } */ +// Testing if we can do a new of a complex type +// PR C++/28450 + +void* q = new __complex__ int (); diff --git a/gcc/testsuite/g++.dg/ext/complex2.C b/gcc/testsuite/g++.dg/ext/complex2.C new file mode 100644 index 000000000..c9e8cdce5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex2.C @@ -0,0 +1,5 @@ +// PR c++/31388 +// { dg-options "" } + +bool b = !0i; + diff --git a/gcc/testsuite/g++.dg/ext/complex3.C b/gcc/testsuite/g++.dg/ext/complex3.C new file mode 100644 index 000000000..062c2d44b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex3.C @@ -0,0 +1,28 @@ +// PR c++/31780 +// { dg-do run } +// { dg-options "" } + +// Test that we can implicitly convert to _Complex, but that it's worse +// than a scalar arithmetic conversion. + +extern "C" void exit (int); + +int r = 0; + +void f (_Complex int) { ++r; } +void f (double) { } + +void g (_Complex int) { } + +int main() +{ + f (1); + g (1); + + return r; +} + +void bar() +{ + r ? 0i : 0; +} diff --git a/gcc/testsuite/g++.dg/ext/complex4.C b/gcc/testsuite/g++.dg/ext/complex4.C new file mode 100644 index 000000000..78b935670 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex4.C @@ -0,0 +1,5 @@ +// { dg-do compile } +// This code used to be rejected as there was no conversion from int to float __complex__ + #include <vector> + typedef float __complex__ fcomplex; + std::vector<fcomplex> vfc(10); diff --git a/gcc/testsuite/g++.dg/ext/complex5.C b/gcc/testsuite/g++.dg/ext/complex5.C new file mode 100644 index 000000000..4a29960f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex5.C @@ -0,0 +1,6 @@ +/* PR c++/21210 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef float __complex__ fcomplex; +fcomplex cplx = fcomplex(0); diff --git a/gcc/testsuite/g++.dg/ext/complex6.C b/gcc/testsuite/g++.dg/ext/complex6.C new file mode 100644 index 000000000..9a7c50a7a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex6.C @@ -0,0 +1,10 @@ +// PR c++/46304 +// { dg-options "" } + +template<class T> +void f() +{ + __complex double d = 1.0 + 2.0i; +} + +template void f<int>(); diff --git a/gcc/testsuite/g++.dg/ext/complex7.C b/gcc/testsuite/g++.dg/ext/complex7.C new file mode 100644 index 000000000..9d5463f94 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complex7.C @@ -0,0 +1,6 @@ +// { dg-options "" } + +class A +{ + static const _Complex double x = 1.0 + 2.0i; +}; diff --git a/gcc/testsuite/g++.dg/ext/complit1.C b/gcc/testsuite/g++.dg/ext/complit1.C new file mode 100644 index 000000000..ab2b038fe --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit1.C @@ -0,0 +1,16 @@ +// PR c++/11063 +// { dg-options "" } + +class Foo +{ +private: + const int val_[2]; + +public: + Foo(int, int); +}; + +Foo::Foo(int v0, int v1) + : val_((int[]) {v0, v1}) // { dg-error "" "" } +{ +} diff --git a/gcc/testsuite/g++.dg/ext/complit10.C b/gcc/testsuite/g++.dg/ext/complit10.C new file mode 100644 index 000000000..7f159f0f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit10.C @@ -0,0 +1,20 @@ +// PR c++/36023 +// { dg-do compile } +// { dg-options "" } + +struct A; + +void +f1 (int i) +{ + (int[i]) { 1 }; // { dg-error "variable-sized compound literal" } + (A[5]) { 1 }; // { dg-error "have incomplete type" } + (A[i]) { 1 }; // { dg-error "have incomplete type" } +} + +void +f2 () +{ + (int[]) { 1 }; + (int[1]) { 1 }; +} diff --git a/gcc/testsuite/g++.dg/ext/complit11.C b/gcc/testsuite/g++.dg/ext/complit11.C new file mode 100644 index 000000000..0662543d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit11.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "" } + +struct A { int i; }; + +template<int t> +void foo() +{ + ((struct A) { 0 }).i += 1; // { dg-error "temporary" } +} + +void g(void) +{ + foo<0>(); +} + diff --git a/gcc/testsuite/g++.dg/ext/complit12.C b/gcc/testsuite/g++.dg/ext/complit12.C new file mode 100644 index 000000000..29c9af186 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit12.C @@ -0,0 +1,65 @@ +// PR c++/40948 +// { dg-do run } +// { dg-options "" } + +int c; +struct M +{ + M () { ++c; } + M (const M&) { ++c; } + ~M () { --c; } +}; + +struct S +{ + S (); + M m[1]; +}; + +S::S () : m ((M[1]) { M () }) +{ +} + +struct T +{ + T (); + M m[4]; +}; + +T::T () : m ((M[4]) { M (), M (), M (), M () }) +{ +} + +typedef M MA[1]; +MA &bar (MA, MA& r) { return r; } + +M f(M m) { return m; } + +int main () +{ + { + M m[1] = (M[1]) { M () }; + if (c != 1) + return 1; + M n = (M) { M () }; + if (c != 2) + return 2; + M o[4] = (M[4]) { M (), M (), M (), M () }; + if (c != 6) + return 3; + S s; + if (c != 7) + return 4; + T t; + if (c != 11) + return 5; + MA ma = bar ((M[2]) { M(), M() }, m); + if (c != 12) + return 7; + M mm[2] = ((M[2]) { f(M()), f(M()) }); + if (c != 14) + return 8; + } + if (c != 0) + return 6; +} diff --git a/gcc/testsuite/g++.dg/ext/complit2.C b/gcc/testsuite/g++.dg/ext/complit2.C new file mode 100644 index 000000000..9fe00c42e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit2.C @@ -0,0 +1,22 @@ +// PR c++/12726 +// Origin: Vladimir Zidar <mr_W@mindnever.org> +// Reduced version: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// { dg-options "" } + +struct A +{ + A(); + A(const A&); + A(int); +}; + +struct B +{ + A a; +}; + +void foo() +{ + B b; + b = (B){0}; +} diff --git a/gcc/testsuite/g++.dg/ext/complit3.C b/gcc/testsuite/g++.dg/ext/complit3.C new file mode 100644 index 000000000..a54a8bce1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit3.C @@ -0,0 +1,8 @@ +// { dg-options "" } + +int Compound_Literals_0() +{ + static int y[] = (int []) {1, 2, 3}; // { dg-error "init" } + static int z[] = (int [3]) {1}; // { dg-error "init" } + return y[0]+z[0]; +} diff --git a/gcc/testsuite/g++.dg/ext/complit4.C b/gcc/testsuite/g++.dg/ext/complit4.C new file mode 100644 index 000000000..1448e7a66 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit4.C @@ -0,0 +1,10 @@ +// PR c++/23172 +// { dg-do run } +// { dg-options "" } + +int i = (int) {7}; + +int main () { + if (i != 7) + return 1; +} diff --git a/gcc/testsuite/g++.dg/ext/complit5.C b/gcc/testsuite/g++.dg/ext/complit5.C new file mode 100644 index 000000000..c406c9980 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit5.C @@ -0,0 +1,12 @@ +// PR c++/25417 +// { dg-options "" } + +struct object { + int a; + int b; +}; + +void f (int c, int d) +{ + object o = ((object){ a : c, b : d}); +} diff --git a/gcc/testsuite/g++.dg/ext/complit6.C b/gcc/testsuite/g++.dg/ext/complit6.C new file mode 100644 index 000000000..d3187a65b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit6.C @@ -0,0 +1,19 @@ +// PR c++/20103 +// { dg-options "" } + +struct A +{ + A(const A&); +}; + +struct B +{ + A a; +}; + +void foo(B); + +void bar(A &x) +{ + foo((B){x}); +} diff --git a/gcc/testsuite/g++.dg/ext/complit7.C b/gcc/testsuite/g++.dg/ext/complit7.C new file mode 100644 index 000000000..bceb6d108 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit7.C @@ -0,0 +1,4 @@ +// PR c++/27807 +// { dg-options "" } + +int i = (int()){0}; // { dg-error "type" } diff --git a/gcc/testsuite/g++.dg/ext/complit8.C b/gcc/testsuite/g++.dg/ext/complit8.C new file mode 100644 index 000000000..97ff563fe --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit8.C @@ -0,0 +1,12 @@ +// PR c++/27270 +// { dg-options "" } + +template<typename Entry> +struct Array { + Entry *array[32]; + Array () : + array ( (Entry*[1]) { 0, 0 } ) // { dg-error "initializers|incompatible" } + {} +}; + +Array<void*> a; diff --git a/gcc/testsuite/g++.dg/ext/complit9.C b/gcc/testsuite/g++.dg/ext/complit9.C new file mode 100644 index 000000000..5b7fbe75c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit9.C @@ -0,0 +1,15 @@ +// PR c++/35708 +// { dg-options "" } + +struct object { int one_o; int allocstamp; }; +int pgci_pointable (object obj); +void foo(void); +int main (int argc, char *argv[]) +{ + if (pgci_pointable((object){7,100})) + { + bad_rehash_size: + foo(); + } + goto bad_rehash_size; +} diff --git a/gcc/testsuite/g++.dg/ext/cond1.C b/gcc/testsuite/g++.dg/ext/cond1.C new file mode 100644 index 000000000..ec342121e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/cond1.C @@ -0,0 +1,4 @@ +// PR c++/12515 +// { dg-do compile } +// { dg-options "" } +template<int> void foo() { 0 ?: 0; } diff --git a/gcc/testsuite/g++.dg/ext/construct1.C b/gcc/testsuite/g++.dg/ext/construct1.C new file mode 100644 index 000000000..6a7d8cee4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/construct1.C @@ -0,0 +1,12 @@ +// PR c++/16717 +// { dg-options "-O2" } + +int i; + +void hello (void) __attribute__ ((constructor)); +void hello (void) { i = 1; } + +int main (void) { + if (i != 1) + return 1; +} diff --git a/gcc/testsuite/g++.dg/ext/conv1.C b/gcc/testsuite/g++.dg/ext/conv1.C new file mode 100644 index 000000000..6c16fe484 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/conv1.C @@ -0,0 +1,19 @@ +// Test for backwards brain-damage compatibility with -fpermissive. +// { dg-options "-fpermissive -w" } + +void f (); +void f (int *); +void g (int); + +int main () +{ + void *v = 1234; + void (*p)() = v; + int i = v; + f (i); + f (v); + g (v); + enum { a } b = i; + void (*p2)(int) = p; + unsigned *ip = &i; +} diff --git a/gcc/testsuite/g++.dg/ext/desig1.C b/gcc/testsuite/g++.dg/ext/desig1.C new file mode 100644 index 000000000..c3ff4c142 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/desig1.C @@ -0,0 +1,24 @@ +// { dg-options "" } + +struct a { + int x; +}; + +struct b { + int x; + int y; +}; + +struct foo { + union { + struct a a; + struct b b; + } u; +}; + +int main(void) +{ + struct foo bar = { u: { b: { x: 0, y: 0, }}}; + (void)bar; + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/dll-MI1.h b/gcc/testsuite/g++.dg/ext/dll-MI1.h new file mode 100644 index 000000000..2f8b83669 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dll-MI1.h @@ -0,0 +1,39 @@ +// Class definitions for dllexport-MI1.C and dllimport-MI1.C + +#ifdef BUILDING_MI_DLL +#define DLL_IMPEXP __attribute__ ((dllexport)) +#else +#define DLL_IMPEXP __attribute__ ((dllimport)) +#endif + + +#define D1_return 1 +#define D2_return 2 + +class DLL_IMPEXP MBase +{ +public: + virtual int vf() const = 0; + virtual ~MBase(); +}; + +class DLL_IMPEXP D1 : virtual public MBase +{ +public: + int vf() const; +}; + +class DLL_IMPEXP D2 : virtual public MBase +{ +public: + D2 (); + D2 (D2 const&); + int vf() const; +}; + +class DLL_IMPEXP MI1 : public D1, public D2 +{ +public: + int vf() const; +}; + diff --git a/gcc/testsuite/g++.dg/ext/dllexport-MI1.C b/gcc/testsuite/g++.dg/ext/dllexport-MI1.C new file mode 100644 index 000000000..08e65ec96 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport-MI1.C @@ -0,0 +1,51 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw*} } +// Test that non-virtual MI thunks are exported. + + +// To build the dll and client app: +// g++ -shared -o MI.dll dllexport-MI1.C +// g++ -o MItest.exe dllimport-MI1.C -L. MI.dll + +#define BUILDING_MI_DLL +#include "dll-MI1.h" + +MBase::~MBase(){} + +int D1::vf() const { return D1_return; } + +D2::D2() { } +D2::D2 (D2 const&) { } +int D2::vf() const { return D2_return; } + +int MI1::vf() const { return D1::vf();} + +// a dllexported object +DLL_IMPEXP MI1 dllMI1; + +// use default copy ctor +DLL_IMPEXP MI1 dllMI1Copy = dllMI1; + +// Scan for export of some methods that are undefined in dllimportMI1.C, + +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZNK2D12vfEv" } } +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZNK2D22vfEv" } } +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZNK3MI12vfEv" } } + +// and MI thunks, + +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZThn._NK3MI12vfEv" } } +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZTv0_n.._NK2D12vfEv" } } + +// and a vtable data variable. + +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZTV2D1\[\\\\\"\]*,data" } } + +// an explicit copy ctor +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZN2D2C2ERKS_" } } + +// but not implicit copy ctor generated by compiler +// nor implicit dtor + +// { dg-final { scan-assembler-not "-export:\[\\\\\"\]*_ZN2D1C2ERKS_" } } +// { dg-final { scan-assembler-not "-export:\[\\\\\"\]*_ZN2D1D2Ev" } } + diff --git a/gcc/testsuite/g++.dg/ext/dllexport1.C b/gcc/testsuite/g++.dg/ext/dllexport1.C new file mode 100644 index 000000000..3683d08b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport1.C @@ -0,0 +1,23 @@ +// Test that inline functions are exported with -fkeep-inline-functions. +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw*} } +// { dg-options -fkeep-inline-functions } + +__attribute__((dllexport)) inline int foo (int a) { return a;} + + +class __attribute__((dllexport)) Bar +{ + public: + Bar(){}; + int inline_bar(int a) {return a;} + int outline_bar(int a); +}; + +int Bar::outline_bar(int a) {return foo (a);} + + +Bar abar; + +// { dg-final { scan-assembler "\.section\[ \t\]*.drectve\n.*_ZN3Bar11outline_barEi" } } +// { dg-final { scan-assembler " -export:\[\\\\\"\]*_ZN3Bar10inline_barEi" } } +// { dg-final { scan-assembler " -export:\[\\\\\"\]*_Z3fooi" } } diff --git a/gcc/testsuite/g++.dg/ext/dllexport2.C b/gcc/testsuite/g++.dg/ext/dllexport2.C new file mode 100644 index 000000000..71ccf670b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport2.C @@ -0,0 +1,52 @@ +// { dg-do link } +// { dg-require-dll "" } +// { dg-additional-sources "dllexport2a.cc" } +// { dg-options "-O2" } + +/* Test that inline functions declared "dllexport" appear in object + files, even if they are not called. + + This behavior is required by the ARM C++ ABI: + + Exporting a function that can be inlined should force the + creation and export of an out-of-line copy of it. + + and should presumably also apply. + + Visual Studio 2005 also honors that rule. */ + +__declspec(dllexport) inline void i1() {} + +__declspec(dllexport) extern inline void e1() {} + +/* It is invalid to declare the function inline after its definition. */ +#if 0 +__declspec(dllexport) void i2() {} +inline void i2(); + +__declspec(dllexport) extern void e2() {} +inline void e2(); +#endif + +__declspec(dllexport) inline void i3() {} +void i3(); + +__declspec(dllexport) inline void e3() {} +extern void e3(); + +__declspec(dllexport) void i4(); +inline void i4() {}; + +__declspec(dllexport) extern void e4(); +inline void e4() {}; + +__declspec(dllexport) inline void i5(); +void i5() {}; + +__declspec(dllexport) inline void e5(); +extern void e5() {}; + +/* Make sure that just declaring the function -- without defining it + -- does not cause errors. */ +__declspec(dllexport) inline void i6(); +__declspec(dllexport) extern inline void e6(); diff --git a/gcc/testsuite/g++.dg/ext/dllexport2a.cc b/gcc/testsuite/g++.dg/ext/dllexport2a.cc new file mode 100644 index 000000000..80caf3217 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport2a.cc @@ -0,0 +1,21 @@ +extern void i1(); +extern void i3(); +extern void i4(); +extern void i5(); + +extern void e1(); +extern void e3(); +extern void e4(); +extern void e5(); + +int main () { + i1(); + i3(); + i4(); + i5(); + + e1(); + e3(); + e4(); + e5(); +} diff --git a/gcc/testsuite/g++.dg/ext/dllexport3.C b/gcc/testsuite/g++.dg/ext/dllexport3.C new file mode 100644 index 000000000..206dfc92c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport3.C @@ -0,0 +1,19 @@ +// PR c++/42870 +// { dg-do compile { target i?86-*-cygwin *-*-mingw* } } +// { dg-final { scan-assembler "-export:\[\\\\\"\]*_ZN2SaD1Ev" } } + +#define ATTRIBUTE __attribute__ ((dllexport)) +class ATTRIBUTE Sa { + public: + Sa() + {} + ~Sa(); +}; +ATTRIBUTE Sa::~Sa() +{return;} + +bool DllMain(void *a,void*b,int) +{ + Sa s; + return true; +} diff --git a/gcc/testsuite/g++.dg/ext/dllexport4.C b/gcc/testsuite/g++.dg/ext/dllexport4.C new file mode 100644 index 000000000..81c57c3fb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport4.C @@ -0,0 +1,54 @@ +// { dg-do link } +// { dg-require-dll "" } +// { dg-additional-sources "dllexport4a.cc" } +// { dg-options "-O2 -fno-keep-inline-dllexport" } +// { dg-prune-output .*undefined.* } +// { dg-xfail-if "link failure expected" { *-*-* } } + +/* Test that inline functions declared "dllexport" appear in object files, + even if they are not called - except when -fno-keep-inline-dllexport. + + This behavior is required by the ARM C++ ABI: + + Exporting a function that can be inlined should force the + creation and export of an out-of-line copy of it. + + and should presumably also apply. + + Visual Studio 2005 also honors that rule. */ + +__declspec(dllexport) inline void i1() {} + +__declspec(dllexport) extern inline void e1() {} + +/* It is invalid to declare the function inline after its definition. */ +#if 0 +__declspec(dllexport) void i2() {} +inline void i2(); + +__declspec(dllexport) extern void e2() {} +inline void e2(); +#endif + +__declspec(dllexport) inline void i3() {} +void i3(); + +__declspec(dllexport) inline void e3() {} +extern void e3(); + +__declspec(dllexport) void i4(); +inline void i4() {}; + +__declspec(dllexport) extern void e4(); +inline void e4() {}; + +__declspec(dllexport) inline void i5(); +void i5() {}; + +__declspec(dllexport) inline void e5(); +extern void e5() {}; + +/* Make sure that just declaring the function -- without defining it + -- does not cause errors. */ +__declspec(dllexport) inline void i6(); +__declspec(dllexport) extern inline void e6(); diff --git a/gcc/testsuite/g++.dg/ext/dllexport4a.cc b/gcc/testsuite/g++.dg/ext/dllexport4a.cc new file mode 100644 index 000000000..80caf3217 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport4a.cc @@ -0,0 +1,21 @@ +extern void i1(); +extern void i3(); +extern void i4(); +extern void i5(); + +extern void e1(); +extern void e3(); +extern void e4(); +extern void e5(); + +int main () { + i1(); + i3(); + i4(); + i5(); + + e1(); + e3(); + e4(); + e5(); +} diff --git a/gcc/testsuite/g++.dg/ext/dllexport5.C b/gcc/testsuite/g++.dg/ext/dllexport5.C new file mode 100755 index 000000000..8b2780731 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport5.C @@ -0,0 +1,52 @@ +// { dg-do link } +// { dg-require-dll "" } +// { dg-additional-sources "dllexport5a.cc" } +// { dg-options "-O2 -fkeep-inline-dllexport" } + +/* Test that inline functions declared "dllexport" appear in object files, + even if they are not called, when -fkeep-inline-dllexport is supplied. + + This behavior is required by the ARM C++ ABI: + + Exporting a function that can be inlined should force the + creation and export of an out-of-line copy of it. + + and should presumably also apply. + + Visual Studio 2005 also honors that rule. */ + +__declspec(dllexport) inline void i1() {} + +__declspec(dllexport) extern inline void e1() {} + +/* It is invalid to declare the function inline after its definition. */ +#if 0 +__declspec(dllexport) void i2() {} +inline void i2(); + +__declspec(dllexport) extern void e2() {} +inline void e2(); +#endif + +__declspec(dllexport) inline void i3() {} +void i3(); + +__declspec(dllexport) inline void e3() {} +extern void e3(); + +__declspec(dllexport) void i4(); +inline void i4() {}; + +__declspec(dllexport) extern void e4(); +inline void e4() {}; + +__declspec(dllexport) inline void i5(); +void i5() {}; + +__declspec(dllexport) inline void e5(); +extern void e5() {}; + +/* Make sure that just declaring the function -- without defining it + -- does not cause errors. */ +__declspec(dllexport) inline void i6(); +__declspec(dllexport) extern inline void e6(); diff --git a/gcc/testsuite/g++.dg/ext/dllexport5a.cc b/gcc/testsuite/g++.dg/ext/dllexport5a.cc new file mode 100644 index 000000000..80caf3217 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllexport5a.cc @@ -0,0 +1,21 @@ +extern void i1(); +extern void i3(); +extern void i4(); +extern void i5(); + +extern void e1(); +extern void e3(); +extern void e4(); +extern void e5(); + +int main () { + i1(); + i3(); + i4(); + i5(); + + e1(); + e3(); + e4(); + e5(); +} diff --git a/gcc/testsuite/g++.dg/ext/dllimport-MI1.C b/gcc/testsuite/g++.dg/ext/dllimport-MI1.C new file mode 100644 index 000000000..3f2d05683 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport-MI1.C @@ -0,0 +1,53 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// Test handling of MI thunks in dllimported classes. + +// To build the dll and client app: +// g++ -shared -o MI.dll dllexport-MI1.C +// g++ -o MItest.exe dllimport-MI1.C -L. MI.dll + +#include <stdlib.h> +#include "dll-MI1.h" + +extern DLL_IMPEXP MI1 dllMI1; + +// This should use the implicit copy ctor for D1 (not imported) +// and the explicit copy ctor for D2 (dll-imported). +MI1 dllMI1LocalCopy = dllMI1; + +class MI2 : public D1, public D2 +{ +public: + int vf() const { return D2::vf();} +}; + +class MI3 : public MI1 +{ +}; + +int main () + +{ + MI1 bar1; + MI2 bar2; + MI3 bar3; + + if (dllMI1.vf() != D1_return) + abort(); + + if (dllMI1LocalCopy.vf() != D1_return) + abort(); + + if (bar1.vf() != D1_return) + abort(); + + if (bar2.vf() != (D2_return)) + abort(); + + if (bar3.vf() != D1_return ) + abort(); +} + +// Scan for import of explicit copy ctor for D2, but no import +// of compiler generated copy ctor for D1. +// { dg-final { scan-assembler "__imp\[_\]*__ZN2D2C2ERKS_" } } +// { dg-final { scan-assembler-not "__imp\[_\]*__ZN2D1C2ERKS_" } } diff --git a/gcc/testsuite/g++.dg/ext/dllimport1.C b/gcc/testsuite/g++.dg/ext/dllimport1.C new file mode 100644 index 000000000..d7ddfe8a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport1.C @@ -0,0 +1,31 @@ +// PR c++/7910 +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// { dg-options { -Wall -W } } + +class __attribute__((dllimport)) Foo +{ + public: + virtual void dummy_foo_func(void) + {} + void dummy_foo_fun2(); + virtual ~Foo(); // avoid warning +}; + +void Foo::dummy_foo_fun2() // { dg-warning "redeclared without dllimport" } +{ +} + +class Bar : public Foo +{ +public: + ~Bar(); + void dummy_bar_func(); +}; + +Bar::~Bar() +{} + +void Bar::dummy_bar_func() +{} + +// { dg-final { scan-assembler-not "__imp\[_\]*__ZN3Foo14dummy_foo_fun" } } diff --git a/gcc/testsuite/g++.dg/ext/dllimport10.C b/gcc/testsuite/g++.dg/ext/dllimport10.C new file mode 100644 index 000000000..808337661 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport10.C @@ -0,0 +1,16 @@ +// PR c++/5287, c++/11021 +// Inherit a virtual method from a dllimport'd base class. + +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +struct __attribute__((dllimport)) A +{ + virtual void vfunc(void); +}; + +struct B : public A +{ +}; + + +B aB; diff --git a/gcc/testsuite/g++.dg/ext/dllimport11.C b/gcc/testsuite/g++.dg/ext/dllimport11.C new file mode 100644 index 000000000..6d822be22 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport11.C @@ -0,0 +1,15 @@ +// PR target/23589 +// Template member functions do not get dllimport status of class. +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +struct __attribute__((dllimport)) Foo +{ + template <class T> Foo (T); +}; + +void a (int i) +{ + Foo f(i); +} + +template <class T> Foo::Foo (T) {} // no dllimport warnings on definition. diff --git a/gcc/testsuite/g++.dg/ext/dllimport12.C b/gcc/testsuite/g++.dg/ext/dllimport12.C new file mode 100644 index 000000000..ede546f20 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport12.C @@ -0,0 +1,23 @@ +// PR target/27650 +// Don't use dllimport semantics on virtual methods when initializing +// vtables +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +// Use import lib thunk for vtable entry of explicitly virtual method, +struct base +{ + virtual void key_method(); + __attribute__((dllimport)) virtual ~base(); +}; + +void base::key_method() {} + + +// Likewise for an implicitly virtual method. +struct derived : public base +{ + void key_method(); + __attribute__((dllimport)) ~derived(); +}; + +void derived::key_method() {} diff --git a/gcc/testsuite/g++.dg/ext/dllimport13.C b/gcc/testsuite/g++.dg/ext/dllimport13.C new file mode 100644 index 000000000..fa1ffbfdb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport13.C @@ -0,0 +1,14 @@ +// PR c++/34749 +// Ensure dllimport is handled correctly for friends + +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +int __declspec (dllimport) bar(); +int __declspec (dllimport) baz(); + +class Foo +{ +// MS requires that the dllimport attribute be specified on each declaration + friend int __declspec (dllimport) bar(); + friend int baz(); // { dg-warning "dllimport ignored" } +}; diff --git a/gcc/testsuite/g++.dg/ext/dllimport2.C b/gcc/testsuite/g++.dg/ext/dllimport2.C new file mode 100644 index 000000000..d0de2551a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport2.C @@ -0,0 +1,28 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// PR c++/9738 Dllimport attribute is overriden by later definition/redeclaration + +void __attribute__((dllimport)) Bar(void); +void __attribute__((dllimport)) Baz(void); +__attribute__((dllimport)) int Biz; +__attribute__((dllimport)) int Boz; + + +void Foo(void) + { + Bar(); + Baz(); + Biz++; + Boz++; + } + +void Baz(void); // { dg-warning "referenced with dll linkage" } +void Bar(void) // { dg-warning "referenced with dll linkage" } + { + } +extern int Biz; // { dg-warning "referenced with dll linkage" } +int Boz; // { dg-warning "referenced with dll linkage" } + +void foo() +{ + Biz++; +} diff --git a/gcc/testsuite/g++.dg/ext/dllimport3.C b/gcc/testsuite/g++.dg/ext/dllimport3.C new file mode 100644 index 000000000..6538232f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport3.C @@ -0,0 +1,24 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +// PR 10148 Dllimport attribute of object is overriden by later +// redefinition without attribute. + +struct Foo +{ + int a; +}; + + __attribute__((dllimport)) struct Foo f; + +void Bar(void) +{ + void* dummy = (void*) &f; +} + +struct Foo f; // { dg-warning "referenced with dll linkage" } + +// Dllimport'd symbols do not have a constant address, so following +// assignment would require static_initialization_and_destruction +// if attribute is retained. + +void* dummy = &f; diff --git a/gcc/testsuite/g++.dg/ext/dllimport4.C b/gcc/testsuite/g++.dg/ext/dllimport4.C new file mode 100644 index 000000000..4d4074cbb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport4.C @@ -0,0 +1,38 @@ +// Report error if dllimport attribute in definition itself. +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +__attribute__((dllimport)) void bar () { } // { dg-error "definition" } + +__attribute__((dllimport)) int foo = 1; // { dg-error "definition" } + +void faz() +{ + __attribute__((dllimport)) int faa = 1; // { dg-error "definition" } + faa++; +} + +__attribute__((dllimport)) int fee (1); // { dg-error "definition" } + + +// In-class initialization of a static data member is not a definition. +struct F +{ + __attribute__ ((dllimport)) static const int i = 1; // OK +}; + +// Reference the dllimport'd static data member. +void f () +{ + const int* j = &F::i; +} + +struct G +{ + __attribute__ ((dllimport)) static const int i = 1; +}; + +// Define the static data member _without_ the dllimport. +// This should override the prior declaration with dllimport. + +const int G::i; // { dg-warning "dllimport ignored" } + diff --git a/gcc/testsuite/g++.dg/ext/dllimport5.C b/gcc/testsuite/g++.dg/ext/dllimport5.C new file mode 100644 index 000000000..5f1adb1ac --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport5.C @@ -0,0 +1,28 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// Report error if static symbol definition has dllimport attribute. + +__attribute__((dllimport)) + int impvar; // OK, implicit "extern" + + static __attribute__((dllimport)) + int static_impvar; // { dg-error "external linkage" } + + static __attribute__((dllexport)) +int static_expvar; // { dg-error "external linkage" } + +static __attribute__((dllimport)) +void static_impfun(void); // { dg-error "external linkage" } + +void foo() +{ + __attribute__((dllimport)) + int foovar; // OK, implicit "extern" + foovar++; +} + +void bar() +{ + __attribute__((dllexport)) + int barvar; // { dg-error "external linkage" } + barvar++; +} diff --git a/gcc/testsuite/g++.dg/ext/dllimport6.C b/gcc/testsuite/g++.dg/ext/dllimport6.C new file mode 100644 index 000000000..52b0476c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport6.C @@ -0,0 +1,30 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// Mark class static members as dllimport. + +struct Baz +{ + Baz(int a_ =0) : a(a_) {} + int a; +}; + +class __attribute__ ((dllimport)) Bar +{ + public: + static const int two = 2; + static const int three; + static const Baz null_baz; +}; + +int foo() +{ + Bar foobar; + const int* baz = &Bar::two; + int a = foobar.two; + int b = foobar.three; + int c = foobar.null_baz.a; + return (a + b + c + *baz); +} + +// { dg-final { scan-assembler __imp\[_\]*__ZN3Bar3twoE } } +// { dg-final { scan-assembler __imp\[_\]*__ZN3Bar5threeE } } +// { dg-final { scan-assembler __imp\[_\]*__ZN3Bar8null_bazE } } diff --git a/gcc/testsuite/g++.dg/ext/dllimport7.C b/gcc/testsuite/g++.dg/ext/dllimport7.C new file mode 100644 index 000000000..0a79b3da3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport7.C @@ -0,0 +1,34 @@ +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } + +// Report errors on definition of dllimport'd static data member . + + +struct Baz +{ + Baz(int a_ =0) : a(a_) {} + int a; +}; + +class __declspec(dllimport) Bar +{ + public: + enum {one = 1}; + static const int two = 2; + static const int three; + static const Baz null_baz; +}; + +const int Bar::three = 3; // { dg-warning "redeclared without dllimport" } +// { dg-error "definition of static data" "C++ specific error" { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } 21 } + +const Baz Bar::null_baz; // { dg-warning "redeclared without dllimport" } + +int foo() +{ + Bar foobar; + const int* baz = &Bar::two; + int a = foobar.two; + int b = foobar.three; + int c = foobar.null_baz.a; + return (a + b + c + *baz); +} diff --git a/gcc/testsuite/g++.dg/ext/dllimport8.C b/gcc/testsuite/g++.dg/ext/dllimport8.C new file mode 100644 index 000000000..af605a368 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport8.C @@ -0,0 +1,29 @@ +// PR c++/8378 +// Ignore dllimport of static members if marked inlined. +// or if definition follows declaration in dllimported class. + +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// { dg-options { -Wall -W } } + +struct __attribute__((dllimport)) Foo +{ + static int static_int; + static void static_func1(); + static void static_func2(); + }; + +void Foo::static_func1() // { dg-warning "redeclared without dllimport" } +{ +} + +inline void Foo::static_func2() +{ +} + +void testfoo() +{ + Foo::static_func1(); + Foo::static_func2(); +} + +// { dg-final { scan-assembler-not "__imp_" } } diff --git a/gcc/testsuite/g++.dg/ext/dllimport9.C b/gcc/testsuite/g++.dg/ext/dllimport9.C new file mode 100644 index 000000000..da57ef4bd --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/dllimport9.C @@ -0,0 +1,23 @@ +// Handle dllimport attribute for functions declared inline. +// { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* x86_64-*-mingw* } } +// { dg-options { -W } } + +inline __attribute__((dllimport)) void bar() { } // { dg-warning "inline" } + +struct __attribute__ ((dllimport)) Blah +{ + void in_blah () { } // Don't warn if member declared inline in class definition. + void out_blah (); +}; + +inline void Blah::out_blah(){ } // Don't warn for inline override of external declaration + +void use_inlines() +{ + Blah aBlah; + bar(); + aBlah.in_blah (); + aBlah.out_blah (); +} + +// { dg-final { scan-assembler-not "__imp_" } } diff --git a/gcc/testsuite/g++.dg/ext/fixed1.C b/gcc/testsuite/g++.dg/ext/fixed1.C new file mode 100644 index 000000000..5a479d689 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/fixed1.C @@ -0,0 +1,8 @@ +// PR c++/35325 +// { dg-options "" } + +template<int> struct A {}; + +template<typename> struct B : A<sizeof(0=0r)> {}; // { dg-error "not supported" } + +template<typename> struct C : A<sizeof(0=0r)> {}; // { dg-error "not supported" } diff --git a/gcc/testsuite/g++.dg/ext/fixed2.C b/gcc/testsuite/g++.dg/ext/fixed2.C new file mode 100644 index 000000000..1ee5538a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/fixed2.C @@ -0,0 +1,7 @@ +// PR c++/35319 +// { dg-options "" } + +void foo() +{ + throw 0r; // { dg-error "not supported" } +} diff --git a/gcc/testsuite/g++.dg/ext/flexary1.C b/gcc/testsuite/g++.dg/ext/flexary1.C new file mode 100644 index 000000000..4033e339d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary1.C @@ -0,0 +1,33 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com> + +// PR c++ 11614 + +typedef int ary_t[]; + +struct test +{ + ary_t *b; + int (*a)[]; // this is not a flexible array member +}; + +void test(void) +{ + struct test s; + int (*a)[] = 0; + ary_t *b = 0; + + a = s.a; + a = s.b; + + s.a = a; + s.b = a; + + b = s.a; + b = s.b; + + s.a = b; + s.b = b; +} diff --git a/gcc/testsuite/g++.dg/ext/flexary2.C b/gcc/testsuite/g++.dg/ext/flexary2.C new file mode 100644 index 000000000..4855b3f57 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary2.C @@ -0,0 +1,11 @@ +// PR c++/46688 +// { dg-options "" } + +struct A { + A(int); +}; + +struct B { + B() {} + A a[]; +}; diff --git a/gcc/testsuite/g++.dg/ext/fnname1.C b/gcc/testsuite/g++.dg/ext/fnname1.C new file mode 100644 index 000000000..521d5a736 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/fnname1.C @@ -0,0 +1,26 @@ +// Test whether __func__ works for namespace-scope C++ functions. + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Matt Austern <austern@apple.com>, 3 Aug 2003 +// { dg-do run } + +namespace xyzzy +{ + const char* ab6(double, void*) + { + return __func__; + } +} + +int main() +{ + const char* s = xyzzy::ab6(2.3, (void*) 0); + bool ok = true; + + ok = ok && s[0] == 'a'; + ok = ok && s[1] == 'b'; + ok = ok && s[2] == '6'; + ok = ok && s[3] == '\0'; + + return ok ? 0 : 1; +} diff --git a/gcc/testsuite/g++.dg/ext/fnname2.C b/gcc/testsuite/g++.dg/ext/fnname2.C new file mode 100644 index 000000000..ea0c1826f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/fnname2.C @@ -0,0 +1,31 @@ +// Test whether __func__ works for ordinary member functions. + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Matt Austern <austern@apple.com>, 3 Aug 2003 +// { dg-do run } + +struct y8a +{ + const char* zqjx(int, char); +}; + +const char* y8a::zqjx(int, char) +{ + return __func__; +} + + +int main() +{ + y8a tmp; + const char* s = tmp.zqjx(16, 'x'); + bool ok = true; + + ok = ok && s[0] == 'z'; + ok = ok && s[1] == 'q'; + ok = ok && s[2] == 'j'; + ok = ok && s[3] == 'x'; + ok = ok && s[4] == '\0'; + + return ok ? 0 : 1; +} diff --git a/gcc/testsuite/g++.dg/ext/fnname3.C b/gcc/testsuite/g++.dg/ext/fnname3.C new file mode 100644 index 000000000..c29170a9a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/fnname3.C @@ -0,0 +1,65 @@ +// Test whether __func__ works for constructors and destructors. + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Matt Austern <austern@apple.com>, 3 Aug 2003 +// { dg-do run } + +struct uk9i +{ + uk9i(); + ~uk9i(); + + static const char* fname; + static bool obj_exists; +}; + +uk9i::uk9i() +{ + obj_exists = true; + fname = __func__; +} + +uk9i::~uk9i() +{ + obj_exists = false; + fname = __func__; +} + +const char* uk9i::fname = 0; +bool uk9i::obj_exists = false; + +int main() +{ + bool ok = true; + + ok = ok && uk9i::fname == 0; + ok = ok && !uk9i::obj_exists; + + { + uk9i tmp; + ok = ok && uk9i::obj_exists; + ok = ok && uk9i::fname != 0; + if (ok) + { + ok = ok && uk9i::fname[0] == 'u'; + ok = ok && uk9i::fname[1] == 'k'; + ok = ok && uk9i::fname[2] == '9'; + ok = ok && uk9i::fname[3] == 'i'; + ok = ok && uk9i::fname[4] == '\0'; + } + } + + ok = ok && !uk9i::obj_exists; + ok = ok && uk9i::fname != 0; + if (ok) + { + ok = ok && uk9i::fname[0] == '~'; + ok = ok && uk9i::fname[1] == 'u'; + ok = ok && uk9i::fname[2] == 'k'; + ok = ok && uk9i::fname[3] == '9'; + ok = ok && uk9i::fname[4] == 'i'; + ok = ok && uk9i::fname[5] == '\0'; + } + + return ok ? 0 : 1; +} diff --git a/gcc/testsuite/g++.dg/ext/forscope1.C b/gcc/testsuite/g++.dg/ext/forscope1.C new file mode 100644 index 000000000..fa6401a3b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/forscope1.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options -fno-for-scope } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 4 Sept 2001 <nathan@codesourcery.com> + +// Bug 4206. We were nesting SCOPE_STMTs badly. + + +struct A +{ + A (); + ~A (); +}; + + +void Go( ) +{ + for (int i = 1;;) + { + switch (1) { + default: {} + } + A d; + } + i; +} diff --git a/gcc/testsuite/g++.dg/ext/forscope2.C b/gcc/testsuite/g++.dg/ext/forscope2.C new file mode 100644 index 000000000..b883effb2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/forscope2.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options -fpermissive } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 4 Sept 2001 <nathan@codesourcery.com> + +// Bug 4206. We were nesting SCOPE_STMTs badly. + + +struct A +{ + A (); + ~A (); +}; + + +void Go( ) +{ + for (int i = 1;;) // { dg-warning "using obsolete binding" "" } + { + switch (1) { + default: {} + } + A d; + } + i; // { dg-warning "name lookup" "" } +} diff --git a/gcc/testsuite/g++.dg/ext/fpreg1.C b/gcc/testsuite/g++.dg/ext/fpreg1.C new file mode 100644 index 000000000..c5170a4a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/fpreg1.C @@ -0,0 +1,82 @@ +// Test permitted and invalid uses of __fpreg, for C++. +// Origin: Joseph Myers <joseph@codesourcery.com> +// { dg-do compile { target ia64-*-* } } +// { dg-options "" } + +__float80 f80; +double d; +// Default initialized __fpreg is OK. +__fpreg fpreg, fpreg2; +// But explicitly zero-initialized is an invalid conversion. +__fpreg fi = 0; // { dg-error "invalid conversion to '__fpreg'" } + +__fpreg f0 (__fpreg); +int f1 (__float80); + +// __fpreg in a structure is OK. +struct s { + __float80 b; + __fpreg a; +} x; + +void +f (void) +{ + __fpreg *p; + // Valid operations. + fpreg = fpreg2; + fpreg2 = (__fpreg) fpreg; + fpreg = f0 (fpreg2); + fpreg = +fpreg2; + p = &fpreg; + (void) fpreg; + fpreg = x.a; + fpreg2 = (struct s) { 0 }.a; + fpreg = (d ? fpreg : fpreg2); + d = sizeof (fpreg); + (void)(fpreg, fpreg); + // Invalid operations. + ++fpreg; // { dg-error "invalid operation on '__fpreg'" } + --fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg++; // { dg-error "invalid operation on '__fpreg'" } + fpreg--; // { dg-error "invalid operation on '__fpreg'" } + fpreg = -fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = ~fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = !fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = *fpreg; // { dg-error "invalid type argument" } + if (fpreg) // { dg-error "invalid conversion from '__fpreg'" } + return; + d = fpreg; // { dg-error "invalid conversion from '__fpreg'" } + d = (double) fpreg; // { dg-error "invalid conversion from '__fpreg'" } + fpreg = (__fpreg) d; // { dg-error "invalid conversion to '__fpreg'" } + fpreg = fpreg * fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = fpreg / fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = fpreg % fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = fpreg + fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = fpreg - fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = fpreg << fpreg; // { dg-error "invalid operation on '__fpreg'" } + fpreg = fpreg >> fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg < fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg > fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg <= fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg >= fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg == fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg != fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg & fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg ^ fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg | fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg && fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = fpreg || fpreg; // { dg-error "invalid operation on '__fpreg'" } + d = (fpreg ? 1 : 2); // { dg-error "invalid conversion from '__fpreg'" } + fpreg = (d ? fpreg : d); // { dg-error "invalid conversion to '__fpreg'" } + fpreg *= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg /= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg %= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg += fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg -= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg <<= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg >>= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg &= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg ^= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } + fpreg |= fpreg; // { dg-error "invalid operation on '__fpreg'|in evaluation" } +} diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-anon-namespace.C b/gcc/testsuite/g++.dg/ext/gnu-inline-anon-namespace.C new file mode 100644 index 000000000..b33629dcf --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-anon-namespace.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler-not "func1" } } */ +/* { dg-final { scan-assembler-not "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler-not "func4" } } */ +/* { dg-final { scan-assembler-not "func5" } } */ + +namespace { +#include "gnu-inline-global.C" +} diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-class-static.C b/gcc/testsuite/g++.dg/ext/gnu-inline-class-static.C new file mode 100644 index 000000000..f22a23c0b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-class-static.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler "func5" } } */ + +#undef IN_CLASS +#define IN_CLASS gnu_test_static + +struct IN_CLASS { + static int func1(void); + static int func2(void); + static int func3(void); + static int func4(void); + static int func5(void); +}; + +#include "gnu-inline-global.C" diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-class.C b/gcc/testsuite/g++.dg/ext/gnu-inline-class.C new file mode 100644 index 000000000..71a0b1e36 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-class.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler "func5" } } */ + +#define IN_CLASS gnu_test + +struct IN_CLASS { + int func1(void); + int func2(void); + int func3(void); + int func4(void); + int func5(void); +}; + +#include "gnu-inline-global.C" diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-common.h b/gcc/testsuite/g++.dg/ext/gnu-inline-common.h new file mode 100644 index 000000000..87455ae7a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-common.h @@ -0,0 +1,24 @@ +#ifndef gnu +# define gnu_inline __attribute__((gnu_inline)) inline +#endif + +#define declspec(spec, name) spec int name (void) +#ifdef IN_CLASS +# define decl(spec, name) +#else +# define decl(spec, name) defpfx declspec(spec, name); +#endif +#define def(spec, name, ret) defpfx declspec(spec, name) { return ret; } +#define gnuindef(name, ret) def(gnu_inline, name, ret) + +#ifndef pfx +# ifdef IN_CLASS +# define pfx(x) IN_CLASS::x +# else +# define pfx(x) x +# endif +#endif + +#ifndef defpfx +# define defpfx +#endif diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C new file mode 100644 index 000000000..fc72d26fb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C @@ -0,0 +1,19 @@ +/* Test __attribute__((gnu_inline)). + + Check that we don't get out-of-line definitions for extern inline + gnu_inline functions, regardless of redeclaration. + + */ + +/* { dg-do link } */ +/* { dg-options "-O" } */ // such that static functions are optimized out + +#include "gnu-inline-common.h" + +decl(extern, fn) +gnuindef(fn, 0) +decl(extern, fn) + +int main () { + fn (); +} diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C new file mode 100644 index 000000000..d9e266095 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C @@ -0,0 +1,56 @@ +/* Test __attribute__((gnu_inline)). + + Check that we reject various forms of duplicate definitions. +*/ + +/* { dg-do compile } */ +/* { dg-options " -ansi -Wno-long-long" } */ + +#include "gnu-inline-common.h" + +#undef fn +#define fn pfx(func_decl_inline_before) +decl(inline, fn) // { dg-error "previous" "" } +gnuindef(fn, 0) // { dg-error "redeclared" "" } + +#undef fn +#define fn pfx(func_decl_inline_after) +gnuindef(fn, 0) // { dg-error "previous" "" } +decl(inline, fn) // { dg-error "redeclared" "" } + +#undef fn +#define fn pfx(func_def_gnuin_redef) +gnuindef(fn, 0) // { dg-error "previous" "" } +gnuindef(fn, 1) // { dg-error "redefinition" "" } + +#undef fn +#define fn pfx(func_def_inline_redef) +def(inline, fn, 0) // { dg-error "previous" "" } +def(inline, fn, 1) // { dg-error "redefinition" "" } + +#undef fn +#define fn pfx(func_def_inline_after) +gnuindef(fn, 0) // { dg-error "previous" "" } +def(inline, fn, 1) // { dg-error "redeclare" "" } + +#undef fn +#define fn pfx(func_def_inline_before) +def(inline, fn, 0) // { dg-error "previous" "" } +gnuindef(fn, 1) // { dg-error "redefinition" "" } + +#undef fn +#define fn pfx(func_def_before) +def(, fn, 0) // { dg-error "previous" "" } +gnuindef(fn, 1) // { dg-error "redefinition" "" } + +#undef fn +#define fn pfx(func_decl_static_inline_before) +decl(static inline, fn) // { dg-error "previous" "" } +gnuindef(fn, 0) // { dg-error "redeclared" "" } + +#undef fn +#define fn pfx(func_def_static_inline_after) +decl(static, fn) +gnuindef(fn, 0) // { dg-error "previous" "" } +decl(static, fn) +def(static inline, fn, 1) // { dg-error "redeclare" "" } diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global.C new file mode 100644 index 000000000..f628073f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-global.C @@ -0,0 +1,50 @@ +/* Test __attribute__((gnu_inline)). + + Check that __attribute__((gnu_inline)) has no effect, in the + absence of extern and/or inline. + + Check that we don't get out-of-line definitions for extern inline + gnu_inline functions, regardless of declarations or definitions. + + Check that such functions can be overridden by out-of-line + definitions. + + */ + +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler-not "func5" } } */ + +#include "gnu-inline-common.h" + +#undef fn +#define fn pfx(func1) // must be emitted out-of-line +gnuindef(fn, 0) +def(, fn, 2) + +#undef fn +#define fn pfx(func2) // must be emitted out-of-line +decl(extern, fn) +gnuindef(fn, 0) +def(, fn, 2) + +#undef fn +#define fn pfx(func3) // must not be emitted +decl(extern, fn) +gnuindef(fn, 0) + +#undef fn +#define fn pfx(func4) // must be emitted out-of-line +decl(extern, fn) +gnuindef(fn, 0) +def(, fn, 1) + +#undef fn +#define fn pfx(func5) // must NOT be emitted, because it's static and unused +decl(static, fn) +gnuindef(fn, 0) +def(, fn, 1) diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-namespace.C b/gcc/testsuite/g++.dg/ext/gnu-inline-namespace.C new file mode 100644 index 000000000..ce3fea655 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-namespace.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler-not "func5" } } */ + +namespace gnu_test { +#include "gnu-inline-global.C" +} diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-template-class.C b/gcc/testsuite/g++.dg/ext/gnu-inline-template-class.C new file mode 100644 index 000000000..9bf36a8d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-template-class.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler "func5" } } */ + +template <typename T> struct gnu_test { + int func1(void); + int func2(void); + int func3(void); + int func4(void); + int func5(void); +}; + +#define defpfx template <typename T> +#define IN_CLASS gnu_test<T> + +#include "gnu-inline-global.C" + +template struct gnu_test<int>; diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-template-func.C b/gcc/testsuite/g++.dg/ext/gnu-inline-template-func.C new file mode 100644 index 000000000..fb88a2a91 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/gnu-inline-template-func.C @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ // such that static functions are optimized out +/* { dg-final { scan-assembler "func1" } } */ +/* { dg-final { scan-assembler "func2" } } */ +/* { dg-final { scan-assembler-not "func3" } } */ +/* { dg-final { scan-assembler "func4" } } */ +/* { dg-final { scan-assembler-not "func5" } } */ + +#define defpfx template <typename T> + +#include "gnu-inline-global.C" + +template int func1<int>(void); +template int func2<int>(void); +template int func3<int>(void); +template int func4<int>(void); +template int func5<int>(void); diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C b/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C new file mode 100644 index 000000000..e6e9fc6ed --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C @@ -0,0 +1,152 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +struct B +{ + A a; +}; + +struct C +: public A { }; + +struct D +{ + D& operator=(const D&) throw() { return *this; } +}; + +struct E +{ + E& operator=(const E&) throw(int) { return *this; } +}; + +struct E1 +{ + E1& operator=(const E1&) throw(int) { throw int(); return *this; } +}; + +struct F +{ + F() throw(int) { } +}; + +struct G +{ + G() throw(int) { throw int(); } +}; + +struct H +{ + H& operator=(H&) throw(int) { return *this; } +}; + +struct H1 +{ + H1& operator=(H1&) throw(int) { throw int(); return *this; } +}; + +struct I +{ + I& operator=(I&) throw(int) { return *this; } + I& operator=(const I&) throw() { return *this; } +}; + +struct I1 +{ + I1& operator=(I1&) throw(int) { throw int(); return *this; } + I1& operator=(const I1&) throw() { return *this; } +}; + +struct J +{ + J& operator=(J&) throw() { return *this; } + J& operator=(const J&) throw() { return *this; } + J& operator=(volatile J&) throw() { return *this; } + J& operator=(const volatile J&) throw() { return *this; } +}; + +struct K +{ + K& operator=(K&) throw() { return *this; } +}; + +struct L +{ + L& operator=(const L&) throw() { return *this; } +}; + +template<typename T> + bool + f() + { return __has_nothrow_assign(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_nothrow_assign(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_nothrow_assign(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_nothrow_assign(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_nothrow_assign(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_nothrow_assign(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (B)); + assert (PTEST (C)); + assert (PTEST (C[])); + assert (PTEST (D)); + assert (NTEST (E)); + assert (NTEST (E1)); + assert (PTEST (F)); + assert (PTEST (G)); + assert (NTEST (H)); + assert (NTEST (H1)); + assert (NTEST (I)); + assert (NTEST (I1)); + assert (PTEST (J)); + assert (NTEST (const K)); + assert (NTEST (const L)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C b/gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C new file mode 100644 index 000000000..c2e99ef54 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C @@ -0,0 +1,16 @@ +// PR c++/36870 +// { dg-do run } +#include <cassert> + +struct S { const S& operator= (const S&); }; + +bool f (); + +int main () +{ + assert (__has_nothrow_assign (S) == f ()); +} + +const S& S::operator= (const S&) { } + +bool f () { return __has_nothrow_assign (S); } diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C new file mode 100644 index 000000000..1f1227c30 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C @@ -0,0 +1,106 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +struct B +{ + A a; +}; + +struct C +: public A { }; + +struct D +{ + D() throw() { } +}; + +struct E +{ + E() throw(int) { } +}; + +struct E1 +{ + E1() throw(int) { throw int(); } +}; + +struct F +{ + F(const F&) throw() { } +}; + +struct G +{ + G(const G&) throw(int) { throw int(); } +}; + +template<typename T> + bool + f() + { return __has_nothrow_constructor(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_nothrow_constructor(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_nothrow_constructor(T); + }; + +template<typename T> + const bool My2<T>::trait; + + +template<typename T, bool b = __has_nothrow_constructor(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_nothrow_constructor(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_nothrow_constructor(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (B)); + assert (PTEST (C)); + assert (PTEST (C[])); + assert (PTEST (D)); + assert (NTEST (E)); + assert (NTEST (E1)); + assert (NTEST (F)); + assert (NTEST (G)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C new file mode 100644 index 000000000..68ca111b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C @@ -0,0 +1,16 @@ +// PR c++/36870 +// { dg-do run } +#include <cassert> + +struct S { S (); }; + +bool f (); + +int main () +{ + assert (__has_nothrow_constructor (S) == f ()); +} + +S::S () { } + +bool f () { return __has_nothrow_constructor (S); } diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C new file mode 100644 index 000000000..87785ae5a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C @@ -0,0 +1,140 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +struct B +{ + A a; +}; + +struct C +: public A { }; + +struct D +{ + D(const D&) throw() { } +}; + +struct E +{ + E(const E&) throw(int) { } +}; + +struct E1 +{ + E1(const E1&) throw(int) { throw int(); } +}; + +struct F +{ + F() throw() { } +}; + +struct G +{ + G() throw(int) { throw int(); } +}; + +struct H +{ + H(H&) throw(int) { } +}; + +struct H1 +{ + H1(H1&) throw(int) { throw int(); } +}; + +struct I +{ + I(I&) throw(int) { } + I(const I&) throw() { } +}; + +struct I1 +{ + I1(I1&) throw(int) { throw int(); } + I1(const I1&) throw() { } +}; + +struct J +{ + J(J&) throw() { } + J(const J&) throw() { } + J(volatile J&) throw() { } + J(const volatile J&) throw() { } +}; + +template<typename T> + bool + f() + { return __has_nothrow_copy(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_nothrow_copy(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_nothrow_copy(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_nothrow_copy(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_nothrow_copy(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_nothrow_copy(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (B)); + assert (PTEST (C)); + assert (PTEST (C[])); + assert (PTEST (D)); + assert (NTEST (E)); + assert (NTEST (E1)); + assert (PTEST (F)); + assert (PTEST (G)); + assert (NTEST (H)); + assert (NTEST (H1)); + assert (NTEST (I)); + assert (NTEST (I1)); + assert (PTEST (J)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C new file mode 100644 index 000000000..b2eb203f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C @@ -0,0 +1,12 @@ +// PR c++/36871 +// { dg-do run } +#include <cassert> + +struct A { template <class T> A (T) throw (int); }; +struct B { B (B&) throw (); template <class T> B (T) throw (int); }; + +int main () +{ + assert (__has_nothrow_copy (A)); + assert (__has_nothrow_copy (B)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C new file mode 100644 index 000000000..797004410 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C @@ -0,0 +1,13 @@ +// PR c++/36871 +// { dg-do run } +#include <cassert> + +struct F { + F (const F&) throw () { } + template <class T> F (T) throw () { } +}; + +int main () +{ + assert (__has_nothrow_copy (F)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C new file mode 100644 index 000000000..69e9a6bac --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C @@ -0,0 +1,13 @@ +// PR c++/36872 +// { dg-do run } +#include <cassert> + +struct S { + S (const S&) throw (); + S (...) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C new file mode 100644 index 000000000..b94b338c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C @@ -0,0 +1,13 @@ +// PR c++/36872 +// { dg-do run } +#include <cassert> + +struct S { + S (const S&) throw (); + S (int) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C new file mode 100644 index 000000000..6268ee292 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C @@ -0,0 +1,12 @@ +// { dg-do run } +#include <cassert> + +struct S { + S (S&) throw (); + S (const S&, int) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C new file mode 100644 index 000000000..e0ecef44a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C @@ -0,0 +1,13 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } +#include <cassert> + +struct S { + S (const S&) throw (); + S (S&&) throw (int); +}; + +int main () +{ + assert (__has_nothrow_copy (S)); +} diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C new file mode 100644 index 000000000..573fd2f80 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C @@ -0,0 +1,16 @@ +// PR c++/36870 +// { dg-do run } +#include <cassert> + +struct S { S (const S&); }; + +bool f (); + +int main () +{ + assert (__has_nothrow_copy (S) == f ()); +} + +S::S (const S&) { } + +bool f () { return __has_nothrow_copy (S); } diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_assign.C b/gcc/testsuite/g++.dg/ext/has_trivial_assign.C new file mode 100644 index 000000000..dce0f8b3a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_trivial_assign.C @@ -0,0 +1,106 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +union U +{ + double a; + double b; +}; + +struct B +{ + B& operator=(const B&) { return *this;} +}; + +struct C +{ + virtual int f() { return 1; } +}; + +struct D +: public B { }; + +struct E +: public A { }; + +struct F +{ + A a; +}; + +struct G +{ + B b; +}; + +template<typename T> + bool + f() + { return __has_trivial_assign(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_trivial_assign(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_trivial_assign(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_trivial_assign(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_trivial_assign(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_trivial_assign(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (U)); + assert (NTEST (B)); + assert (NTEST (C)); + assert (NTEST (D)); + assert (PTEST (E)); + assert (PTEST (E[])); + assert (PTEST (F)); + assert (NTEST (G)); + assert (NTEST (const A)); + assert (NTEST (A&)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_constructor.C b/gcc/testsuite/g++.dg/ext/has_trivial_constructor.C new file mode 100644 index 000000000..f4addd824 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_trivial_constructor.C @@ -0,0 +1,98 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +union U +{ + double a; + double b; +}; + +struct B +{ + B() { } +}; + +struct C +: public B { }; + +struct D +: public A { }; + +struct E +{ + A a; +}; + +struct F +{ + B b; +}; + +template<typename T> + bool + f() + { return __has_trivial_constructor(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_trivial_constructor(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_trivial_constructor(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_trivial_constructor(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_trivial_constructor(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_trivial_constructor(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (U)); + assert (NTEST (B)); + assert (NTEST (C)); + assert (PTEST (D)); + assert (PTEST (D[])); + assert (PTEST (E)); + assert (NTEST (F)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_copy.C b/gcc/testsuite/g++.dg/ext/has_trivial_copy.C new file mode 100644 index 000000000..4d2341b17 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_trivial_copy.C @@ -0,0 +1,105 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +union U +{ + double a; + double b; +}; + +struct B +{ + B(const B&) { } +}; + +struct C +{ + virtual int f() { return 1; } +}; + +struct D +: public B { }; + +struct E +: public A { }; + +struct F +{ + A a; +}; + +struct G +{ + B b; +}; + +template<typename T> + bool + f() + { return __has_trivial_copy(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_trivial_copy(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_trivial_copy(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_trivial_copy(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_trivial_copy(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_trivial_copy(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (U)); + assert (NTEST (B)); + assert (NTEST (C)); + assert (NTEST (D)); + assert (PTEST (E)); + assert (PTEST (E[])); + assert (PTEST (F)); + assert (NTEST (G)); + assert (PTEST (B&)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_destructor-1.C b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-1.C new file mode 100644 index 000000000..2834c238d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-1.C @@ -0,0 +1,86 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +union U +{ + double a; + double b; +}; + +struct B +{ + ~B() { } +}; + +struct C +: public B { }; + +struct D +: public A { }; + +template<typename T> + bool + f() + { return __has_trivial_destructor(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_trivial_destructor(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_trivial_destructor(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_trivial_destructor(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_trivial_destructor(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_trivial_destructor(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (int (int))); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (U)); + assert (NTEST (B)); + assert (NTEST (C)); + assert (PTEST (D)); + assert (PTEST (D[])); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C new file mode 100644 index 000000000..f9dacf179 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C @@ -0,0 +1,3 @@ +// PR c++/36855 + +typedef char assert_0 [__has_trivial_destructor (int&) ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C b/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C new file mode 100644 index 000000000..62b60aebf --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C @@ -0,0 +1,89 @@ +// { dg-do run } +#include <cassert> +#include <exception> + +struct A +{ + double a; + double b; +}; + +union U +{ + double a; + double b; +}; + +struct B +{ + virtual ~B() { } +}; + +struct C +: public B { }; + +struct D +{ + ~D() { } +}; + +template<typename T> + bool + f() + { return __has_virtual_destructor(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__has_virtual_destructor(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __has_virtual_destructor(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __has_virtual_destructor(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__has_virtual_destructor(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__has_virtual_destructor(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (PTEST (std::exception)); + assert (NTEST (A)); + assert (NTEST (U)); + assert (PTEST (B)); + assert (PTEST (C)); + assert (NTEST (C[])); + assert (NTEST (D)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/init1.C b/gcc/testsuite/g++.dg/ext/init1.C new file mode 100644 index 000000000..f8d8e8533 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/init1.C @@ -0,0 +1,6 @@ +// PR c++/9623 +// Test for trivial use of named initializer extension +// { dg-options "" } + +struct S { int x; int y; }; +S s = { x:1, y:2 }; diff --git a/gcc/testsuite/g++.dg/ext/injected-ttp.C b/gcc/testsuite/g++.dg/ext/injected-ttp.C new file mode 100644 index 000000000..405bee88c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/injected-ttp.C @@ -0,0 +1,15 @@ +// Test for doing the right thing with injected-class-name used as template +// type argument. This is an extension from DR 176. + +// { dg-options "-pedantic" } + +template <class T> +struct A { }; + +template <template <class> class TTP> +struct B { }; + +struct C: A<int> +{ + B<A> b; // { dg-warning "injected-class-name" } +}; diff --git a/gcc/testsuite/g++.dg/ext/inline1.C b/gcc/testsuite/g++.dg/ext/inline1.C new file mode 100644 index 000000000..7e5f062e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/inline1.C @@ -0,0 +1,34 @@ +// { dg-do compile } +// { dg-options "-O" } +// Make sure inlined non-outlined functions aren't marked weak. +// We'd get a ".weak xyzzy" annotation trigged by the second declaration. + +// { dg-final { scan-assembler-not "weak\[^ \t\]*\[ \t\]_?xyzzy" } } + +// The next check isn't really part of the actual test, just to make +// sure there's no outline-copy of xyzzy, because if that really +// happened, it *should* be marked linkonce or perhaps weak. +// { dg-final { scan-assembler-not "xyzzy" } } + +extern int x; +extern void foo(void); +extern void bar(void); + +extern "C" inline int xyzzy(int a) +{ + foo(); + return a + x; +} + +extern "C" int xyzzy(int); + +extern inline int plugh(int c) +{ + return xyzzy (c); +} + +int y; +void doit(int b) +{ + y = xyzzy (b) + plugh (b); +} diff --git a/gcc/testsuite/g++.dg/ext/instantiate1.C b/gcc/testsuite/g++.dg/ext/instantiate1.C new file mode 100644 index 000000000..1d2a6200b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/instantiate1.C @@ -0,0 +1,24 @@ +// Test that 'extern template' suppresses instantiations. +// { dg-do compile } +// { dg-options "" } + +template <class T> void f (T) { } +extern template void f (int); + +template <class T> struct A { + void f (); +}; +template <class T> void A<T>::f () { } +extern template struct A<int>; + +// { dg-final { scan-assembler-not "\n_?_Z1fIiEvT_(:|\n|\t)" } } +void test_f_int () { f(42); } + +// { dg-final { scan-assembler-not "\n_?_ZN1AIiE1fEv(:|\n|\t)" } } +void test_A_int_f () { A<int> a; a.f (); } + +// { dg-final { scan-assembler "\n_?_Z1fIdEvT_(:|\n|\t)" } } +void test_f_double () { f (2.0); } + +// { dg-final { scan-assembler "\n_?_ZN1AIdE1fEv(:|\n|\t)" } } +void test_A_double_f () { A<double> b; b.f (); } diff --git a/gcc/testsuite/g++.dg/ext/instantiate2.C b/gcc/testsuite/g++.dg/ext/instantiate2.C new file mode 100644 index 000000000..a6292892b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/instantiate2.C @@ -0,0 +1,16 @@ +// Test that 'static template' instantiates statics. +// { dg-do compile } +// { dg-options "-fno-implicit-templates" } + +template <class T> struct A { + static T t; +}; +template <class T> T A<T>::t = 0; +static template struct A<int>; + +// { dg-final { scan-assembler "\n_?_ZN1AIiE1tE(:|\n|\t)" { target { ! *-*-darwin* } } } } +// { dg-final { scan-assembler ".zerofill __DATA,__pu_bss2,__ZN1AIiE1tE" { target *-*-darwin* } } } +void test_int() { A<int>::t = 42; } + +// { dg-final { scan-assembler-not "\n_?_ZN1AIcE1tE(:|\n|\t)" } } +void test_char() { A<char>::t = 42; } diff --git a/gcc/testsuite/g++.dg/ext/instantiate3.C b/gcc/testsuite/g++.dg/ext/instantiate3.C new file mode 100644 index 000000000..ea60d5bf9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/instantiate3.C @@ -0,0 +1,14 @@ +// Test that 'inline template' instantiates the vtable. +// { dg-do compile } +// { dg-options "-O -fno-implicit-templates" } + +template <class T> struct A { + virtual void f () { } +}; +inline template struct A<int>; + +// { dg-final { scan-assembler "\n_?_ZTV1AIiE(:|\n|\t)" } } +A<int> a; + +// { dg-final { scan-assembler-not "\n_?_ZTV1AIcE(:|\n|\t)" } } +A<char> b; diff --git a/gcc/testsuite/g++.dg/ext/interface1.C b/gcc/testsuite/g++.dg/ext/interface1.C new file mode 100644 index 000000000..0f803abc4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface1.C @@ -0,0 +1,7 @@ +// PR c++/22252 +// { dg-do link } +// { dg-additional-sources "interface1a.cc" } +// { dg-options "-fno-inline" } + +#pragma implementation +#include "interface1.h" diff --git a/gcc/testsuite/g++.dg/ext/interface1.h b/gcc/testsuite/g++.dg/ext/interface1.h new file mode 100644 index 000000000..ce91527b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface1.h @@ -0,0 +1,10 @@ +#pragma interface +struct B +{ + B(){}; + ~B(){} +}; +struct A { + B a; + +}; diff --git a/gcc/testsuite/g++.dg/ext/interface1a.cc b/gcc/testsuite/g++.dg/ext/interface1a.cc new file mode 100644 index 000000000..1859d5ce3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface1a.cc @@ -0,0 +1,4 @@ +#include "interface1.h" +A a; +int main() {} + diff --git a/gcc/testsuite/g++.dg/ext/interface2.C b/gcc/testsuite/g++.dg/ext/interface2.C new file mode 100644 index 000000000..3b306fdd8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface2.C @@ -0,0 +1,7 @@ +// PR c++/26195 +// { dg-do link } +// { dg-additional-sources "interface2b.cc" } +// { dg-options "-fno-inline" } + +#pragma implementation "interface2-imaginary.h" +#include "interface2a.h" diff --git a/gcc/testsuite/g++.dg/ext/interface2a.h b/gcc/testsuite/g++.dg/ext/interface2a.h new file mode 100644 index 000000000..efde3e24b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface2a.h @@ -0,0 +1,5 @@ +// PR c++/26195 +#pragma interface "interface2-imaginary.h" + +inline void foo1() { } +inline void foo2() { } diff --git a/gcc/testsuite/g++.dg/ext/interface2b.cc b/gcc/testsuite/g++.dg/ext/interface2b.cc new file mode 100644 index 000000000..9109949b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface2b.cc @@ -0,0 +1,9 @@ +// PR c++/26195 +extern void foo1(); +extern void foo2(); + +int main() +{ + foo1(); + foo2(); +} diff --git a/gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h b/gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h new file mode 100644 index 000000000..874be7509 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface3/dir1/interface3.h @@ -0,0 +1,6 @@ +// PR c++/26195 +#pragma interface "dir1/interface3.h" +#include "../dir2/interface3.h" + +inline void f1() { } +inline void f2() { } diff --git a/gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h b/gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h new file mode 100644 index 000000000..df6f7cd2f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface3/dir2/interface3.h @@ -0,0 +1,5 @@ +// PR c++/26195 +#pragma interface "dir2/interface3.h" + +inline void g1() { } +inline void g2() { } diff --git a/gcc/testsuite/g++.dg/ext/interface3/interface3a.C b/gcc/testsuite/g++.dg/ext/interface3/interface3a.C new file mode 100644 index 000000000..b324dbef7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface3/interface3a.C @@ -0,0 +1,7 @@ +// PR c++/26195 +// { dg-do link } +// { dg-additional-sources "interface3a2.cc" } +// { dg-options "-I. -fno-inline" } + +#pragma implementation "dir1/interface3.cc" +#include "dir1/interface3.h" diff --git a/gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc b/gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc new file mode 100644 index 000000000..cbf1ba801 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface3/interface3a2.cc @@ -0,0 +1,9 @@ +// PR c++/26195 +extern void f1(); +extern void f2(); + +int main() +{ + f1(); + f2(); +} diff --git a/gcc/testsuite/g++.dg/ext/interface3/interface3b.C b/gcc/testsuite/g++.dg/ext/interface3/interface3b.C new file mode 100644 index 000000000..03f753209 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface3/interface3b.C @@ -0,0 +1,7 @@ +// PR c++/26195 +// { dg-do link } +// { dg-additional-sources "interface3b2.cc" } +// { dg-options "-fno-inline" } + +#pragma implementation "dir2/interface3.cc" +#include "dir1/interface3.h" diff --git a/gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc b/gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc new file mode 100644 index 000000000..f532adc74 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface3/interface3b2.cc @@ -0,0 +1,9 @@ +// PR c++/26195 +extern void g1(); +extern void g2(); + +int main() +{ + g1(); + g2(); +} diff --git a/gcc/testsuite/g++.dg/ext/interface4.C b/gcc/testsuite/g++.dg/ext/interface4.C new file mode 100644 index 000000000..85bb91283 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface4.C @@ -0,0 +1,13 @@ +/* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=227376 */ + +/* { dg-do compile } */ +/* { dg-options "-g2" } */ + +/* We used to crash when emitting debug info for type N::A because its + context was a namespace, not a function. */ + +#include "interface4.h" + +void f ( ) { + g ( ); +} diff --git a/gcc/testsuite/g++.dg/ext/interface4.h b/gcc/testsuite/g++.dg/ext/interface4.h new file mode 100644 index 000000000..0971b3722 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/interface4.h @@ -0,0 +1,8 @@ +#pragma interface +namespace N { + typedef int A; +} +inline void g ( ) { + static N :: A a = 0; + a = a; +} diff --git a/gcc/testsuite/g++.dg/ext/is_abstract.C b/gcc/testsuite/g++.dg/ext/is_abstract.C new file mode 100644 index 000000000..2d7149452 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_abstract.C @@ -0,0 +1,89 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +union U +{ + double a; + double b; +}; + +class B +{ + B(); +}; + +class C +{ + virtual void rotate(int) = 0; +}; + +class D +{ + virtual void rotate(int) { } +}; + +template<typename T> + bool + f() + { return __is_abstract(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_abstract(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_abstract(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_abstract(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_abstract(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_abstract(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (NTEST (A)); + assert (NTEST (U)); + assert (NTEST (B)); + assert (NTEST (B[])); + assert (PTEST (C)); + assert (NTEST (D)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_base_of.C b/gcc/testsuite/g++.dg/ext/is_base_of.C new file mode 100644 index 000000000..8afa532e1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_base_of.C @@ -0,0 +1,94 @@ +// { dg-do run } +#include <cassert> + +class A1 +{ + double a; + double b; +}; + +class A2 +{ + double a; + double b; +}; + +class B +: private A1 { }; + +class C +: private A1, private A2 { }; + +union U +{ + double a; + double b; +}; + +template<typename T, typename U> + bool + f() + { return __is_base_of(T, U); } + +template<typename T, typename U> + class My + { + public: + bool + f() + { return !!__is_base_of(T, U); } + }; + +template<typename T, typename U> + class My2 + { + public: + static const bool trait = __is_base_of(T, U); + }; + +template<typename T, typename U> + const bool My2<T, U>::trait; + +template<typename T, typename U, bool b = __is_base_of(T, U)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, typename U, bool b> + const bool My3_help<T, U, b>::trait; + +template<typename T, typename U> + class My3 + { + public: + bool + f() + { return My3_help<T, U>::trait; } + }; + +#define PTEST(T, U) (__is_base_of(T, U) && f<T, U>() \ + && My<T, U>().f() && My2<T, U>::trait && My3<T, U>().f()) + +#define NTEST(T, U) (!__is_base_of(T, U) && !f<T, U>() \ + && !My<T, U>().f() && !My2<T, U>::trait && !My3<T, U>().f()) + +int main() +{ + assert (NTEST (int, A1)); + assert (NTEST (A1, void)); + assert (PTEST (A1, A1)); + assert (NTEST (A1*, A1*)); + assert (NTEST (A1&, A1&)); + assert (PTEST (A1, B)); + assert (NTEST (B, A1)); + assert (PTEST (A1, C)); + assert (PTEST (A2, C)); + assert (NTEST (C, A1)); + assert (PTEST (A1, const B)); + assert (NTEST (const B, A1)); + assert (PTEST (A1, volatile C)); + assert (PTEST (volatile A2, const C)); + assert (NTEST (const volatile C, A1)); + assert (NTEST (U, U)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_base_of_diagnostic.C b/gcc/testsuite/g++.dg/ext/is_base_of_diagnostic.C new file mode 100644 index 000000000..8cb1ce38f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_base_of_diagnostic.C @@ -0,0 +1,15 @@ +class A +{ }; + +class B; + +union C +{ }; + +union D; + +void f() +{ + __is_base_of(A, B); // { dg-error "incomplete type" } + __is_base_of(C, D); +} diff --git a/gcc/testsuite/g++.dg/ext/is_class.C b/gcc/testsuite/g++.dg/ext/is_class.C new file mode 100644 index 000000000..6f3982855 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_class.C @@ -0,0 +1,76 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +class B +{ + B() { } +}; + +union U +{ + double a; + double b; +}; + +template<typename T> + bool + f() + { return __is_class(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_class(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_class(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_class(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_class(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_class(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (B)); + assert (NTEST (U)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_class_error1.C b/gcc/testsuite/g++.dg/ext/is_class_error1.C new file mode 100644 index 000000000..d037ec72b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_class_error1.C @@ -0,0 +1,6 @@ +// PR c++/33212 + +template<int> void foo() +{ + __is_class((int); // { dg-error "type-specifier|primary-expression" } +} diff --git a/gcc/testsuite/g++.dg/ext/is_class_error2.C b/gcc/testsuite/g++.dg/ext/is_class_error2.C new file mode 100644 index 000000000..8649dc441 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_class_error2.C @@ -0,0 +1,22 @@ +// PR c++/33464 + +template<int> void foo() +{ + __has_nothrow_assign(int)(); // { dg-error "'__has_nothrow_assign\\(int\\)' cannot be used" } + __has_trivial_assign(int)(); // { dg-error "'__has_trivial_assign\\(int\\)' cannot be used" } + __has_nothrow_constructor(int)(); // { dg-error "'__has_nothrow_constructor\\(int\\)' cannot be used" } + __has_trivial_constructor(int)(); // { dg-error "'__has_trivial_constructor\\(int\\)' cannot be used" } + __has_nothrow_copy(int)(); // { dg-error "'__has_nothrow_copy\\(int\\)' cannot be used" } + __has_trivial_copy(int)(); // { dg-error "'__has_trivial_copy\\(int\\)' cannot be used" } + __has_trivial_destructor(int)(); // { dg-error "'__has_trivial_destructor\\(int\\)' cannot be used" } + __has_virtual_destructor(int)(); // { dg-error "'__has_virtual_destructor\\(int\\)' cannot be used" } + __is_abstract(int)(); // { dg-error "'__is_abstract\\(int\\)' cannot be used" } + __is_base_of(int, float)(); // { dg-error "'__is_base_of\\(int, float\\)' cannot be used" } + __is_class(int)(); // { dg-error "'__is_class\\(int\\)' cannot be used" } + __is_convertible_to(int, float)(); // { dg-message "unimplemented" } + __is_empty(int)(); // { dg-error "'__is_empty\\(int\\)' cannot be used" } + __is_enum(int)(); // { dg-error "'__is_enum\\(int\\)' cannot be used" } + __is_pod(int)(); // { dg-error "'__is_pod\\(int\\)' cannot be used" } + __is_polymorphic(int)(); // { dg-error "'__is_polymorphic\\(int\\)' cannot be used" } + __is_union(int)(); // { dg-error "'__is_union\\(int\\)' cannot be used" } +} diff --git a/gcc/testsuite/g++.dg/ext/is_empty.C b/gcc/testsuite/g++.dg/ext/is_empty.C new file mode 100644 index 000000000..4c58941b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_empty.C @@ -0,0 +1,78 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +struct B +{ + virtual ~B() { } +}; + +class C +{ }; + +union U +{ }; + +template<typename T> + bool + f() + { return __is_empty(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_empty(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_empty(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_empty(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_empty(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_empty(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (NTEST (A)); + assert (NTEST (B)); + assert (PTEST (C)); + assert (NTEST (C[])); + assert (NTEST (U)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_enum.C b/gcc/testsuite/g++.dg/ext/is_enum.C new file mode 100644 index 000000000..4ac1723ed --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_enum.C @@ -0,0 +1,73 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +class B +{ }; + +enum E +{ + e0 +}; + +template<typename T> + bool + f() + { return __is_enum(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_enum(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_enum(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_enum(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_enum(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_enum(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (NTEST (A)); + assert (NTEST (B)); + assert (PTEST (E)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_pod.C b/gcc/testsuite/g++.dg/ext/is_pod.C new file mode 100644 index 000000000..939665d8d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_pod.C @@ -0,0 +1,76 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +struct B +{ + B() { } +}; + +struct C +: public A { }; + +template<typename T> + bool + f() + { return __is_pod(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_pod(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_pod(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_pod(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_pod(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_pod(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (PTEST (int)); + assert (NTEST (void)); + assert (PTEST (A)); + assert (PTEST (A[])); + assert (NTEST (B)); + assert (PTEST (C)); + assert (PTEST (C[])); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_pod_98.C b/gcc/testsuite/g++.dg/ext/is_pod_98.C new file mode 100644 index 000000000..80a87c825 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_pod_98.C @@ -0,0 +1,16 @@ +// PR c++/43333 +// { dg-options "-std=c++98" } +// { dg-do run } + +struct strPOD +{ + const char *const foo; + const char *const bar; +}; +extern "C" void abort (void); +int main () +{ + if (!__is_pod (strPOD)) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_pod_incomplete.C b/gcc/testsuite/g++.dg/ext/is_pod_incomplete.C new file mode 100644 index 000000000..a30ab1fdd --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_pod_incomplete.C @@ -0,0 +1,8 @@ +// PR c++/32158 +template<typename T> + struct A + { + A() { } + }; + +int t[__is_pod(A<int>)?-1:1]; diff --git a/gcc/testsuite/g++.dg/ext/is_polymorphic.C b/gcc/testsuite/g++.dg/ext/is_polymorphic.C new file mode 100644 index 000000000..462e4b705 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_polymorphic.C @@ -0,0 +1,83 @@ +// { dg-do run } +#include <cassert> +#include <exception> + +struct A +{ + double a; + double b; +}; + +class B +{ + virtual void rotate(int) { } +}; + +class C +: public B { }; + +union U +{ + double a; + double b; +}; + +template<typename T> + bool + f() + { return __is_polymorphic(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_polymorphic(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_polymorphic(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_polymorphic(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_polymorphic(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_polymorphic(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (PTEST (std::exception)); + assert (NTEST (A)); + assert (PTEST (B)); + assert (PTEST (C)); + assert (NTEST (C[])); + assert (NTEST (U)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_union.C b/gcc/testsuite/g++.dg/ext/is_union.C new file mode 100644 index 000000000..c95f5a6e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_union.C @@ -0,0 +1,76 @@ +// { dg-do run } +#include <cassert> + +struct A +{ + double a; + double b; +}; + +class B +{ + B() { } +}; + +union U +{ + double a; + double b; +}; + +template<typename T> + bool + f() + { return __is_union(T); } + +template<typename T> + class My + { + public: + bool + f() + { return !!__is_union(T); } + }; + +template<typename T> + class My2 + { + public: + static const bool trait = __is_union(T); + }; + +template<typename T> + const bool My2<T>::trait; + +template<typename T, bool b = __is_union(T)> + struct My3_help + { static const bool trait = b; }; + +template<typename T, bool b> + const bool My3_help<T, b>::trait; + +template<typename T> + class My3 + { + public: + bool + f() + { return My3_help<T>::trait; } + }; + +#define PTEST(T) (__is_union(T) && f<T>() \ + && My<T>().f() && My2<T>::trait && My3<T>().f()) + +#define NTEST(T) (!__is_union(T) && !f<T>() \ + && !My<T>().f() && !My2<T>::trait && !My3<T>().f()) + +int main() +{ + assert (NTEST (int)); + assert (NTEST (void)); + assert (NTEST (A)); + assert (NTEST (B)); + assert (PTEST (U)); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/java-1.C b/gcc/testsuite/g++.dg/ext/java-1.C new file mode 100644 index 000000000..f88e1fcab --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/java-1.C @@ -0,0 +1,26 @@ +// { dg-do compile { target { ! { powerpc-ibm-aix* } } } } +// { dg-options "" } +// Test extern "java" and some throwing of the objects. + +extern "Java" + namespace java + { + namespace lang + { + class Throwable; + class Class; + } +} +typedef class java::lang::Throwable* jthrowable; +typedef class java::lang::Class* jclass; +class java::lang::Throwable { +public: + static jclass class$; +}; +int +_Jv_FindClassFromSignature ( ) + try + { + } + catch (java::lang::Throwable *ncdfe) {} + diff --git a/gcc/testsuite/g++.dg/ext/java-2.C b/gcc/testsuite/g++.dg/ext/java-2.C new file mode 100644 index 000000000..8114517b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/java-2.C @@ -0,0 +1,79 @@ +// PR c++/30293 +// PR c++/30294 +// { dg-do compile { target { ! { powerpc-ibm-aix* } } } } +// { dg-options "" } + +extern "Java" { +typedef __java_byte jbyte; +namespace java { +namespace lang { + class Object {}; + class Class {}; +} +} +typedef struct java::lang::Object* jobject; +typedef java::lang::Class *jclass; +} +extern "C" jobject _Jv_AllocObject (jclass); + +extern "Java" { + struct A { static java::lang::Class class$; }; +} + +struct B { + A a; // { dg-error "has Java class type" } +}; + +void* operator new (__SIZE_TYPE__, void*) throw(); +char buf[1024]; + +A a; // { dg-error "not allocated with" } +A b = A (); // { dg-error "not allocated with" } +A *c = new ((void *) buf) A (); // { dg-error "using placement new" } +A *d = new A (); +jbyte e = 6; + +const A fn1 () // { dg-error "return type has Java class type" } +{ + A a; // { dg-error "not allocated with" } + return a; +} + +A fn2 () // { dg-error "return type has Java class type" } +{ + A a; // { dg-error "not allocated with" } + return a; +} + +A *fn3 () +{ + return new A (); +} + +A &fn4 () +{ + return *c; +} + +jbyte fn5 () +{ + return 7; +} + +void fn6 (A x) // { dg-error "has Java class type" } +{ +} + +void fn7 (const A x) // { dg-error "has Java class type" } +{ +} + +void fn8 (A *x) +{ + (void) x; +} + +void fn9 (jbyte x) +{ + (void) x; +} diff --git a/gcc/testsuite/g++.dg/ext/label1.C b/gcc/testsuite/g++.dg/ext/label1.C new file mode 100644 index 000000000..95fd644e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label1.C @@ -0,0 +1,10 @@ +// { dg-options "" } + +int main(void) { + static const void* lbls[2][2] = {{&&lbl0, &&lbl0}, {&&lbl0, &&lbl0}}; + goto *lbls[0][0]; + goto *lbls[0][0][0]; // { dg-message "" } + goto *lbls[0]; // { dg-error "" } + lbl0: + ; +} diff --git a/gcc/testsuite/g++.dg/ext/label10.C b/gcc/testsuite/g++.dg/ext/label10.C new file mode 100644 index 000000000..632b2426e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label10.C @@ -0,0 +1,17 @@ +// PR c++/33836 +// { dg-do compile } +// { dg-options "" } + +template<int N> struct A +{ + enum { M = && N }; // { dg-error "referenced outside|cannot appear in|not an integer constant" } +}; + +A<0> a; + +void foo () +{ + __label__ P; + enum { O = && P }; // { dg-error "cannot appear in|not an integer constant" } + P:; +} diff --git a/gcc/testsuite/g++.dg/ext/label11.C b/gcc/testsuite/g++.dg/ext/label11.C new file mode 100644 index 000000000..dd9222860 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label11.C @@ -0,0 +1,46 @@ +// PR c++/38725 +// { dg-do compile } +// { dg-options "" } + +struct A {}; +struct B : virtual A {}; +int vi; +void *vp; + +void +f1 (int i) +{ + goto *i; +} + +void +f2 (B b) +{ + goto *b; // { dg-error "cannot convert" } +} + +template <typename T> +void +f3 (T i) +{ + goto *i; +} + +void +f3a () +{ + f3 (vi); +} + +template <typename T> +void +f4 (T i) +{ + goto *i; +} + +void +f4a () +{ + f4 (vp); +} diff --git a/gcc/testsuite/g++.dg/ext/label12.C b/gcc/testsuite/g++.dg/ext/label12.C new file mode 100644 index 000000000..2585318b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label12.C @@ -0,0 +1,39 @@ +// PR c++/39028 +// { dg-do compile } +// Origin: Stephan Springl <springl@bfw-online.de> + +void +f () +{ + int i; + for (i = 0; i < 2; i++) + { + __label__ l; + goto l; + l:; + } + while (i++ < 5) + { + __label__ l; + goto l; + l:; + } + do + { + __label__ l; + goto l; + l:; + } + while (i++ < 8); + if (1) + { + __label__ l; + goto l; + l:; + } + { + __label__ l; + goto l; + l:; + } +} diff --git a/gcc/testsuite/g++.dg/ext/label13.C b/gcc/testsuite/g++.dg/ext/label13.C new file mode 100644 index 000000000..d932a9a50 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label13.C @@ -0,0 +1,22 @@ +// PR c++/41090 +// { dg-do run } +// { dg-options "" } + +int i; +struct C +{ + C(); +}; + +C::C() // { dg-bogus "can never be copied" "" { xfail { { *-apple-darwin* alpha*-dec-osf* } || { hppa*-*-hpux* && { ! hppa*64*-*-* } } } } } +{ + static void *labelref = &&label; + goto *labelref; + label: i = 1; +} + +int main() +{ + C c; + return (i != 1); +} diff --git a/gcc/testsuite/g++.dg/ext/label2.C b/gcc/testsuite/g++.dg/ext/label2.C new file mode 100644 index 000000000..7d11d00f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label2.C @@ -0,0 +1,11 @@ +// { dg-options "" } + +template <typename T> +void f() { + l: + void *p[] = { &&l }; + + goto *p[0]; +} + +template void f<int>(); diff --git a/gcc/testsuite/g++.dg/ext/label3.C b/gcc/testsuite/g++.dg/ext/label3.C new file mode 100644 index 000000000..604bfdc12 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label3.C @@ -0,0 +1,39 @@ +// Bug: we were removing the p = q assignment in dce, and then reinserting +// it *after* the try/catch in out-of-ssa. Oops. + +// testcase reduced from libjava/interpret.cc. + +// { dg-do run } +// { dg-options "-O2" } + +extern "C" int printf (const char *, ...); + +bool b; + +int main() +{ + __label__ one, two, done; + void *labs[] = { &&one, &&two, &&done }; + const void **q = (const void **)labs; + const void **p = q; + + try + { + one: + printf ("one!\n"); + if (b) + throw 42; + goto **p++; + + two: + printf ("two!\n"); + goto **p++; + + done: + printf ("done!\n"); + } + catch (int) + { + printf ("caught!\n"); + } +} diff --git a/gcc/testsuite/g++.dg/ext/label4.C b/gcc/testsuite/g++.dg/ext/label4.C new file mode 100644 index 000000000..93f140f34 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label4.C @@ -0,0 +1,6 @@ +// PR c++/20563: ICE (--enable-checking), infinite loop (--disable-checking) +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// { dg-do compile } + +__label__ *l; // { dg-error "not at the beginning of" } diff --git a/gcc/testsuite/g++.dg/ext/label5.C b/gcc/testsuite/g++.dg/ext/label5.C new file mode 100644 index 000000000..fc611cd41 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label5.C @@ -0,0 +1,6 @@ +// { dg-options "" } +// PR c++/24052 + +struct A { }; +int main() { b: A() && && b; } // { dg-error "A\\(\\) && && *b" } +// { dg-message "candidate|operator&&|no known conversion" "additional" { target *-*-* } 5 } diff --git a/gcc/testsuite/g++.dg/ext/label6.C b/gcc/testsuite/g++.dg/ext/label6.C new file mode 100644 index 000000000..e4b0c37c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label6.C @@ -0,0 +1,3 @@ +// PR c++/32108 + +__label__ L; // { dg-error "not at the beginning" } diff --git a/gcc/testsuite/g++.dg/ext/label7.C b/gcc/testsuite/g++.dg/ext/label7.C new file mode 100644 index 000000000..e92dccf5d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label7.C @@ -0,0 +1,12 @@ +// PR c++/32121 +// { dg-do compile } + +int f (void) +{ + a:; + __label__ a; // { dg-error "not at the beginning" } + int b; + __label__ c; // { dg-error "not at the beginning" } + a:; // { dg-error "duplicate label" } + c:; +} diff --git a/gcc/testsuite/g++.dg/ext/label8.C b/gcc/testsuite/g++.dg/ext/label8.C new file mode 100644 index 000000000..1f6175df3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label8.C @@ -0,0 +1,22 @@ +// PR c++/32121 +// { dg-do compile } + +int f (void) +{ + __label__ a, b; + __label__ c; + a:; + b:; + c:; + { + __label__ d; + d:; + if (0) + { + __label__ e; + __label__ f; + f:; + e:; + } + } +} diff --git a/gcc/testsuite/g++.dg/ext/label9.C b/gcc/testsuite/g++.dg/ext/label9.C new file mode 100644 index 000000000..81b385ffe --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label9.C @@ -0,0 +1,10 @@ +// PR c++/32121 +// { dg-do compile } + +int f (void) +{ + while (1) + __label__ a; // { dg-error "not at the beginning" } + for (;;) + __label__ b; // { dg-error "not at the beginning" } +} diff --git a/gcc/testsuite/g++.dg/ext/lvaddr.C b/gcc/testsuite/g++.dg/ext/lvaddr.C new file mode 100644 index 000000000..5b217d165 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/lvaddr.C @@ -0,0 +1,10 @@ +// Copyright (C) 2002 Free Software Foundation +// Contributed by Matt Austern <austern@apple.com> + +// { dg-do compile } + +void f() +{ + int n; + char* p = &(char) n; // { dg-error "lvalue" } +} diff --git a/gcc/testsuite/g++.dg/ext/lvalue1.C b/gcc/testsuite/g++.dg/ext/lvalue1.C new file mode 100644 index 000000000..bf883eae2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/lvalue1.C @@ -0,0 +1,10 @@ +// Test that we complain about the gcc cast-as-lvalue extension. + +int main () +{ + char c; + + static_cast<int>(c) = 2; // { dg-error "lvalue" "not an lvalue" } + + return c != 2; +} diff --git a/gcc/testsuite/g++.dg/ext/max.C b/gcc/testsuite/g++.dg/ext/max.C new file mode 100644 index 000000000..bc65f1f70 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/max.C @@ -0,0 +1,6 @@ +struct s_t { +}; +void foo(void) { + s_t s; int i; + s<?=i; // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/ext/member-attr.C b/gcc/testsuite/g++.dg/ext/member-attr.C new file mode 100644 index 000000000..2a7e18bf5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/member-attr.C @@ -0,0 +1,14 @@ +/* Test to see if__attribute__'s are handled by inline member functions */ +/* { dg-do compile } */ +/* { dg-options "-fmessage-length=0" } */ + +/* Previously __attribute__'s were handled by the grammar but "dropped + on the floor", these effectively ignoring them. This tests the fix + to see that they are now handled. In this test it should report + that we have an illegal attribute. */ + +class T { + public: + __attribute__ ((garbage1)) void member1(int) {} /* { dg-warning "'garbage1' attribute directive ignored" "" } */ + void __attribute__ ((garbage2)) member2(int) {} /* { dg-warning "'garbage2' attribute directive ignored" "" } */ +}; diff --git a/gcc/testsuite/g++.dg/ext/ms-1.C b/gcc/testsuite/g++.dg/ext/ms-1.C new file mode 100644 index 000000000..3963b7561 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/ms-1.C @@ -0,0 +1,17 @@ + +// MS allows more things to be pointers to member functions +// { dg-options "-fms-extensions" } + +struct X +{ + void Foo (X *); + void Bar (); +}; + +void Quux (void (X::*) ()); + +void X::Foo (X *ptr) // { dg-message "candidate" } +{ + Quux (Foo); // { dg-error "no matches" } + Quux (Bar); +} diff --git a/gcc/testsuite/g++.dg/ext/no-asm-1.C b/gcc/testsuite/g++.dg/ext/no-asm-1.C new file mode 100644 index 000000000..6c4c20439 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/no-asm-1.C @@ -0,0 +1,10 @@ +// { dg-do compile } +// { dg-options "" } + +// Verify that asm and the GNU extension typeof are recognized as +// keywords. + +int asm; // { dg-error "before .asm." } +int typeof; // { dg-error "expected" } +// { dg-error "multiple types" "" { target *-*-* } 8 } +// { dg-error "declaration" "" { target *-*-* } 8 } diff --git a/gcc/testsuite/g++.dg/ext/no-asm-2.C b/gcc/testsuite/g++.dg/ext/no-asm-2.C new file mode 100644 index 000000000..fa614d8e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/no-asm-2.C @@ -0,0 +1,10 @@ +// { dg-do compile } +// { dg-options "-fno-asm" } + +// Verify that the keyword asm and the GNU extension typeof are not +// recognized as keywords when using -fno-asm. Having -fno-asm affect +// a standard C++ keyword seems strange, but that is existing +// behaviour. If that behaviour changes, this test should change. + +int asm; // { dg-bogus "before .asm." } +int typeof; // { dg-bogus "before .typeof." } diff --git a/gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C b/gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C new file mode 100644 index 000000000..8dbbd5f34 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C @@ -0,0 +1,9 @@ +// { dg-do compile } +// { dg-options "-fno-gnu-keywords" } + +// Verify that the keyword asm is recognized and that the GNU +// extension typeof is not recognized as a keyword when using +// -fno-gnu-keywords. + +int asm; // { dg-error "before .asm." } +int typeof; // { dg-bogus "before .typeof." } diff --git a/gcc/testsuite/g++.dg/ext/offsetof1.C b/gcc/testsuite/g++.dg/ext/offsetof1.C new file mode 100644 index 000000000..1468c0a7c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/offsetof1.C @@ -0,0 +1,21 @@ +// PR c++/27601 +// Origin: Patrik Hägglund <patrik.hagglund@bredband.net> +// { dg-do compile } + +struct bar { + static int foo; + static int baz(); +}; + +int a = __builtin_offsetof(bar, foo); // { dg-error "static data member" } +int av = __builtin_offsetof(volatile bar, foo); // { dg-error "static data member" } +int b = __builtin_offsetof(bar, baz); // { dg-error "member function" } +int b0 = __builtin_offsetof(bar, baz[0]); // { dg-error "function" } +int bv0 = __builtin_offsetof(volatile bar, baz[0]); // { dg-error "function" } +int c = __builtin_offsetof(bar, ~bar); // { dg-error "member function" } + +typedef int I; +enum E { }; + +int d = __builtin_offsetof(I, ~I); // { dg-error "destructor" } +int e = __builtin_offsetof(E, ~E); // { dg-error "destructor" } diff --git a/gcc/testsuite/g++.dg/ext/oper1.C b/gcc/testsuite/g++.dg/ext/oper1.C new file mode 100644 index 000000000..7f97d73a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/oper1.C @@ -0,0 +1,19 @@ +// { dg-do run } + +// Copyright 2002 Free Software Foundation +// Contributed by Jason Merrill <jason@redhat.com> + +// Make sure the GNU extension of accepting dropping cv-qualifiers for +// the implicit this argument does not kick in when taking the address +// of an object, since this extension would change the meaning of a +// well-defined program. + +struct A { + A* operator&() { return 0; } +}; + +int main () +{ + const A a = {}; + return (&a == 0); +} diff --git a/gcc/testsuite/g++.dg/ext/packed10.C b/gcc/testsuite/g++.dg/ext/packed10.C new file mode 100644 index 000000000..c4bbb1462 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed10.C @@ -0,0 +1,14 @@ +// PR c++/13983, c++/17519 +// The typedef and the array were causing us to miss that A<int> is +// a packed type. + +template <class T> +struct A { + A(); +} __attribute__((packed)); + +typedef A<int> Ai; + +struct B { + Ai a[2]; +} __attribute__((packed)); diff --git a/gcc/testsuite/g++.dg/ext/packed11.C b/gcc/testsuite/g++.dg/ext/packed11.C new file mode 100644 index 000000000..e75845d93 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed11.C @@ -0,0 +1,13 @@ +// PR c++/26670 + +struct nonpod { + nonpod(); +}; + +struct nonpod_pack { + nonpod n; // { dg-warning "ignoring packed attribute" } +} __attribute__ ((packed)); + +struct nonpod_pack2 { + nonpod_pack p; // { dg-warning "ignoring packed attribute" } +} __attribute__ ((packed)); diff --git a/gcc/testsuite/g++.dg/ext/packed2.C b/gcc/testsuite/g++.dg/ext/packed2.C new file mode 100644 index 000000000..66f156bac --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed2.C @@ -0,0 +1,35 @@ +// PR c++/10091 + +// Original synopsis +// Bug: We were dying because in general, B::a doesn't have enough +// alignment for us to take its address. But if the B is C::b, it does +// have enough alignment, and we should be able to determine that. + +// This only failed on STRICT_ALIGNMENT targets (i.e. not i686) + +// July 2003 +// packing of non-pods is now only allowed if the non-pod is itself +// packed. Also only such pods can be reference bound to non-consts + +struct A { + int i; + + A(); + A(const A&); + A& operator=(const A&); +} __attribute__ ((packed)); + +struct B { + A a; +} __attribute__ ((packed)); + +struct C { + B b; + int j; +}; + +void f (A&); +void g (C& c) +{ + f (c.b.a); +} diff --git a/gcc/testsuite/g++.dg/ext/packed3.C b/gcc/testsuite/g++.dg/ext/packed3.C new file mode 100644 index 000000000..880b5d9b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed3.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Jul 2003 <nathan@codesourcery.com> + +// Packed fields are unsuitable for direct reference binding. + +struct Unpacked { int i; }; + +void Ref (int &p); +void Ref (Unpacked &p); + +struct __attribute__ ((packed)) Packed +{ + char c; + int i; + Unpacked u; +}; + +void Foo (Packed &p) +{ + Ref (p.i); // { dg-error "cannot bind packed field" "" { target { ! default_packed } } } + Ref (p.u.i); // { dg-error "cannot bind packed field" "" { target { ! default_packed } } } + Ref (p.u); // { dg-error "cannot bind packed field" "" { target { ! default_packed } } } +} diff --git a/gcc/testsuite/g++.dg/ext/packed4.C b/gcc/testsuite/g++.dg/ext/packed4.C new file mode 100644 index 000000000..e5e5e2c08 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed4.C @@ -0,0 +1,77 @@ +// { dg-do run { target { ! default_packed } } } +// { dg-options "-w" } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Jul 2003 <nathan@codesourcery.com> + +// Packed fields are unsuitable for direct reference binding. + +struct Unpacked { int i; }; + +int ConstRef (int const &p, int const *ptr, int v) +{ + if (p != v) + return 1; + if (&p == ptr) + return 2; + return 0; +} + +int ConstRef (Unpacked const &p, Unpacked const *ptr, int v) +{ + if (p.i != v) + return 1; + if (&p == ptr) + return 2; + return 0; +} + +int Val (int p, int v) +{ + if (p != v) + return 1; + return 0; +} +int Val (Unpacked p, int v) +{ + if (p.i != v) + return 1; + return 0; +} + +struct __attribute__ ((packed)) Packed +{ + char c; + int i; + Unpacked u; + char t; +}; + +int Foo (Packed &p, int i, int ui) +{ + int r; + + if ((r = Val (p.i, i))) + return r; + if ((r = Val (p.u.i, ui))) + return r + 2; + if ((r = Val (p.u, ui))) + return r + 4; + + if ((r = ConstRef (p.i, &p.i, i))) + return r + 6; + + return 0; +} + +int main () +{ + Packed p; + + p.c = 0x12; + p.i = 0x3456789a; + p.u.i = 0xbcdef00f; + p.t = 0xed; + + return Foo (p, 0x3456789a, 0xbcdef00f); +} diff --git a/gcc/testsuite/g++.dg/ext/packed5.C b/gcc/testsuite/g++.dg/ext/packed5.C new file mode 100644 index 000000000..caf14d89c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed5.C @@ -0,0 +1,16 @@ +// PR c++/14173 + +struct A; + +void foo(const A&); + +struct A +{ + A(const A&); +}; + +struct B +{ + A a; + A bar() { return a; } +}; diff --git a/gcc/testsuite/g++.dg/ext/packed6.C b/gcc/testsuite/g++.dg/ext/packed6.C new file mode 100644 index 000000000..6a176b624 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed6.C @@ -0,0 +1,78 @@ +// PR c++/15209 +// { dg-options "-w" } + +__extension__ typedef __SIZE_TYPE__ size_t; +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; + +typedef unsigned int uint32_t; +__extension__ typedef unsigned long long int uint64_t; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +struct MAGIC {u8 magic[8];} __attribute__ ((packed)); +struct PACKETTYPE {u8 type[16];} __attribute__ ((packed)); + + +typedef u16 leu16; +typedef u32 leu32; +typedef u64 leu64; + +class MD5Hash +{ +public: + + MD5Hash(void) {}; + + void *print(void) const; + MD5Hash(const MD5Hash &other); + MD5Hash& operator=(const MD5Hash &other); + +public: + u8 hash[16]; +}; + +struct PACKET_HEADER +{ + + MAGIC magic; + leu64 length; + MD5Hash hash; + MD5Hash setid; + PACKETTYPE type; +} __attribute__ ((packed)); + + +struct MAINPACKET +{ + PACKET_HEADER header; + + leu64 blocksize; + leu32 recoverablefilecount; + MD5Hash fileid[0]; + + +} __attribute__ ((packed)); + +struct CriticalPacket +{ + u8 *packetdata; + size_t packetlength; +}; + +class MainPacket : public CriticalPacket +{ + const MD5Hash& SetId(void) const; + + u64 blocksize; + u32 totalfilecount; + u32 recoverablefilecount; +}; + +inline const MD5Hash& MainPacket::SetId(void) const +{ + return ((const MAINPACKET*)packetdata)->header.setid; +} diff --git a/gcc/testsuite/g++.dg/ext/packed7.C b/gcc/testsuite/g++.dg/ext/packed7.C new file mode 100644 index 000000000..e2f74e026 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed7.C @@ -0,0 +1,15 @@ +// PR c++/14124 +// A packed enum uses the minimal underlying type. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Matt Austern <austern@apple.com> + +// { dg-do run } + +enum XXX { xyzzy = 3 } __attribute__((packed)); + +int main() +{ + int enumsize = sizeof(xyzzy); + return (enumsize == 1) ? 0 : 1; +} diff --git a/gcc/testsuite/g++.dg/ext/packed8.C b/gcc/testsuite/g++.dg/ext/packed8.C new file mode 100644 index 000000000..91ee8b3ee --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed8.C @@ -0,0 +1,24 @@ +// PR c++/18378 +// NOTE: This test assumes packed structure layout differs from unpacked +// structure layout. This isn't true, e.g., with the default +// arm-none-elf options. +// { dg-options "-mstructure-size-boundary=8" { target arm*-*-* } } + +class A +{ +public: + int i; + + A() {} + A(const A& a) { i = a.i; } +}; + +class B +{ + A a __attribute__((packed)); // { dg-warning "attribute ignored" "" { target default_packed } } + +public: + B() {} + A GetA() { return a; } // { dg-error "" "" { target { ! default_packed } } } +}; + diff --git a/gcc/testsuite/g++.dg/ext/packed9.C b/gcc/testsuite/g++.dg/ext/packed9.C new file mode 100644 index 000000000..ba5d4ab04 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed9.C @@ -0,0 +1,20 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Apr 2005 <nathan@codesourcery.com> + +// DR21166. unnecessary error on packed char + +struct s1 { + char c1; +} __attribute__((packed)); + +char& +f(struct s1 *s) +{ + return s->c1; +} + +char * +g(struct s1 *s) +{ + return &s->c1; +} diff --git a/gcc/testsuite/g++.dg/ext/pr17577.C b/gcc/testsuite/g++.dg/ext/pr17577.C new file mode 100644 index 000000000..29b1d17d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr17577.C @@ -0,0 +1,6 @@ +// Test for PR c++/17577. + +/* { dg-do compile } */ + +#include "pr17577.h" +#pragma implementation "pr17577.h" /* { dg-warning "appears after file" } */ diff --git a/gcc/testsuite/g++.dg/ext/pr17577.h b/gcc/testsuite/g++.dg/ext/pr17577.h new file mode 100644 index 000000000..6ff0addb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr17577.h @@ -0,0 +1,2 @@ +// Test for PR c++/17577. +#pragma interface diff --git a/gcc/testsuite/g++.dg/ext/pr27019.C b/gcc/testsuite/g++.dg/ext/pr27019.C new file mode 100644 index 000000000..c96d51c14 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr27019.C @@ -0,0 +1,11 @@ + +// { dg-do compile } +// { dg-options "" } + +struct A +{ + int i; + int z[1]; +}; + +A a = { z:{} }; // { dg-message "unimplemented" } diff --git a/gcc/testsuite/g++.dg/ext/pr28291.C b/gcc/testsuite/g++.dg/ext/pr28291.C new file mode 100644 index 000000000..1b3b9f40a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr28291.C @@ -0,0 +1,13 @@ + +// Test to make sure we do not ICE on this invalid program. + +// { dg-do compile } +// { dg-options "" } + +struct A +{ + static int i; + int j; +}; + +A a = { i:0 }; // { dg-error "non-static data member" } diff --git a/gcc/testsuite/g++.dg/ext/pr34829.C b/gcc/testsuite/g++.dg/ext/pr34829.C new file mode 100644 index 000000000..d588b5b2b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr34829.C @@ -0,0 +1,22 @@ +// Test for PR c++/34829 +// Placement new should be ok for non-aggregate Java types. + +// { dg-do compile } +// { dg-options "" } + +extern "Java" +{ + typedef __java_byte jbyte; +} + +typedef __SIZE_TYPE__ size_t; + +void *operator new (size_t, void *m) +{ + return m; +} + +jbyte *f(void *memory) +{ + return new (memory) jbyte; +} diff --git a/gcc/testsuite/g++.dg/ext/pr47213.C b/gcc/testsuite/g++.dg/ext/pr47213.C new file mode 100644 index 000000000..193007e83 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr47213.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-require-visibility "" } +// { dg-options "-fvisibility-ms-compat" } +#include <typeinfo> + +template < typename T > void +bar () +{ + typeid (T); +} + +void +foo () +{ + bar < int () > (); +} diff --git a/gcc/testsuite/g++.dg/ext/pragmaweak1.C b/gcc/testsuite/g++.dg/ext/pragmaweak1.C new file mode 100644 index 000000000..68bf3fce2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pragmaweak1.C @@ -0,0 +1,9 @@ +// PR c++/25999 +// { dg-final { scan-assembler-not "_Z3Foov" } } + +extern "C" { + void Foo(); +} +#pragma weak Random_Symbol +void Foo() { } + diff --git a/gcc/testsuite/g++.dg/ext/pretty1.C b/gcc/testsuite/g++.dg/ext/pretty1.C new file mode 100644 index 000000000..06608ae30 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pretty1.C @@ -0,0 +1,67 @@ +// PR c++/6794 +// Test whether __PRETTY_FUNCTION__ works in templates, functions and +// in initializers at global scope +// { dg-do compile } +// { dg-options "" } + +extern "C" void __assert_fail (const char *, const char *, + unsigned int, const char *) + throw() __attribute__((noreturn)); +extern "C" void abort (void); +extern "C" void exit (int); + +#define str(expr) #expr +#define assert(expr) \ + ((expr) ? 0 : (__assert_fail (str(expr), __FILE__, __LINE__, \ + __PRETTY_FUNCTION__), 0)) + +int __attribute__((noinline)) +foo (void) +{ + return 1; +} + +template<class T> int +bar (T) +{ + return (assert (foo ()), 1); +} + +template<> int +bar<int> (int) +{ + return (assert (foo ()), 2); +} + +int a = (assert (foo ()), 1); +int b = (assert (foo ()), 2); + +int +main () +{ + double c = 1.0; + unsigned char *d = 0; + int e = (assert (foo ()), 3); + + bar (c); + bar (d); + bar (e); +} + +namespace N +{ + int f = (assert (foo ()), 4); +} + +void __attribute__((noinline)) +__assert_fail (const char *cond, const char *file, unsigned int line, + const char *pretty) throw () +{ + abort (); +} + +// { dg-final { scan-assembler "int bar\\(T\\).*with T = int" } } +// { dg-final { scan-assembler "top level" } } +// { dg-final { scan-assembler "int main\\(\\)" } } +// { dg-final { scan-assembler "int bar\\(T\\).*with T = double" } } +// { dg-final { scan-assembler "int bar\\(T\\).*with T = unsigned char\*" } } diff --git a/gcc/testsuite/g++.dg/ext/pretty2.C b/gcc/testsuite/g++.dg/ext/pretty2.C new file mode 100644 index 000000000..0c05da9b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pretty2.C @@ -0,0 +1,61 @@ +// PR c++/6794 +// Test whether __PRETTY_FUNCTION__ works in templates, functions and +// in initializers at global scope +// { dg-do run } +// { dg-options "" } + +extern "C" void __assert_fail (const char *, const char *, + unsigned int, const char *) + throw() __attribute__((noreturn)); +extern "C" void abort (void); +extern "C" void exit (int); + +#define str(expr) #expr +#define assert(expr) \ + ((expr) ? 0 : (__assert_fail (str(expr), __FILE__, __LINE__, \ + __PRETTY_FUNCTION__), 0)) + +int __attribute__((noinline)) +foo (void) +{ + return 1; +} + +template<class T> int +bar (T) +{ + return (assert (foo ()), 1); +} + +template<> int +bar<int> (int) +{ + return (assert (foo ()), 2); +} + +int a = (assert (foo ()), 1); +int b = (assert (foo ()), 2); + +int +main () +{ + double c = 1.0; + unsigned char *d = 0; + int e = (assert (foo ()), 3); + + bar (c); + bar (d); + bar (e); +} + +namespace N +{ + int f = (assert (foo ()), 4); +} + +void __attribute__((noinline)) +__assert_fail (const char *cond, const char *file, unsigned int line, + const char *pretty) throw () +{ + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/pretty3.C b/gcc/testsuite/g++.dg/ext/pretty3.C new file mode 100644 index 000000000..01b14579a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pretty3.C @@ -0,0 +1,19 @@ +// PR c++/16630 +// { dg-do compile } +// { dg-options "" } +extern "C" int printf (const char*, ...); + +template <class T> +struct B { typedef T X; }; + +template <class U> +struct D +{ + const char* foo (typename B<U>::X) { return __PRETTY_FUNCTION__; } +}; + +int main () +{ + printf ("%s\n", D<int>().foo (0)); +} +// { dg-final { scan-assembler "const char\\* D<U>::foo\\(typename B<U>::X\\)" } } diff --git a/gcc/testsuite/g++.dg/ext/restrict1.C b/gcc/testsuite/g++.dg/ext/restrict1.C new file mode 100644 index 000000000..049af1fa4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/restrict1.C @@ -0,0 +1,7 @@ +// PR c++/6392 +// { dg-do compile } + +struct A +{ + int* __restrict__ data[10]; +}; diff --git a/gcc/testsuite/g++.dg/ext/selectany1.C b/gcc/testsuite/g++.dg/ext/selectany1.C new file mode 100644 index 000000000..e80fe4fd1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/selectany1.C @@ -0,0 +1,20 @@ +// { dg-do compile { target i?86-pc-cygwin } } +// { dg-do compile { target i?86-*-mingw* x86_64-*-mingw* } } + +// Check that selectany attribute puts symbols into link-once sections. + +// { dg-final { scan-assembler "\.section\t\.data\\\$foo\[^\n\]*\n\t\.linkonce discard" } } +// { dg-final { scan-assembler "\.section\t\.data\\\$x\[^\n\]*\n\t\.linkonce discard" } } + +__declspec (selectany) int foo = 1; + +class X +{ +private: + int m_i; +public: + X(int i): m_i(i){} + ~X(){} +}; + +__declspec(selectany) X x(1); diff --git a/gcc/testsuite/g++.dg/ext/selectany2.C b/gcc/testsuite/g++.dg/ext/selectany2.C new file mode 100644 index 000000000..278b32d2f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/selectany2.C @@ -0,0 +1,30 @@ +// { dg-do compile { target i?86-pc-cygwin } } +// { dg-do compile { target i?86-*-mingw* x86_64-*-mingw* } } + +// Check for errors with invalid usage of selectany attribute. + +extern int foo; +__declspec (selectany) int foo = 1; // OK + +struct d +{ + static int foo; +}; +__declspec (selectany) int d::foo = 1; // OK + +struct f +{ + int i; +}; +__declspec (selectany) struct f F= {1}; // OK + +__declspec (selectany) int boo; //{ dg-error "selectany" } + +__declspec (selectany) static int bar = 1; // { dg-error "selectany" } +int use_bar = bar; // Avoid defined but not used warning. + +int baz() +{ + __declspec (selectany) int foo = 1; // { dg-error "selectany" } + return foo; +} diff --git a/gcc/testsuite/g++.dg/ext/spe1.C b/gcc/testsuite/g++.dg/ext/spe1.C new file mode 100644 index 000000000..8b1e630ec --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/spe1.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ + +typedef int v2si __attribute__ ((vector_size (8))); + +/* The two specializations must be considered different. */ +template <class T> class X { }; +template <> class X<__ev64_opaque__> { }; +template <> class X<v2si> { }; diff --git a/gcc/testsuite/g++.dg/ext/static1.C b/gcc/testsuite/g++.dg/ext/static1.C new file mode 100644 index 000000000..9298b1d57 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/static1.C @@ -0,0 +1,18 @@ +// PR c++/23699 +// { dg-options "" } + +template<typename _CharT > class basic_string; +typedef basic_string<char> string; +template<typename _CharT> +struct basic_string +{ + static const int npos = -1; +}; +template<typename _CharT> +const int basic_string<_CharT>::npos; + +extern template class basic_string<char>; +struct A +{ + static const long npos = string::npos; +}; diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr1.C b/gcc/testsuite/g++.dg/ext/stmtexpr1.C new file mode 100644 index 000000000..fe9f3c3aa --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr1.C @@ -0,0 +1,53 @@ +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 30 Jul 2003 <nathan@codesourcery.com> + +// make sure statement expressions work properly + +// { dg-do run } +// { dg-options "" } + +extern "C" int printf (char const *, ...); +extern "C" void abort (); + +static unsigned order[] = +{ + 1, 101, 2, 102, + 3, 4, 104, 103, + 5, 6, 105, 106, + 7, 107, 8, 408, 9, 109, 108, + 10, 11, 110, 411, 12, 112, 111, + 13, 113, + 14, 214, 114, 114, + 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__); } +}; + +int main () +{ + ({A<1> (); A<2> (); ;}); + ({A<3> (), A<4> (); ;}); + ({A<5> (), A<6> ();}); + ({A <7> (); A<8> (); }).Foo (), A<9> (); + ({A <10> (), A<11> (); }).Foo (), A<12> (); + ({A<13> a; a; ; }); + ({A<14> a; a; }); + Check (0, 0, 0, "end"); +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr10.C b/gcc/testsuite/g++.dg/ext/stmtexpr10.C new file mode 100644 index 000000000..f7c5f8f59 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr10.C @@ -0,0 +1,16 @@ +/* { dg-do compile } " */ +/* { dg-options "" } */ + +void foo(int i) +{ + (i ? 1 : 2) = ({ X; }); /* { dg-error "" } */ +} + +struct A +{ + ~A (); + void foo() + { + delete this = ({ X; }); /* { dg-error "" } */ + } +}; diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr11.C b/gcc/testsuite/g++.dg/ext/stmtexpr11.C new file mode 100644 index 000000000..8b5c5f847 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr11.C @@ -0,0 +1,15 @@ +// PR c++/31337 +// { dg-options "" } + +struct A +{ + int i[0]; + A(); + A(const A&); + ~A(); +}; + +void foo() +{ + A a = ({ A(); }); +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr12.C b/gcc/testsuite/g++.dg/ext/stmtexpr12.C new file mode 100644 index 000000000..c35f41b0c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr12.C @@ -0,0 +1,7 @@ +// PR c++/29000 +// { dg-options "" } + +template<int> int foo() +{ + return ({foo;})==0; // { dg-error "insufficient context" } +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr13.C b/gcc/testsuite/g++.dg/ext/stmtexpr13.C new file mode 100644 index 000000000..978da1584 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr13.C @@ -0,0 +1,9 @@ +// PR c++/35747 +// { dg-do compile } +// { dg-options "" } + +void +foo () +{ + ({ i; ({ i; }); 0; }); // { dg-error "was not declared" } +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr2.C b/gcc/testsuite/g++.dg/ext/stmtexpr2.C new file mode 100644 index 000000000..5301103d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr2.C @@ -0,0 +1,51 @@ +// { dg-do run } +// { dg-options "" } + +extern "C" int printf (char const *, ...); +extern "C" void abort (); + +// There are two alternate legal renderings. +static unsigned int alt1[] = { 11, 10, 21, 110, 111, 121 }; +static unsigned int alt2[] = { 10, 11, 21, 111, 110, 121 }; + +static unsigned int pointer = 0; +static unsigned int *which; + +static void Check (unsigned t, unsigned i, void const *ptr, char const *name) +{ + printf ("%d %d %p %s\n", t, i, ptr, name); + + if (pointer > sizeof(alt1)/sizeof(alt1[0])) + abort (); + if (pointer == 0) + { + if (t + i == alt1[0]) + which = &alt1[0]; + else if (t + i == alt2[0]) + which = &alt2[0]; + else + abort (); + } + else if (t + i != which[pointer]) + abort (); + pointer++; +} + +struct A +{ + int I; + + A (int i) : I(i) { Check (0, I, this, __PRETTY_FUNCTION__); } + ~A () { Check (100, I, this, __PRETTY_FUNCTION__); } + A (A const &a) : I(a.I) { Check (200, I, this, __PRETTY_FUNCTION__); } + A &operator= (A const &a) + { I = a.I; Check (300, I, this, __PRETTY_FUNCTION__); return *this; } + void Foo () const { Check (400, I, this, __PRETTY_FUNCTION__); } + A operator+ (A const &a) const + { return A(I + a.I); } +}; + +int main () +{ + ({ A(10) + A(11); }); +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr3.C b/gcc/testsuite/g++.dg/ext/stmtexpr3.C new file mode 100644 index 000000000..9a3205c08 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr3.C @@ -0,0 +1,9 @@ +// PR c++/16112 +// { dg-options "" } + +struct A +{ + A(); +}; + +A foo() { return ({ A(); }); } diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr4.C b/gcc/testsuite/g++.dg/ext/stmtexpr4.C new file mode 100644 index 000000000..a37c33ae0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr4.C @@ -0,0 +1,8 @@ +// PR c++/20147 +// { dg-do compile } +// { dg-options "" } + +void foo() +{ + ({x;}); // { dg-error "was not declared" } +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr5.C b/gcc/testsuite/g++.dg/ext/stmtexpr5.C new file mode 100644 index 000000000..fc84981ce --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr5.C @@ -0,0 +1,15 @@ +// PR c++/21440 +// { dg-options "" } + +struct Foo { + ~Foo(); + int i; +}; + +void bar() { + Foo foo = ({ + Foo bletch; + bletch.i = 0; + bletch; + }); +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr6.C b/gcc/testsuite/g++.dg/ext/stmtexpr6.C new file mode 100644 index 000000000..d2518a64a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr6.C @@ -0,0 +1,11 @@ +// { dg-do run } +// { dg-options "" } + +int a[128]; + +int main() { + // Check that array-to-pointer conversion occurs in a + // statement-expression. + if (sizeof (({ a; })) != sizeof (int *)) + return 1; +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr7.C b/gcc/testsuite/g++.dg/ext/stmtexpr7.C new file mode 100644 index 000000000..87ca39b56 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr7.C @@ -0,0 +1,14 @@ +// PR c++/24686 +// { dg-options "" } + +struct A +{ + ~A(); +}; +bool h(int, const A&); +int f(); +int i; +void g() +{ + i && (A(), ({ static int l = f(); l; })); +} diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr8.C b/gcc/testsuite/g++.dg/ext/stmtexpr8.C new file mode 100644 index 000000000..8e5d0ddcb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr8.C @@ -0,0 +1,28 @@ +// PR c++/27115 + +// { dg-do run } +// { dg-options "" } + +struct A +{ + int i; + A (int j) : i(j) {} + A (const A &j) : i(j.i) {} + A& operator= (const A &j) { i = j.i; return *this; } +}; + +A foo(int j) +{ + return ({ j ? A(1) : A(0); }); +} + +int main() +{ + return foo(1).i-1; +} + +void foo2() +{ + A b = ({ A a(1); a; }); +} + diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr9.C b/gcc/testsuite/g++.dg/ext/stmtexpr9.C new file mode 100644 index 000000000..4963e10e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr9.C @@ -0,0 +1,8 @@ +// PR c++/28899 +// { dg-options "" } + +void f() +{ + unsigned l, l1; + l1 = l = ({ unsigned __v; __v; }); +} diff --git a/gcc/testsuite/g++.dg/ext/strncpy-chk1.C b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C new file mode 100644 index 000000000..7770ba931 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/strncpy-chk1.C @@ -0,0 +1,31 @@ +// PR c++/40502 +// { dg-do compile } +// { dg-options "-O2" } + +struct A { char x[12], y[35]; }; +struct B { char z[50]; }; + +inline void +foo (char *dest, const char *__restrict src, __SIZE_TYPE__ n) +{ + __builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0)); // { dg-warning "will always overflow" } +} + +void bar (const char *, int); + +inline void +baz (int i) +{ + char s[128], t[32]; + bar (s, 0); + bar (t, i); + A a; + B b; + foo (a.y, b.z, 36); +} + +void +test () +{ + baz (0); +} diff --git a/gcc/testsuite/g++.dg/ext/sync-1.C b/gcc/testsuite/g++.dg/ext/sync-1.C new file mode 100644 index 000000000..e4d6dff61 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/sync-1.C @@ -0,0 +1,40 @@ +// Validate that the __sync builtins are overloaded properly. +// { dg-do compile } +// { dg-options "-Werror" } + +#define TEST1(TYPE, BUILTIN) \ +void t_##TYPE##BUILTIN(TYPE *p) \ +{ \ + __typeof(BUILTIN(p, 1)) *pp; \ + pp = p; \ +} + +#define TEST2(BUILTIN) \ + TEST1(int, BUILTIN) \ + TEST1(long, BUILTIN) + +TEST2(__sync_fetch_and_add) +TEST2(__sync_fetch_and_sub) +TEST2(__sync_fetch_and_or) +TEST2(__sync_fetch_and_and) +TEST2(__sync_fetch_and_xor) +TEST2(__sync_fetch_and_nand) + +TEST2(__sync_add_and_fetch) +TEST2(__sync_sub_and_fetch) +TEST2(__sync_or_and_fetch) +TEST2(__sync_and_and_fetch) +TEST2(__sync_xor_and_fetch) +TEST2(__sync_nand_and_fetch) + +TEST2(__sync_lock_test_and_set) + +#define TEST3(TYPE) \ +void t_##TYPE##__sync_val_compare_and_swap(TYPE *p) \ +{ \ + __typeof(__sync_val_compare_and_swap(p, 1, 2)) *pp; \ + pp = p; \ +} + +TEST3(int) +TEST3(long) diff --git a/gcc/testsuite/g++.dg/ext/sync-2.C b/gcc/testsuite/g++.dg/ext/sync-2.C new file mode 100644 index 000000000..5695684c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/sync-2.C @@ -0,0 +1,58 @@ +// Validate that the __sync builtins are overloaded properly in templates. +// { dg-do compile } +// { dg-options "-Werror" } + + +#define TEST1(BUILTIN) \ +template<typename T> \ +void f##BUILTIN(T *p) \ +{ \ + __typeof(BUILTIN(p, 1)) *pp; \ + pp = p; \ +} + +TEST1(__sync_fetch_and_add) +TEST1(__sync_fetch_and_sub) +TEST1(__sync_fetch_and_or) +TEST1(__sync_fetch_and_and) +TEST1(__sync_fetch_and_xor) +TEST1(__sync_fetch_and_nand) + +TEST1(__sync_add_and_fetch) +TEST1(__sync_sub_and_fetch) +TEST1(__sync_or_and_fetch) +TEST1(__sync_and_and_fetch) +TEST1(__sync_xor_and_fetch) +TEST1(__sync_nand_and_fetch) + +TEST1(__sync_lock_test_and_set) + +template<typename T> +void f__sync_val_compare_and_swap(T *p) +{ + __typeof(__sync_val_compare_and_swap(p, 1, 2)) *pp; + pp = p; +} + +#define TEST2(TYPE) \ +void h_##TYPE () \ +{ \ + TYPE x; \ + f__sync_fetch_and_add (&x); \ + f__sync_fetch_and_sub (&x); \ + f__sync_fetch_and_or (&x); \ + f__sync_fetch_and_and (&x); \ + f__sync_fetch_and_xor (&x); \ + f__sync_fetch_and_nand (&x); \ + f__sync_add_and_fetch (&x); \ + f__sync_sub_and_fetch (&x); \ + f__sync_or_and_fetch (&x); \ + f__sync_and_and_fetch (&x); \ + f__sync_xor_and_fetch (&x); \ + f__sync_nand_and_fetch (&x); \ + f__sync_lock_test_and_set (&x); \ + f__sync_val_compare_and_swap (&x); \ +} + +TEST2(int) +TEST2(long) diff --git a/gcc/testsuite/g++.dg/ext/sync-3.C b/gcc/testsuite/g++.dg/ext/sync-3.C new file mode 100644 index 000000000..99faac7bc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/sync-3.C @@ -0,0 +1,21 @@ +// PR debug/41801 +// { dg-do compile } +// { dg-options "-O2 -g" } + +struct T +{ + void + foo () volatile + { + __sync_lock_release (&t); + __sync_synchronize (); + } + bool t; +}; + +int +main () +{ + T t = { false }; + t.foo (); +} diff --git a/gcc/testsuite/g++.dg/ext/tmplattr1.C b/gcc/testsuite/g++.dg/ext/tmplattr1.C new file mode 100644 index 000000000..111e3441f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr1.C @@ -0,0 +1,24 @@ +// PR c++/24260 +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-require-effective-target ilp32 } + +#define stdcall __attribute__((stdcall)) + +struct T { + template <class S> + static int stdcall func(int arg1, int arg2); +}; + +template <class S> +int stdcall T::func(int arg1, int arg2) +{ + return arg1+arg2; +} + +struct dummy {}; + +void xx() +{ + int (stdcall *ptr2)(int,int) = &T::func<dummy>; +} + diff --git a/gcc/testsuite/g++.dg/ext/tmplattr2.C b/gcc/testsuite/g++.dg/ext/tmplattr2.C new file mode 100644 index 000000000..4fd651d6c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr2.C @@ -0,0 +1,18 @@ +// PR c++/17743 + +template <unsigned Len, unsigned Align> +struct aligned_storage +{ + typedef char type[Len] __attribute__((aligned((Align)))); +}; + +template<typename T> +struct X +{ + typename aligned_storage<sizeof(T),__alignof(T)>::type data; +}; + +template<bool> struct StaticAssert; +template<> struct StaticAssert<true> {}; + +StaticAssert<__alignof (X<double>) == __alignof (double)> dummy; diff --git a/gcc/testsuite/g++.dg/ext/tmplattr3.C b/gcc/testsuite/g++.dg/ext/tmplattr3.C new file mode 100644 index 000000000..f8d3c1620 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr3.C @@ -0,0 +1,42 @@ +// PR c++/17743 + +template<typename T> +struct X { + typedef char layout_type[sizeof(T)] + __attribute ((aligned(__alignof(double)))); + layout_type data; +}; + +template<typename T> +struct Y { + typedef char layout_type[sizeof(T)] + __attribute ((aligned(__alignof(T)))); + layout_type data; +}; + +template<typename T> +struct Z { + typedef char layout_type[sizeof(T)] + __attribute ((aligned(__alignof(T)))); + struct Z2 { + layout_type data; + } in; +}; + +template<typename T> +struct A; + +template <typename T> +struct A<T*> { + typedef char layout_type[sizeof(T)] + __attribute ((aligned(__alignof(T)))); + layout_type data; +}; + +template<bool> struct StaticAssert; +template<> struct StaticAssert<true> {}; + +StaticAssert<__alignof(X<double>) == __alignof(double)> d1; +StaticAssert<__alignof(Y<double>) == __alignof(double)> d2; +StaticAssert<__alignof(Z<double>) == __alignof(double)> d3; +StaticAssert<__alignof(A<double*>) == __alignof(double)> d4; diff --git a/gcc/testsuite/g++.dg/ext/tmplattr4.C b/gcc/testsuite/g++.dg/ext/tmplattr4.C new file mode 100644 index 000000000..3d5c6b7d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr4.C @@ -0,0 +1,19 @@ +// PR c++/7586 +// { dg-do run } + +template<typename T> +int f() +{ + typedef unsigned char type[sizeof (T)] + __attribute((aligned(__alignof(T)))); + + return __alignof (type); +} + +int main() +{ + if (f<int>() == __alignof (int)) + return 0; + else + return 1; +} diff --git a/gcc/testsuite/g++.dg/ext/tmplattr5.C b/gcc/testsuite/g++.dg/ext/tmplattr5.C new file mode 100644 index 000000000..30138d44a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr5.C @@ -0,0 +1,33 @@ +// PR c++/19407 +// { dg-do run } + +typedef float global_vector_type __attribute__((vector_size(16))); + +template <class T> struct A +{ + typedef T type; +}; + +template < typename Val > struct S +{ + typedef typename A<Val>::type vector_type __attribute__((vector_size(16))); + typedef Val vector_type2 __attribute__((vector_size(16))); + int pr_size() { return sizeof(vector_type); } + int pr_size2() { return sizeof(vector_type2); } +}; + +int main() +{ + if (sizeof (S<float>::vector_type) != sizeof (global_vector_type)) + return 1; + if (sizeof (S<float>::vector_type2) != sizeof (global_vector_type)) + return 2; + + S<float> x; + if (x.pr_size() != sizeof (global_vector_type)) + return 3; + if (x.pr_size2() != sizeof (global_vector_type)) + return 4; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/tmplattr6.C b/gcc/testsuite/g++.dg/ext/tmplattr6.C new file mode 100644 index 000000000..17f23fe34 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr6.C @@ -0,0 +1,12 @@ +// Don't crash on an unknown attribute. + +struct foo { + template <class T> + void __attribute__((leafify)) bar() {} // { dg-warning "ignored" } +}; + +void bar(void) +{ + foo f; + f.bar<int>(); +} diff --git a/gcc/testsuite/g++.dg/ext/tmplattr7.C b/gcc/testsuite/g++.dg/ext/tmplattr7.C new file mode 100644 index 000000000..ee6c41847 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr7.C @@ -0,0 +1,11 @@ +// PR c++/33620 + +template <typename T> +struct __attribute__((visibility("default"))) List {}; + +int bar(List<int> args); +bool test(const List<int> &); + +int i = bar(List<int>()); + +bool test(const List<int> &) {} diff --git a/gcc/testsuite/g++.dg/ext/tmplattr8.C b/gcc/testsuite/g++.dg/ext/tmplattr8.C new file mode 100644 index 000000000..4b8707aa5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr8.C @@ -0,0 +1,8 @@ +// PR c++/28560 + +template<typename> struct A {}; + +template<int> struct B; + +template<int N> struct C : + A<typename B<N>::X __attribute__((unused))> {}; // { dg-warning "attribute" } diff --git a/gcc/testsuite/g++.dg/ext/tmplattr9.C b/gcc/testsuite/g++.dg/ext/tmplattr9.C new file mode 100644 index 000000000..090257a5f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr9.C @@ -0,0 +1,26 @@ +// PR c++/34937, 34962 +// { dg-require-weak "" } +// { dg-options "" } + +struct A +{ + static const int i; +}; + +template<int> void foo() +{ + int x[A::i] __attribute((vector_size(8))); +} + +template<int> struct B +{ + enum { a, b = a }; + void bar(B<b>) __attribute((weak)); +}; + +void f() +{ + foo<0>(); + B<0> b; + b.bar (B<B<0>::b>()); +} diff --git a/gcc/testsuite/g++.dg/ext/typedef-init.C b/gcc/testsuite/g++.dg/ext/typedef-init.C new file mode 100644 index 000000000..153303d21 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typedef-init.C @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-fpermissive" } // suppress default -pedantic-errors */ + +/* This code used to be a legitimate, if dubious, extension. However, + it's been broken since GCC 3.0 (caused ICE) and we have now removed + the extension. See PR c/7353. + + For cases A and C, C++ issues a warning in addition to the error, + since this construct appears to be a case of implicit int + (forbidden in std. C++) until we get to the equals sign. */ + +/* Case A: just the bare name = initializer. */ + +typedef A = 0; /* { dg-error "does not name a type" "A" } */ +A a; /* { dg-error "does not name a type" "A error cascade" } */ + +/* Case B: with a type also. */ + +typedef int B = 0; /* { dg-error "initialized" "B" } */ +B b; /* { dg-error "does not name a type" "B error cascade" } */ + +/* C and D are the same as A and B, but wrapped in a structure; + field declarations go by a different code path in C++ (ick). */ + +struct S { + typedef C = 0; /* { dg-error "does not name a type" "C" } */ + C c; /* { dg-error "" "C error cascade" } */ + + typedef int D = 0; /* { dg-error "initialized" "D" } */ + D d; /* { dg-bogus "" "D error cascade" } */ +}; + +template<int> void foo() +{ + typedef int i = 0; /* { dg-error "is initialized" } */ +} diff --git a/gcc/testsuite/g++.dg/ext/typename1.C b/gcc/testsuite/g++.dg/ext/typename1.C new file mode 100644 index 000000000..cb9f4a7fc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typename1.C @@ -0,0 +1,7 @@ +// PR c++/6255 +// { dg-options "-fpermissive -w" } + +template <class T> struct A { typedef int X; }; +template <class T> struct B { typedef A<T> Y; void f (typename Y::X); }; +template <class T, class T1, class T2, class T3> struct C : public B<T> { void g (typename B<T>::Y::X); }; +template class B<int>; diff --git a/gcc/testsuite/g++.dg/ext/typeof1.C b/gcc/testsuite/g++.dg/ext/typeof1.C new file mode 100644 index 000000000..a3c13c8ae --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof1.C @@ -0,0 +1,21 @@ +// Test typeof template argument substitution + +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } +// { dg-options "" } + +template <class T> struct A { + void f() {} + void g(T* t) { + A<typeof(t)> a; + a.f(); + } +}; + +int main() +{ + A<int> a; + int b; + a.g(&b); +} diff --git a/gcc/testsuite/g++.dg/ext/typeof10.C b/gcc/testsuite/g++.dg/ext/typeof10.C new file mode 100644 index 000000000..1b357ad9d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof10.C @@ -0,0 +1,11 @@ +// PR c++/20552 +// Origin: Ivan Godard <igodard@pacbell.net> + +template<int> struct A +{ + void foo() + { + typedef int T; // { dg-error "previous" } + typedef __typeof__(*this) T; // { dg-error "conflicting" } + } +}; diff --git a/gcc/testsuite/g++.dg/ext/typeof11.C b/gcc/testsuite/g++.dg/ext/typeof11.C new file mode 100644 index 000000000..757bcdea4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof11.C @@ -0,0 +1,18 @@ +// PR c++/37920 + +template<typename T> T& ensure_obj(const T&); +template <typename T> +void func2(T& t) +{ + typedef __typeof__(ensure_obj(t)) ttt; + struct ttt1 + { + ttt1( ttt arg0 ){} + } tttt ( t ); +} +int main() +{ + double d = 5; + func2(d); +} + diff --git a/gcc/testsuite/g++.dg/ext/typeof2.C b/gcc/testsuite/g++.dg/ext/typeof2.C new file mode 100644 index 000000000..3c5112fd0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof2.C @@ -0,0 +1,29 @@ +// Test typeof with __asm redirection +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" { + extern int foo1; + extern int foo1 __asm ("bar1"); + int foo1 = 1; + + extern int foo2 (int); + extern int foo2 (int) __asm ("bar2"); + int foo2 (int x) + { + return x; + } + + extern int foo3; + extern __typeof (foo3) foo3 __asm ("bar3"); + int foo3 = 1; + + extern int foo4 (int); + extern __typeof (foo4) foo4 __asm ("bar4"); + int foo4 (int x) + { + return x; + } +} + +// { dg-final { scan-assembler-not "foo" } } diff --git a/gcc/testsuite/g++.dg/ext/typeof3.C b/gcc/testsuite/g++.dg/ext/typeof3.C new file mode 100644 index 000000000..cf78c7c61 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof3.C @@ -0,0 +1,4 @@ +double f(double); +float f(float); +void h(typeof(f) g) {} // { dg-error "" } + diff --git a/gcc/testsuite/g++.dg/ext/typeof4.C b/gcc/testsuite/g++.dg/ext/typeof4.C new file mode 100644 index 000000000..2f4237035 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof4.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "" } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/9459: typeof in return type of template function + +void foo (int) {} +void foo (double) {} + +template <typename C> +typeof(foo(1)) +bar () { return foo(1); } diff --git a/gcc/testsuite/g++.dg/ext/typeof5.C b/gcc/testsuite/g++.dg/ext/typeof5.C new file mode 100644 index 000000000..d1ee4f718 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof5.C @@ -0,0 +1,8 @@ +// { dg-options "" } + +int foo; + +template <class T> struct Base {}; + +template <class T> +struct Derived : public Base<typeof(foo)> {}; diff --git a/gcc/testsuite/g++.dg/ext/typeof6.C b/gcc/testsuite/g++.dg/ext/typeof6.C new file mode 100644 index 000000000..ef75f255c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof6.C @@ -0,0 +1,17 @@ +// { dg-options "" } + +template <class T> +void test1() { + int x = 0; + const typeof(x) & t1 = x+0; +} + +void test2() { + int x = 0; + const typeof(x) & t1 = x+0; +} + +int main() { + test1<int>(); + test2 (); +} diff --git a/gcc/testsuite/g++.dg/ext/typeof7.C b/gcc/testsuite/g++.dg/ext/typeof7.C new file mode 100644 index 000000000..6c426931b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof7.C @@ -0,0 +1,6 @@ +// PR c++/13635 +// { dg-options "" } + +template<int n> class X {template<class Y> typeof(Y::y) foo();}; +X<0> x; + diff --git a/gcc/testsuite/g++.dg/ext/typeof8.C b/gcc/testsuite/g++.dg/ext/typeof8.C new file mode 100644 index 000000000..8e6523484 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof8.C @@ -0,0 +1,12 @@ +// PR c++/14116 +// Any use of typeof in a templete was causing an ICE. +// { dg-options "" } + +struct vector { typedef int iterator; }; +vector read_queue; +template <class T> void f(){ + typedef typeof (read_queue) read_queue_t; + read_queue_t::iterator it; +} + + diff --git a/gcc/testsuite/g++.dg/ext/typeof9.C b/gcc/testsuite/g++.dg/ext/typeof9.C new file mode 100644 index 000000000..1547c0f2f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/typeof9.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// Origin: gcc-bug@vogtner.de + +// PR c++/14106: ICE with typeof of function template. + +template<class T> +void j (T i) +{ +} + +template<typename T> +void instanciate () { + static void (*fp) (T) = j; + __typeof__ (j) *p; // { dg-error "unknown|invalid" } +} +template void instanciate<float>(); diff --git a/gcc/testsuite/g++.dg/ext/unary_trait_incomplete.C b/gcc/testsuite/g++.dg/ext/unary_trait_incomplete.C new file mode 100644 index 000000000..51cc80cd2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/unary_trait_incomplete.C @@ -0,0 +1,76 @@ +// PR c++/39475 + +struct I; +struct C { }; + +bool nas1 = __has_nothrow_assign(I); // { dg-error "incomplete type" } +bool nas2 = __has_nothrow_assign(C[]); +bool nas3 = __has_nothrow_assign(I[]); // { dg-error "incomplete type" } +bool nas4 = __has_nothrow_assign(void); +bool nas5 = __has_nothrow_assign(const void); + +bool tas1 = __has_trivial_assign(I); // { dg-error "incomplete type" } +bool tas2 = __has_trivial_assign(C[]); +bool tas3 = __has_trivial_assign(I[]); // { dg-error "incomplete type" } +bool tas4 = __has_trivial_assign(void); +bool tas5 = __has_trivial_assign(const void); + +bool nco1 = __has_nothrow_constructor(I); // { dg-error "incomplete type" } +bool nco2 = __has_nothrow_constructor(C[]); +bool nco3 = __has_nothrow_constructor(I[]); // { dg-error "incomplete type" } +bool nco4 = __has_nothrow_constructor(void); +bool nco5 = __has_nothrow_constructor(const void); + +bool tco1 = __has_trivial_constructor(I); // { dg-error "incomplete type" } +bool tco2 = __has_trivial_constructor(C[]); +bool tco3 = __has_trivial_constructor(I[]); // { dg-error "incomplete type" } +bool tco4 = __has_trivial_constructor(void); +bool tco5 = __has_trivial_constructor(const void); + +bool ncp1 = __has_nothrow_copy(I); // { dg-error "incomplete type" } +bool ncp2 = __has_nothrow_copy(C[]); +bool ncp3 = __has_nothrow_copy(I[]); // { dg-error "incomplete type" } +bool ncp4 = __has_nothrow_copy(void); +bool ncp5 = __has_nothrow_copy(const void); + +bool tcp1 = __has_trivial_copy(I); // { dg-error "incomplete type" } +bool tcp2 = __has_trivial_copy(C[]); +bool tcp3 = __has_trivial_copy(I[]); // { dg-error "incomplete type" } +bool tcp4 = __has_trivial_copy(void); +bool tcp5 = __has_trivial_copy(const void); + +bool vde1 = __has_virtual_destructor(I); // { dg-error "incomplete type" } +bool vde2 = __has_virtual_destructor(C[]); +bool vde3 = __has_virtual_destructor(I[]); // { dg-error "incomplete type" } +bool vde4 = __has_virtual_destructor(void); +bool vde5 = __has_virtual_destructor(const void); + +bool tde1 = __has_trivial_destructor(I); // { dg-error "incomplete type" } +bool tde2 = __has_trivial_destructor(C[]); +bool tde3 = __has_trivial_destructor(I[]); // { dg-error "incomplete type" } +bool tde4 = __has_trivial_destructor(void); +bool tde5 = __has_trivial_destructor(const void); + +bool abs1 = __is_abstract(I); // { dg-error "incomplete type" } +bool abs2 = __is_abstract(C[]); +bool abs3 = __is_abstract(I[]); // { dg-error "incomplete type" } +bool abs4 = __is_abstract(void); +bool abs5 = __is_abstract(const void); + +bool pod1 = __is_pod(I); // { dg-error "incomplete type" } +bool pod2 = __is_pod(C[]); +bool pod3 = __is_pod(I[]); // { dg-error "incomplete type" } +bool pod4 = __is_pod(void); +bool pod5 = __is_pod(const void); + +bool emp1 = __is_empty(I); // { dg-error "incomplete type" } +bool emp2 = __is_empty(C[]); +bool emp3 = __is_empty(I[]); // { dg-error "incomplete type" } +bool emp4 = __is_empty(void); +bool emp5 = __is_empty(const void); + +bool pol1 = __is_polymorphic(I); // { dg-error "incomplete type" } +bool pol2 = __is_polymorphic(C[]); +bool pol3 = __is_polymorphic(I[]); // { dg-error "incomplete type" } +bool pol4 = __is_polymorphic(void); +bool pol5 = __is_polymorphic(const void); diff --git a/gcc/testsuite/g++.dg/ext/uow-1.C b/gcc/testsuite/g++.dg/ext/uow-1.C new file mode 100644 index 000000000..fdf6aebb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/uow-1.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +extern "C" { + +typedef int UOW; +struct ABC { + UOW UOW; +}; + +} + diff --git a/gcc/testsuite/g++.dg/ext/uow-2.C b/gcc/testsuite/g++.dg/ext/uow-2.C new file mode 100644 index 000000000..79c1913f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/uow-2.C @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall -fms-extensions" } */ + +typedef int UOW; +struct ABC { + UOW UOW; +}; + diff --git a/gcc/testsuite/g++.dg/ext/uow-3.C b/gcc/testsuite/g++.dg/ext/uow-3.C new file mode 100644 index 000000000..a2c224021 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/uow-3.C @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +typedef int UOW; /* { dg-error "" } */ +struct ABC { + UOW UOW; /* { dg-error "" } */ +}; + diff --git a/gcc/testsuite/g++.dg/ext/uow-4.C b/gcc/testsuite/g++.dg/ext/uow-4.C new file mode 100644 index 000000000..21ed04a88 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/uow-4.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall -pedantic" } */ + +extern "C" { + +typedef int UOW; /* { dg-error "" } */ +struct ABC { + UOW UOW; /* { dg-error "" } */ +}; + +} + diff --git a/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C new file mode 100644 index 000000000..a549f6973 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C @@ -0,0 +1,36 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x -fshort-wchar" } */ + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-error "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-error "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; /* { dg-error "chars is too long" } */ +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char32_t s32_4[0] = U"ab"; /* { dg-error "chars is too long" } */ +const char32_t s32_5[1] = U"ab"; /* { dg-error "chars is too long" } */ +const char32_t s32_6[2] = U"ab"; /* { dg-error "chars is too long" } */ +const char32_t s32_7[3] = U"ab"; +const char32_t s32_8[4] = U"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; diff --git a/gcc/testsuite/g++.dg/ext/utf-array.C b/gcc/testsuite/g++.dg/ext/utf-array.C new file mode 100644 index 000000000..6a14f79e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-array.C @@ -0,0 +1,36 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char16_t/char32_t string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +const char s_0[] = "ab"; +const char s_1[] = u"ab"; /* { dg-error "from wide string" } */ +const char s_2[] = U"ab"; /* { dg-error "from wide string" } */ +const char s_3[] = L"ab"; /* { dg-error "from wide string" } */ + +const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char16_t s16_1[] = u"ab"; +const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char16_t s16_4[0] = u"ab"; /* { dg-error "chars is too long" } */ +const char16_t s16_5[1] = u"ab"; /* { dg-error "chars is too long" } */ +const char16_t s16_6[2] = u"ab"; /* { dg-error "chars is too long" } */ +const char16_t s16_7[3] = u"ab"; +const char16_t s16_8[4] = u"ab"; + +const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */ +const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const char32_t s32_2[] = U"ab"; +const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */ + +const char32_t s32_4[0] = U"ab"; /* { dg-error "chars is too long" } */ +const char32_t s32_5[1] = U"ab"; /* { dg-error "chars is too long" } */ +const char32_t s32_6[2] = U"ab"; /* { dg-error "chars is too long" } */ +const char32_t s32_7[3] = U"ab"; +const char32_t s32_8[4] = U"ab"; + +const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */ +const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */ +const wchar_t sw_3[] = L"ab"; diff --git a/gcc/testsuite/g++.dg/ext/utf-badconcat.C b/gcc/testsuite/g++.dg/ext/utf-badconcat.C new file mode 100644 index 000000000..bab020e4f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-badconcat.C @@ -0,0 +1,22 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test unsupported concatenation of char16_t/char32_t* string literals. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +const void *s0 = u"a" "b"; +const void *s1 = "a" u"b"; +const void *s2 = u"a" U"b"; /* { dg-error "non-standard concatenation" } */ +const void *s3 = U"a" u"b"; /* { dg-error "non-standard concatenation" } */ +const void *s4 = u"a" L"b"; /* { dg-error "non-standard concatenation" } */ +const void *s5 = L"a" u"b"; /* { dg-error "non-standard concatenation" } */ +const void *s6 = u"a" u"b"; +const void *s7 = U"a" "b"; +const void *s8 = "a" U"b"; +const void *s9 = U"a" L"b"; /* { dg-error "non-standard concatenation" } */ +const void *sa = L"a" U"b"; /* { dg-error "non-standard concatenation" } */ +const void *sb = U"a" U"b"; +const void *sc = L"a" "b"; +const void *sd = "a" L"b"; +const void *se = L"a" L"b"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-badconcat2.C b/gcc/testsuite/g++.dg/ext/utf-badconcat2.C new file mode 100644 index 000000000..499b323fc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-badconcat2.C @@ -0,0 +1,15 @@ +// Test unsupported concatenation of UTF-8 string literals. +// { dg-do compile } +// { dg-options "-std=c++0x" } + +const void *s0 = u8"a" "b"; +const void *s1 = "a" u8"b"; +const void *s2 = u8"a" u8"b"; +const void *s3 = u8"a" u"b"; // { dg-error "non-standard concatenation" } +const void *s4 = u"a" u8"b"; // { dg-error "non-standard concatenation" } +const void *s5 = u8"a" U"b"; // { dg-error "non-standard concatenation" } +const void *s6 = U"a" u8"b"; // { dg-error "non-standard concatenation" } +const void *s7 = u8"a" L"b"; // { dg-error "non-standard concatenation" } +const void *s8 = L"a" u8"b"; // { dg-error "non-standard concatenation" } + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-cvt.C b/gcc/testsuite/g++.dg/ext/utf-cvt.C new file mode 100644 index 000000000..286a0d007 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-cvt.C @@ -0,0 +1,55 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test the char16_t and char32_t promotion rules. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x -Wall -Wconversion -Wsign-conversion -Wsign-promo" } */ + +extern void f_c (char); +extern void fsc (signed char); +extern void fuc (unsigned char); +extern void f_s (short); +extern void fss (signed short); +extern void fus (unsigned short); +extern void f_i (int); +extern void fsi (signed int); +extern void fui (unsigned int); +extern void f_l (long); +extern void fsl (signed long); +extern void ful (unsigned long); +extern void f_ll (long long); +extern void fsll (signed long long); +extern void full (unsigned long long); + +void m(char16_t c0, char32_t c1) +{ + f_c (c0); /* { dg-warning "alter its value" } */ + fsc (c0); /* { dg-warning "alter its value" } */ + fuc (c0); /* { dg-warning "alter its value" } */ + f_s (c0); /* { dg-warning "change the sign" } */ + fss (c0); /* { dg-warning "change the sign" } */ + fus (c0); + f_i (c0); + fsi (c0); + fui (c0); + f_l (c0); + fsl (c0); + ful (c0); + f_ll (c0); + fsll (c0); + full (c0); + + f_c (c1); /* { dg-warning "alter its value" } */ + fsc (c1); /* { dg-warning "alter its value" } */ + fuc (c1); /* { dg-warning "alter its value" } */ + f_s (c1); /* { dg-warning "alter its value" } */ + fss (c1); /* { dg-warning "alter its value" } */ + fus (c1); /* { dg-warning "alter its value" } */ + f_i (c1); /* { dg-warning "change the sign" } */ + fsi (c1); /* { dg-warning "change the sign" } */ + fui (c1); + f_l (c1); /* { dg-warning "change the sign" "" { target { llp64 || ilp32 } } } */ + fsl (c1); /* { dg-warning "change the sign" "" { target { llp64 || ilp32 } } } */ + ful (c1); + f_ll (c1); + fsll (c1); + full (c1); +} diff --git a/gcc/testsuite/g++.dg/ext/utf-cxx0x.C b/gcc/testsuite/g++.dg/ext/utf-cxx0x.C new file mode 100644 index 000000000..1daa0dee4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-cxx0x.C @@ -0,0 +1,14 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test parsing of u and U prefixes when also used as macros. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +#define u L +#define U L + +const unsigned short c2 = u'a'; +const unsigned long c3 = U'a'; +const void *s0 = u"a"; +const void *s1 = U"a"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-cxx98.C b/gcc/testsuite/g++.dg/ext/utf-cxx98.C new file mode 100644 index 000000000..a8dd13a4e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-cxx98.C @@ -0,0 +1,29 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char16_t/char32_t in c++98. */ +/* Ensure u and U prefixes are parsed as separate tokens in c++98. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++98" } */ + +const static char16_t c0 = 'a'; /* { dg-error "not name a type" } */ +const static char32_t c1 = 'a'; /* { dg-error "not name a type" } */ + +const unsigned short c2 = u'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 10 } */ +const unsigned long c3 = U'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 12 } */ + +#define u 1 + +#define U 2 + + +const unsigned short c5 = u'a'; +const unsigned long c6 = U'a'; + +#undef u +#undef U +#define u "a" +#define U "b" + +const void *s0 = u"a"; +const void *s1 = U"a"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-dflt.C b/gcc/testsuite/g++.dg/ext/utf-dflt.C new file mode 100644 index 000000000..942f2b26d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-dflt.C @@ -0,0 +1,29 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char16_t/char32_t in default std. */ +/* Ensure u and U prefixes are parsed as separate tokens in default std. */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +const static char16_t c0 = 'a'; /* { dg-error "not name a type" } */ +const static char32_t c1 = 'a'; /* { dg-error "not name a type" } */ + +const unsigned short c2 = u'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 10 } */ +const unsigned long c3 = U'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 12 } */ + +#define u 1 + +#define U 2 + + +const unsigned short c4 = u'a'; +const unsigned long c5 = U'a'; + +#undef u +#undef U +#define u "a" +#define U "b" + +const void *s0 = u"a"; +const void *s1 = U"a"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-dflt2.C b/gcc/testsuite/g++.dg/ext/utf-dflt2.C new file mode 100644 index 000000000..fd2222f67 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-dflt2.C @@ -0,0 +1,12 @@ +// In C++0x, the u8 prefix should be parsed as separate tokens. +// { dg-do compile } +// { dg-options "-std=c++98" } + +const void *s0 = u8"a"; // { dg-error "was not declared" } + // { dg-error "expected ',' or ';'" "" { target *-*-* } 5 } + +#define u8 "a" + +const void *s1 = u8"a"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-gnuxx0x.C b/gcc/testsuite/g++.dg/ext/utf-gnuxx0x.C new file mode 100644 index 000000000..0a6967fe4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-gnuxx0x.C @@ -0,0 +1,14 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test parsing of u and U prefixes when also used as macros. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu++0x" } */ + +#define u L +#define U L + +const unsigned short c2 = u'a'; +const unsigned long c3 = U'a'; +const void *s0 = u"a"; +const void *s1 = U"a"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-gnuxx98.C b/gcc/testsuite/g++.dg/ext/utf-gnuxx98.C new file mode 100644 index 000000000..fc8068b7e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-gnuxx98.C @@ -0,0 +1,29 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char16_t/char32_t in gnu++98. */ +/* Ensure u and U prefixes are parsed as separate tokens in gnu++98. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu++98" } */ + +const static char16_t c0 = 'a'; /* { dg-error "not name a type" } */ +const static char32_t c1 = 'a'; /* { dg-error "not name a type" } */ + +const unsigned short c2 = u'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 10 } */ +const unsigned long c3 = U'a'; /* { dg-error "not declared" } */ + /* { dg-error "expected ',' or ';'" "" { target *-*-* } 12 } */ + +#define u 1 + +#define U 2 + + +const unsigned short c5 = u'a'; +const unsigned long c6 = U'a'; + +#undef u +#undef U +#define u "a" +#define U "b" + +const void *s0 = u"a"; +const void *s1 = U"a"; + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf-mangle.C b/gcc/testsuite/g++.dg/ext/utf-mangle.C new file mode 100644 index 000000000..a13188788 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-mangle.C @@ -0,0 +1,14 @@ +// Contributed by Kris Van Hees <kris.van.hees@oracle.com> +// Test the support for char16_t character constants. +// { dg-do compile } +// { dg-options "-std=c++0x" } + +void f0 (char16_t c) {} +void f1 (char32_t c) {} +void f2 (char16_t *s) {} +void f3 (char32_t *s) {} + +// { dg-final { scan-assembler "_Z2f0Ds:" } } +// { dg-final { scan-assembler "_Z2f1Di:" } } +// { dg-final { scan-assembler "_Z2f2PDs:" } } +// { dg-final { scan-assembler "_Z2f3PDi:" } } diff --git a/gcc/testsuite/g++.dg/ext/utf-rtti.C b/gcc/testsuite/g++.dg/ext/utf-rtti.C new file mode 100644 index 000000000..b5d201b4d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-rtti.C @@ -0,0 +1,12 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Ensure that typeinfo data is generated for char16_t/char32_t. */ +/* { dg-do link } */ +/* { dg-options "-std=c++0x" } */ + +#include <typeinfo> + +int main(void) +{ + typeid(char16_t).name(); + typeid(char32_t).name(); +} diff --git a/gcc/testsuite/g++.dg/ext/utf-type.C b/gcc/testsuite/g++.dg/ext/utf-type.C new file mode 100644 index 000000000..41a83ff2e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-type.C @@ -0,0 +1,15 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Ensure that __CHAR16_TYPE__ and __CHAR32_TYPE__ exist, match the types they + are the underlying data type for. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +int main () +{ + if (sizeof (__CHAR16_TYPE__) != sizeof (char16_t)) + abort(); + if (sizeof (__CHAR32_TYPE__) != sizeof (char32_t)) + abort(); +} diff --git a/gcc/testsuite/g++.dg/ext/utf-typedef-cxx0x.C b/gcc/testsuite/g++.dg/ext/utf-typedef-cxx0x.C new file mode 100644 index 000000000..641e836e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-typedef-cxx0x.C @@ -0,0 +1,7 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Ensure that a typedef to char16_t/char32_t issues an error in c++0x. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +typedef short unsigned int char16_t; /* { dg-error "redeclaration" } */ +typedef unsigned int char32_t; /* { dg-error "redeclaration" } */ diff --git a/gcc/testsuite/g++.dg/ext/utf-typedef-cxx98.C b/gcc/testsuite/g++.dg/ext/utf-typedef-cxx98.C new file mode 100644 index 000000000..8922856c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-typedef-cxx98.C @@ -0,0 +1,7 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Ensure that a typedef to char16_t/char32_t is fine in c++98. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++98" } */ + +typedef short unsigned int char16_t; +typedef unsigned int char32_t; diff --git a/gcc/testsuite/g++.dg/ext/utf-typespec.C b/gcc/testsuite/g++.dg/ext/utf-typespec.C new file mode 100644 index 000000000..6a4af2559 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf-typespec.C @@ -0,0 +1,25 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Ensure that type specifiers are not allowed for char16_t/char32_t. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +signed char16_t c0; /* { dg-error "signed" } */ +signed char32_t c1; /* { dg-error "signed" } */ +unsigned char16_t c2; /* { dg-error "unsigned" } */ +unsigned char32_t c3; /* { dg-error "unsigned" } */ + +short char16_t c4; /* { dg-error "short" } */ +long char16_t c5; /* { dg-error "long" } */ +short char32_t c6; /* { dg-error "short" } */ +long char32_t c7; /* { dg-error "long" } */ + +signed short char16_t c8; /* { dg-error "signed" } */ +signed short char32_t c9; /* { dg-error "signed" } */ +signed long char16_t ca; /* { dg-error "signed" } */ +signed long char32_t cb; /* { dg-error "signed" } */ +unsigned short char16_t cc; /* { dg-error "unsigned" } */ +unsigned short char32_t cd; /* { dg-error "unsigned" } */ +unsigned long char16_t ce; /* { dg-error "unsigned" } */ +unsigned long char32_t cf; /* { dg-error "unsigned" } */ + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf16-1.C b/gcc/testsuite/g++.dg/ext/utf16-1.C new file mode 100644 index 000000000..fa07de912 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf16-1.C @@ -0,0 +1,65 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test the support for char16_t character constants. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +const static char16_t c0 = u'a'; +const static char16_t c1 = u'\0'; +const static char16_t c2 = u'\u0024'; +const static char16_t c3 = u'\u2029'; +const static char16_t c4 = u'\u8010'; + +const static char16_t c5 = 'a'; +const static char16_t c6 = U'a'; +const static char16_t c7 = U'\u2029'; +const static char16_t c8 = U'\u8010'; +const static char16_t c9 = L'a'; +const static char16_t ca = L'\u2029'; +const static char16_t cb = L'\u8010'; + +#define A 0x0061 +#define D 0x0024 +#define X 0x2029 +#define Y 0x8010 + +int main () +{ + if (sizeof (u'a') != sizeof (char16_t)) + abort (); + if (sizeof (u'\0') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u0024') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u2029') != sizeof (char16_t)) + abort (); + if (sizeof (u'\u8010') != sizeof (char16_t)) + abort (); + + if (c0 != A) + abort (); + if (c1 != 0x0000) + abort (); + if (c2 != D) + abort (); + if (c3 != X) + abort (); + if (c4 != Y) + abort (); + + if (c5 != A) + abort (); + if (c6 != A) + abort (); + if (c7 != X) + abort (); + if (c8 != Y) + abort (); + if (c9 != A) + abort (); + if (ca != X) + abort (); + if (cb != Y) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/utf16-2.C b/gcc/testsuite/g++.dg/ext/utf16-2.C new file mode 100644 index 000000000..d7a6056f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf16-2.C @@ -0,0 +1,30 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test the support for char16_t* string literals. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +const static char16_t *s0 = u"ab"; +const static char16_t *s1 = u"a\u0024"; +const static char16_t *s2 = u"a\u2029"; +const static char16_t *s3 = u"a\U00064321"; + +#define A 0x0061 +#define B 0x0062 +#define D 0x0024 +#define X 0x2029 +#define Y1 0xD950 +#define Y2 0xDF21 + +int main () +{ + if (s0[0] != A || s0[1] != B || s0[2] != 0x0000) + abort (); + if (s1[0] != A || s1[1] != D || s0[2] != 0x0000) + abort (); + if (s2[0] != A || s2[1] != X || s0[2] != 0x0000) + abort (); + if (s3[0] != A || s3[1] != Y1 || s3[2] != Y2 || s3[3] != 0x0000) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/utf16-3.C b/gcc/testsuite/g++.dg/ext/utf16-3.C new file mode 100644 index 000000000..183347b6e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf16-3.C @@ -0,0 +1,47 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test concatenation of char16_t* string literals. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +const static char16_t *s0 = u"a" u"b"; + +const static char16_t *s1 = u"a" "b"; +const static char16_t *s2 = "a" u"b"; +const static char16_t *s3 = u"a" "\u2029"; +const static char16_t *s4 = "\u2029" u"b"; +const static char16_t *s5 = u"a" "\U00064321"; +const static char16_t *s6 = "\U00064321" u"b"; + +#define A 0x0061 +#define B 0x0062 +#define X 0x2029 +#define Y1 0xD950 +#define Y2 0xDF21 + +int main () +{ + if (sizeof ((u"a" u"b")[0]) != sizeof (char16_t)) + abort (); + if (sizeof ((u"a" "b")[0]) != sizeof (char16_t)) + abort (); + if (sizeof (( "a" u"b")[0]) != sizeof (char16_t)) + abort (); + + if (s0[0] != A || s0[1] != B || s0[2] != 0x0000) + abort (); + + if (s1[0] != A || s1[1] != B || s1[2] != 0x0000) + abort (); + if (s2[0] != A || s2[1] != B || s2[2] != 0x0000) + abort (); + if (s3[0] != A || s3[1] != X || s3[2] != 0x0000) + abort (); + if (s4[0] != X || s4[1] != B || s4[2] != 0x0000) + abort (); + if (s5[0] != A || s5[1] != Y1 || s5[2] != Y2 || s5[3] != 0x0000) + abort (); + if (s6[0] != Y1 || s6[1] != Y2 || s6[2] != B || s6[3] != 0x0000) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/utf16-4.C b/gcc/testsuite/g++.dg/ext/utf16-4.C new file mode 100644 index 000000000..21cdb53bd --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf16-4.C @@ -0,0 +1,18 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char16_t character constants. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +const static char16_t c0 = u''; /* { dg-error "empty character" } */ +const static char16_t c1 = u'ab'; /* { dg-warning "constant too long" } */ +const static char16_t c2 = u'\U00064321'; /* { dg-warning "constant too long" } */ + +const static char16_t c3 = 'a'; +const static char16_t c4 = U'a'; +const static char16_t c5 = U'\u2029'; +const static char16_t c6 = U'\U00064321'; /* { dg-warning "implicitly truncated" } */ +const static char16_t c7 = L'a'; +const static char16_t c8 = L'\u2029'; +const static char16_t c9 = L'\U00064321'; /* { dg-warning "implicitly truncated" "" { target { 4byte_wchar_t } } 16 } */ + /* { dg-warning "constant too long" "" { target { ! 4byte_wchar_t } } 16 } */ +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf32-1.C b/gcc/testsuite/g++.dg/ext/utf32-1.C new file mode 100644 index 000000000..98465a0a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf32-1.C @@ -0,0 +1,42 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test the support for char32_t character constants. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +const static char32_t c0 = U'a'; +const static char32_t c1 = U'\0'; +const static char32_t c2 = U'\u0024'; +const static char32_t c3 = U'\u2029'; +const static char32_t c4 = U'\U00064321'; + +#define A 0x00000061 +#define D 0x00000024 +#define X 0x00002029 +#define Y 0x00064321 + +int main () +{ + if (sizeof (U'a') != sizeof (char32_t)) + abort (); + if (sizeof (U'\0') != sizeof (char32_t)) + abort (); + if (sizeof (U'\u0024') != sizeof (char32_t)) + abort (); + if (sizeof (U'\u2029') != sizeof (char32_t)) + abort (); + if (sizeof (U'\U00064321') != sizeof (char32_t)) + abort (); + + if (c0 != A) + abort (); + if (c1 != 0x0000) + abort (); + if (c2 != D) + abort (); + if (c3 != X) + abort (); + if (c4 != Y) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/utf32-2.C b/gcc/testsuite/g++.dg/ext/utf32-2.C new file mode 100644 index 000000000..e2256ba74 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf32-2.C @@ -0,0 +1,29 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test the support for char32_t* string constants. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +const static char32_t *s0 = U"ab"; +const static char32_t *s1 = U"a\u0024"; +const static char32_t *s2 = U"a\u2029"; +const static char32_t *s3 = U"a\U00064321"; + +#define A 0x00000061 +#define B 0x00000062 +#define D 0x00000024 +#define X 0x00002029 +#define Y 0x00064321 + +int main () +{ + if (s0[0] != A || s0[1] != B || s0[2] != 0x00000000) + abort (); + if (s1[0] != A || s1[1] != D || s0[2] != 0x00000000) + abort (); + if (s2[0] != A || s2[1] != X || s0[2] != 0x00000000) + abort (); + if (s3[0] != A || s3[1] != Y || s3[2] != 0x00000000) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/utf32-3.C b/gcc/testsuite/g++.dg/ext/utf32-3.C new file mode 100644 index 000000000..bba893cef --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf32-3.C @@ -0,0 +1,46 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Test concatenation of char32_t* string literals. */ +/* { dg-do run } */ +/* { dg-options "-std=c++0x -Wall -Werror" } */ + +extern "C" void abort (void); + +const static char32_t *s0 = U"a" U"b"; + +const static char32_t *s1 = U"a" "b"; +const static char32_t *s2 = "a" U"b"; +const static char32_t *s3 = U"a" "\u2029"; +const static char32_t *s4 = "\u2029" U"b"; +const static char32_t *s5 = U"a" "\U00064321"; +const static char32_t *s6 = "\U00064321" U"b"; + +#define A 0x00000061 +#define B 0x00000062 +#define X 0x00002029 +#define Y 0x00064321 + +int main () +{ + if (sizeof ((U"a" U"b")[0]) != sizeof (char32_t)) + abort (); + if (sizeof ((U"a" "b")[0]) != sizeof (char32_t)) + abort (); + if (sizeof (( "a" U"b")[0]) != sizeof (char32_t)) + abort (); + + if (s0[0] != A || s0[1] != B || s0[2] != 0x00000000) + abort (); + + if (s1[0] != A || s1[1] != B || s1[2] != 0x00000000) + abort (); + if (s2[0] != A || s2[1] != B || s2[2] != 0x00000000) + abort (); + if (s3[0] != A || s3[1] != X || s3[2] != 0x00000000) + abort (); + if (s4[0] != X || s4[1] != B || s4[2] != 0x00000000) + abort (); + if (s5[0] != A || s5[1] != Y || s5[2] != 0x00000000) + abort (); + if (s6[0] != Y || s6[1] != B || s6[2] != 0x00000000) + abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/utf32-4.C b/gcc/testsuite/g++.dg/ext/utf32-4.C new file mode 100644 index 000000000..744fea7c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf32-4.C @@ -0,0 +1,18 @@ +/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */ +/* Expected errors for char32_t character constants. */ +/* { dg-do compile } */ +/* { dg-options "-std=c++0x" } */ + +const static char32_t c0 = U''; /* { dg-error "empty character" } */ +const static char32_t c1 = U'ab'; /* { dg-warning "constant too long" } */ +const static char32_t c2 = U'\U00064321'; + +const static char32_t c3 = 'a'; +const static char32_t c4 = u'a'; +const static char32_t c5 = u'\u2029'; +const static char32_t c6 = u'\U00064321'; /* { dg-warning "constant too long" } */ +const static char32_t c7 = L'a'; +const static char32_t c8 = L'\u2029'; +const static char32_t c9 = L'\U00064321'; /* { dg-warning "constant too long" "" { target { ! 4byte_wchar_t } } } */ + +int main () {} diff --git a/gcc/testsuite/g++.dg/ext/utf8-1.C b/gcc/testsuite/g++.dg/ext/utf8-1.C new file mode 100644 index 000000000..203b326af --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf8-1.C @@ -0,0 +1,45 @@ +// { dg-do run } +// { dg-require-iconv "ISO-8859-2" } +// { dg-options "-std=c++0x -fexec-charset=ISO-8859-2" } + +const char *str1 = "h\u00e1\U0000010Dky "; +const char *str2 = "\u010d\u00E1rky\n"; +const char *str3 = u8"h\u00e1\U0000010Dky "; +const char *str4 = u8"\u010d\u00E1rky\n"; +const char *str5 = "h\u00e1\U0000010Dky " "\u010d\u00E1rky\n"; +const char *str6 = u8"h\u00e1\U0000010Dky " "\u010d\u00E1rky\n"; +const char *str7 = "h\u00e1\U0000010Dky " u8"\u010d\u00E1rky\n"; +#define u8 +const char *str8 = u8"h\u00e1\U0000010Dky " u8"\u010d\u00E1rky\n"; + +const char latin2_1[] = "\x68\xe1\xe8\x6b\x79\x20"; +const char latin2_2[] = "\xe8\xe1\x72\x6b\x79\n"; +const char utf8_1[] = "\x68\xc3\xa1\xc4\x8d\x6b\x79\x20"; +const char utf8_2[] = "\xc4\x8d\xc3\xa1\x72\x6b\x79\n"; + +int +main (void) +{ + if (__builtin_strcmp (str1, latin2_1) != 0 + || __builtin_strcmp (str2, latin2_2) != 0 + || __builtin_strcmp (str3, utf8_1) != 0 + || __builtin_strcmp (str4, utf8_2) != 0 + || __builtin_strncmp (str5, latin2_1, sizeof (latin2_1) - 1) != 0 + || __builtin_strcmp (str5 + sizeof (latin2_1) - 1, latin2_2) != 0 + || __builtin_strncmp (str6, utf8_1, sizeof (utf8_1) - 1) != 0 + || __builtin_strcmp (str6 + sizeof (utf8_1) - 1, utf8_2) != 0 + || __builtin_strncmp (str7, utf8_1, sizeof (utf8_1) - 1) != 0 + || __builtin_strcmp (str7 + sizeof (utf8_1) - 1, utf8_2) != 0 + || __builtin_strncmp (str8, utf8_1, sizeof (utf8_1) - 1) != 0 + || __builtin_strcmp (str8 + sizeof (utf8_1) - 1, utf8_2) != 0) + __builtin_abort (); + if (sizeof ("a" u8"b"[0]) != 1 + || sizeof (u8"a" "b"[0]) != 1 + || sizeof (u8"a" u8"b"[0]) != 1 + || sizeof ("a" "\u010d") != 3 + || sizeof ("a" u8"\u010d") != 4 + || sizeof (u8"a" "\u010d") != 4 + || sizeof (u8"a" "\u010d") != 4) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/utf8-2.C b/gcc/testsuite/g++.dg/ext/utf8-2.C new file mode 100644 index 000000000..417a8bfdc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/utf8-2.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +const char s0[] = u8"ab"; +const char16_t s1[] = u8"ab"; // { dg-error "from non-wide" } +const char32_t s2[] = u8"ab"; // { dg-error "from non-wide" } +const wchar_t s3[] = u8"ab"; // { dg-error "from non-wide" } + +const char t0[0] = u8"ab"; // { dg-error "chars is too long" } +const char t1[1] = u8"ab"; // { dg-error "chars is too long" } +const char t2[2] = u8"ab"; // { dg-error "chars is too long" } +const char t3[3] = u8"ab"; +const char t4[4] = u8"ab"; + +const char u0[0] = u8"\u2160."; // { dg-error "chars is too long" } +const char u1[1] = u8"\u2160."; // { dg-error "chars is too long" } +const char u2[2] = u8"\u2160."; // { dg-error "chars is too long" } +const char u3[3] = u8"\u2160."; // { dg-error "chars is too long" } +const char u4[4] = u8"\u2160."; // { dg-error "chars is too long" } +const char u5[5] = u8"\u2160."; +const char u6[6] = u8"\u2160."; diff --git a/gcc/testsuite/g++.dg/ext/va-arg-pack-1.C b/gcc/testsuite/g++.dg/ext/va-arg-pack-1.C new file mode 100644 index 000000000..b81d0e58d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/va-arg-pack-1.C @@ -0,0 +1,145 @@ +// __builtin_va_arg_pack () builtin tests. +// { dg-do run } +// { dg-options "-O2" } + +#include <stdarg.h> + +extern "C" void abort (void); + +int v1 = 8; +long int v2 = 3; +void *v3 = (void *) &v2; +struct A { char c[16]; } v4 = { "foo" }; +long double v5 = 40; +char seen[20]; +int cnt; + +__attribute__ ((noinline)) int +foo1 (int x, int y, ...) +{ + int i; + long int l; + void *v; + struct A a; + long double ld; + va_list ap; + + va_start (ap, y); + if (x < 0 || x >= 20 || seen[x]) + abort (); + seen[x] = ++cnt; + if (y != 6) + abort (); + i = va_arg (ap, int); + if (i != 5) + abort (); + switch (x) + { + case 0: + i = va_arg (ap, int); + if (i != 9 || v1 != 9) + abort (); + a = va_arg (ap, struct A); + if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0) + abort (); + v = (void *) va_arg (ap, struct A *); + if (v != (void *) &v4) + abort (); + l = va_arg (ap, long int); + if (l != 3 || v2 != 4) + abort (); + break; + case 1: + ld = va_arg (ap, long double); + if (ld != 41 || v5 != ld) + abort (); + i = va_arg (ap, int); + if (i != 8) + abort (); + v = va_arg (ap, void *); + if (v != &v2) + abort (); + break; + case 2: + break; + default: + abort (); + } + va_end (ap); + return x; +} + +__attribute__ ((noinline)) int +foo2 (int x, int y, ...) +{ + long long int ll; + void *v; + struct A a, b; + long double ld; + va_list ap; + + va_start (ap, y); + if (x < 0 || x >= 20 || seen[x]) + abort (); + seen[x] = ++cnt | 64; + if (y != 10) + abort (); + switch (x) + { + case 11: + break; + case 12: + ld = va_arg (ap, long double); + if (ld != 41 || v5 != 40) + abort (); + a = va_arg (ap, struct A); + if (__builtin_memcmp (a.c, v4.c, sizeof (a.c)) != 0) + abort (); + b = va_arg (ap, struct A); + if (__builtin_memcmp (b.c, v4.c, sizeof (b.c)) != 0) + abort (); + v = va_arg (ap, void *); + if (v != &v2) + abort (); + ll = va_arg (ap, long long int); + if (ll != 16LL) + abort (); + break; + case 2: + break; + default: + abort (); + } + va_end (ap); + return x + 8; +} + +__attribute__ ((noinline)) int +foo3 (void) +{ + return 6; +} + +extern inline __attribute__ ((always_inline, gnu_inline)) int +bar (int x, ...) +{ + if (x < 10) + return foo1 (x, foo3 (), 5, __builtin_va_arg_pack ()); + return foo2 (x, foo3 () + 4, __builtin_va_arg_pack ()); +} + +int +main (void) +{ + if (bar (0, ++v1, v4, &v4, v2++) != 0) + abort (); + if (bar (1, ++v5, 8, v3) != 1) + abort (); + if (bar (2) != 2) + abort (); + if (bar (v1 + 2) != 19) + abort (); + if (bar (v1 + 3, v5--, v4, v4, v3, 16LL) != 20) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/va-arg-pack-2.C b/gcc/testsuite/g++.dg/ext/va-arg-pack-2.C new file mode 100644 index 000000000..c5d3e2ac5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/va-arg-pack-2.C @@ -0,0 +1,46 @@ +// { dg-do compile } +// { dg-options "-O2" } + +int bar (int, const char *, int, ...); +int baz (int, const char *, long int); + +extern inline __attribute__((always_inline)) int +f2 (int y, ...) +{ + return bar (y, "", __builtin_va_arg_pack ()); /* { dg-error "invalid use of" } */ +} + +extern inline __attribute__((always_inline)) int +f3 (int y, ...) +{ + return bar (y, "", 5, __builtin_va_arg_pack ()); +} + +extern inline __attribute__((always_inline)) int +f4 (int y, ...) +{ + return bar (y, "", 4, __builtin_va_arg_pack (), 6); /* { dg-error "invalid use of" } */ +} + +extern inline __attribute__((always_inline)) int +f5 (int y, ...) +{ + return baz (y, "", __builtin_va_arg_pack ()); /* { dg-error "invalid use of" } */ +} + +extern inline __attribute__((always_inline)) int +f6 (int y, ...) +{ + return __builtin_va_arg_pack (); /* { dg-error "invalid use of" } */ +} + +int +test (void) +{ + int a = f2 (5, "a", 6); + a += f3 (6, "ab", 17LL); + a += f4 (7, 1, 2, 3); + a += f5 (8, 7L); + a += f6 (9); + return a; +} diff --git a/gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C b/gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C new file mode 100644 index 000000000..d3c84091b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/va-arg-pack-len-1.C @@ -0,0 +1,122 @@ +// { dg-do run } +// { dg-options "-O2" } + +#include <stdarg.h> + +extern "C" int error_open_missing_mode (void) + __attribute__((__error__ ("open with O_CREAT needs 3 arguments, only 2 were given"))); +extern "C" int warn_open_too_many_arguments (void) + __attribute__((__warning__ ("open called with more than 3 arguments"))); +extern "C" void abort (void); + +char expected_char; + +__attribute__((noinline)) int +myopen2 (const char *path, int oflag) +{ + if (expected_char++ != path[0] || path[1] != '\0') + abort (); + switch (path[0]) + { + case 'f': + if (oflag != 0x2) + abort (); + break; + case 'g': + if (oflag != 0x43) + abort (); + // In real __open_2 this would terminate the program: + // open with O_CREAT without third argument. + return -6; + default: + abort (); + } + return 0; +} + +__attribute__((noinline)) int +myopenva (const char *path, int oflag, ...) +{ + int mode = 0; + va_list ap; + if ((oflag & 0x40) != 0) + { + va_start (ap, oflag); + mode = va_arg (ap, int); + va_end (ap); + } + if (expected_char++ != path[0] || path[1] != '\0') + abort (); + switch (path[0]) + { + case 'a': + if (oflag != 0x43 || mode != 0644) + abort (); + break; + case 'b': + if (oflag != 0x3) + abort (); + break; + case 'c': + if (oflag != 0x2) + abort (); + break; + case 'd': + if (oflag != 0x43 || mode != 0600) + abort (); + break; + case 'e': + if (oflag != 0x3) + abort (); + break; + default: + abort (); + } + return 0; +} + +extern inline __attribute__((always_inline, gnu_inline)) int +myopen (const char *path, int oflag, ...) +{ + if (__builtin_va_arg_pack_len () > 1) + warn_open_too_many_arguments (); + + if (__builtin_constant_p (oflag)) + { + if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1) + { + error_open_missing_mode (); + return myopen2 (path, oflag); + } + return myopenva (path, oflag, __builtin_va_arg_pack ()); + } + + if (__builtin_va_arg_pack_len () < 1) + return myopen2 (path, oflag); + + return myopenva (path, oflag, __builtin_va_arg_pack ()); +} + +volatile int l0; + +int +main (void) +{ + expected_char = 'a'; + if (myopen ("a", 0x43, 0644)) + abort (); + if (myopen ("b", 0x3, 0755)) + abort (); + if (myopen ("c", 0x2)) + abort (); + if (myopen ("d", l0 + 0x43, 0600)) + abort (); + if (myopen ("e", l0 + 0x3, 0700)) + abort (); + if (myopen ("f", l0 + 0x2)) + abort (); + // Invalid use of myopen, but only detectable at runtime. + if (myopen ("g", l0 + 0x43) != -6) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/va-arg-pack-len-2.C b/gcc/testsuite/g++.dg/ext/va-arg-pack-len-2.C new file mode 100644 index 000000000..0d369bdc9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/va-arg-pack-len-2.C @@ -0,0 +1,42 @@ +// { dg-do compile } +// { dg-options "-O2" } + +#include <stdarg.h> + +extern int error_open_missing_mode (void) + __attribute__((__error__ ("open with O_CREAT needs 3 arguments, only 2 were given"))); +extern int warn_open_too_many_arguments (void) + __attribute__((__warning__ ("open called with more than 3 arguments"))); + +extern int myopen2 (const char *path, int oflag); +extern int myopenva (const char *path, int oflag, ...); + +extern inline __attribute__((always_inline, gnu_inline)) int +myopen (const char *path, int oflag, ...) +{ + if (__builtin_va_arg_pack_len () > 1) + warn_open_too_many_arguments (); // { dg-warning "called with more than 3" } + + if (__builtin_constant_p (oflag)) + { + if ((oflag & 0x40) != 0 && __builtin_va_arg_pack_len () < 1) + { + error_open_missing_mode (); // { dg-error "needs 3 arguments, only 2 were given" } + return myopen2 (path, oflag); + } + return myopenva (path, oflag, __builtin_va_arg_pack ()); + } + + if (__builtin_va_arg_pack_len () < 1) + return myopen2 (path, oflag); + + return myopenva (path, oflag, __builtin_va_arg_pack ()); +} + +int +main (void) +{ + myopen ("h", 0x43); + myopen ("i", 0x43, 0644, 0655); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/va-arg1.C b/gcc/testsuite/g++.dg/ext/va-arg1.C new file mode 100644 index 000000000..079db2e5c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/va-arg1.C @@ -0,0 +1,8 @@ +// PR c++/33462 + +struct A {}; + +void foo() +{ + ++__builtin_va_arg(0, A); // { dg-error "'\\+\\+va_arg\\(0, A\\)'" } +} diff --git a/gcc/testsuite/g++.dg/ext/vector1.C b/gcc/testsuite/g++.dg/ext/vector1.C new file mode 100644 index 000000000..c6f0e0409 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector1.C @@ -0,0 +1,5 @@ +// PR c++/11895 +// This used to ICE in reshape_init. +// testcase from fnf@ninemoons.com + + __attribute__((vector_size(16))) int a1 = { 100, 200, 300, 400 }; diff --git a/gcc/testsuite/g++.dg/ext/vector10.C b/gcc/testsuite/g++.dg/ext/vector10.C new file mode 100644 index 000000000..46ea244c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector10.C @@ -0,0 +1,11 @@ +// PR c++/34914 +// { dg-do compile } + +struct A { int __attribute ((vector_size (8))) x; }; + +void +foo () +{ + __attribute ((vector_size (8))) int A::*p; + p == 0; +} diff --git a/gcc/testsuite/g++.dg/ext/vector11.C b/gcc/testsuite/g++.dg/ext/vector11.C new file mode 100644 index 000000000..a3213522b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector11.C @@ -0,0 +1,6 @@ +// PR c++/34913 + +template<typename T> struct A +{ + int x[sizeof(T)] __attribute((vector_size(8))); +}; diff --git a/gcc/testsuite/g++.dg/ext/vector12.C b/gcc/testsuite/g++.dg/ext/vector12.C new file mode 100644 index 000000000..e0b6d2ba6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector12.C @@ -0,0 +1,4 @@ +// PR c++/34917 +// { dg-do compile } + +const int i __attribute ((vector_size (8))) = {}; diff --git a/gcc/testsuite/g++.dg/ext/vector13.C b/gcc/testsuite/g++.dg/ext/vector13.C new file mode 100644 index 000000000..5160f1121 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector13.C @@ -0,0 +1,6 @@ +// PR c++/35096 +// { dg-do compile } + +typedef const int X __attribute((vector_size(8))); +extern const int x[] __attribute((vector_size(8))); +X x[] = { 5 }; diff --git a/gcc/testsuite/g++.dg/ext/vector14.C b/gcc/testsuite/g++.dg/ext/vector14.C new file mode 100644 index 000000000..8e792108f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector14.C @@ -0,0 +1,22 @@ +// PR c++/35758 +// { dg-do compile } +// { dg-options "-msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } +// { dg-require-effective-target sse } +// Ignore warning on some powerpc-linux configurations. +// { dg-prune-output "non-standard ABI extension" } +// { dg-prune-output "mangled name" } + +#define vector __attribute__((vector_size(16))) + +template<int N> vector signed int foo (vector float value) {} + +template<int> void foo (float) {} + +int +main () +{ + vector float v; + float f; + foo<1> (v); + foo<1> (f); +} diff --git a/gcc/testsuite/g++.dg/ext/vector15.C b/gcc/testsuite/g++.dg/ext/vector15.C new file mode 100644 index 000000000..7058bf1b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector15.C @@ -0,0 +1,5 @@ +/* { dg-do compile } */ + +/* Check that we error out when using vector_size on the bool type. */ + +__attribute__((vector_size(16) )) bool a; /* { dg-error "" } */ diff --git a/gcc/testsuite/g++.dg/ext/vector16.C b/gcc/testsuite/g++.dg/ext/vector16.C new file mode 100644 index 000000000..7964a881f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector16.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +#define vector __attribute__((vector_size(4*sizeof(int)) )) + +vector int a, b, c; + + +/* Test that remainder works for vectors. */ +void f(void) +{ + a = b % c; +} diff --git a/gcc/testsuite/g++.dg/ext/vector2.C b/gcc/testsuite/g++.dg/ext/vector2.C new file mode 100644 index 000000000..c1737dbb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector2.C @@ -0,0 +1,12 @@ +// PR c++/23337; caused an ICE in component_ref_field_offset +// { dg-options "" } +// { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +// { dg-prune-output "mangled name" } +typedef int vec __attribute__ ((vector_size (8))); +extern int bar (vec); +int +foo (int i) +{ + vec a[] = { (vec) { 0, i }, (vec) { 4, 5 } }; + return bar (a[0]) + bar (a[1]); +} diff --git a/gcc/testsuite/g++.dg/ext/vector3.C b/gcc/testsuite/g++.dg/ext/vector3.C new file mode 100644 index 000000000..1a67cf76a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector3.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +// PR c++/28302 + +int __attribute__((vector_size(8))) x; + +void foo() +{ + ~x; +} + diff --git a/gcc/testsuite/g++.dg/ext/vector4.C b/gcc/testsuite/g++.dg/ext/vector4.C new file mode 100644 index 000000000..e14578489 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector4.C @@ -0,0 +1,6 @@ +/* { dg-options "" } */ +/* { dg-do compile } */ +// Testing if we can do a new of a vector +// PR C++/28450 + +void* q = new int __attribute__((vector_size(8))) (); diff --git a/gcc/testsuite/g++.dg/ext/vector5.C b/gcc/testsuite/g++.dg/ext/vector5.C new file mode 100644 index 000000000..e5304bcb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector5.C @@ -0,0 +1,8 @@ +// PR c++/30022 +// { dg-do compile } + +void foo() +{ + int __attribute__((vector_size(8))) v; + v = 1/v; // { dg-error "invalid operands of types" } +} diff --git a/gcc/testsuite/g++.dg/ext/vector6.C b/gcc/testsuite/g++.dg/ext/vector6.C new file mode 100644 index 000000000..9caf8c2f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector6.C @@ -0,0 +1,12 @@ +// { dg-options "" } +// { dg-do compile } +// C++/30016, we were allowing conversion between vector types +// and union types which is invalid. + +typedef float __v_4F __attribute__ ((vector_size (16))); +typedef union {__v_4F v; float a[4];} __v4F; +void f(void) +{ + __v_4F b; + (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/ext/vector7.C b/gcc/testsuite/g++.dg/ext/vector7.C new file mode 100644 index 000000000..cd259b1a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector7.C @@ -0,0 +1,8 @@ +// { dg-options "" } +// { dg-do compile } +// PR C++/31721 and PR 14217 +// the attribute vector_size would change a reference type into a pointer type which was wrong. + +#define vector __attribute__((__vector_size__(16) )) +vector int b; +vector int &a = b; diff --git a/gcc/testsuite/g++.dg/ext/vector8.C b/gcc/testsuite/g++.dg/ext/vector8.C new file mode 100644 index 000000000..5f9f9561d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector8.C @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +/* Check for application of |, ^, and & on vector types. */ +#define vector __attribute__((vector_size(16) )) + +vector float a; +vector int a1; +vector float b; +vector int b1; + +int f(void) +{ + a = a | b; /* { dg-error "" } */ + a = a & b; /* { dg-error "" } */ + a = a ^ b; /* { dg-error "" } */ + a1 = a1 | b1; + a1 = a1 & b1; + a1 = a1 ^ b1; +} + diff --git a/gcc/testsuite/g++.dg/ext/vector9.C b/gcc/testsuite/g++.dg/ext/vector9.C new file mode 100644 index 000000000..52b3f1714 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vector9.C @@ -0,0 +1,10 @@ +// PR c++/34891 + +typedef float v4f __attribute__((vector_size(8))); +typedef int v4i __attribute__((vector_size(8))); + +void foo() +{ + v4f v; + !(v4i)v; // { dg-error "v4i|argument" } +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon1.C b/gcc/testsuite/g++.dg/ext/visibility/anon1.C new file mode 100644 index 000000000..16647b228 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon1.C @@ -0,0 +1,10 @@ +// PR c++/21581 +// Test for anonymous namespace internal linkage + +// { dg-do compile } +// { dg-final { scan-assembler-not "globl.*_ZN.*1fEv" } } + +namespace +{ + int f() { } +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon10.C b/gcc/testsuite/g++.dg/ext/visibility/anon10.C new file mode 100644 index 000000000..8c79631b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon10.C @@ -0,0 +1,44 @@ +// http://bugzilla.redhat.com/411871 +// { dg-do compile } + +extern "C" int printf (const char *, ...); + +struct E +{ + template <typename T> E (const volatile T&); + template <typename T> E (T&); + char x[64]; +}; + +template<typename T> struct D +{ + static E foo (E, ...); + static int foo (T, int); +}; + +template<typename T, typename U> struct C +{ + static T ca; + static const int value = sizeof (D<U>::foo (ca, 0)) == sizeof (int); +}; + +struct A +{ + int a; +}; + +namespace +{ + struct B + { + int a; + }; +} + +int bar (void) +{ + C<A, int> a; + C<B, int> b; + + return a.value + b.value; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon11.C b/gcc/testsuite/g++.dg/ext/visibility/anon11.C new file mode 100644 index 000000000..dfb4f12bb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon11.C @@ -0,0 +1,13 @@ +// PR c++/55877 +// { dg-final { scan-assembler-not "\\.local" } } + +typedef struct { + typedef enum { X, Y } A; + typedef struct { } B; + struct C { }; +} D; + +D d; +D::A a; +D::B b; +D::C c; diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon2.C b/gcc/testsuite/g++.dg/ext/visibility/anon2.C new file mode 100644 index 000000000..1d8e479b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon2.C @@ -0,0 +1,11 @@ +// Test for propagation of anonymous namespace internal linkage + +// { dg-do compile } +// { dg-final { scan-assembler-not "globl.*_Z1fv" } } + +namespace +{ + struct A { }; +} + +A f () { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon3.C b/gcc/testsuite/g++.dg/ext/visibility/anon3.C new file mode 100644 index 000000000..9def559d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon3.C @@ -0,0 +1,16 @@ +// PR c++/31187 +// Bug: the repeated declaration was confusing the compiler into +// thinking that foo1 had language internal linkage. + +class foo { }; + +namespace +{ + extern foo foo1; + foo foo1; +} + +template< foo * > +class bar { }; + +bar< &foo1 > bar1; diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon4.C b/gcc/testsuite/g++.dg/ext/visibility/anon4.C new file mode 100644 index 000000000..6d5d58ec3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon4.C @@ -0,0 +1,16 @@ +// PR c++/31903 +// Test for anonymous namespace internal linkage, for typeinfo + +// { dg-do compile } +// { dg-final { scan-assembler-not "globl.*_ZTIN*3fooE" } } + +#include <typeinfo> +namespace +{ + class foo + { + virtual void bar(); + }; +} + +const std::type_info &X = typeid(foo); diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon5.C b/gcc/testsuite/g++.dg/ext/visibility/anon5.C new file mode 100644 index 000000000..d069eeab6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon5.C @@ -0,0 +1,8 @@ +// PR c++/32596 +// { dg-do compile } + +namespace +{ + template<class T> inline void char_less(void) { } + template<> inline void char_less<char>(void) { } +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon6.C b/gcc/testsuite/g++.dg/ext/visibility/anon6.C new file mode 100644 index 000000000..951de4964 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon6.C @@ -0,0 +1,28 @@ +// PR c++/33094 +// { dg-final { scan-assembler "1BIiE1cE" } } +// { dg-final { scan-assembler-not "globl.*1BIiE1cE" } } +// { dg-final { scan-assembler-not "1CIiE1cE" } } + +// Test that B<int>::c is emitted as an internal symbol, and C<int>::c is +// not emitted. + +namespace +{ + template <typename T> + class A + { + virtual T f1() { return c; } + static const T c = 0; + }; + + template <typename T> + class B + { + static const T c = 0; + }; + + template <typename T> const T B<T>::c; + + template class A<int>; + template class B<int>; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon7.C b/gcc/testsuite/g++.dg/ext/visibility/anon7.C new file mode 100644 index 000000000..0c42ea866 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon7.C @@ -0,0 +1,23 @@ +// PR c++/34094 +// { dg-do compile } + +namespace +{ + struct A { + static int bar (); + static int i; // { dg-error "used, but not defined" "" { xfail *-*-* } } + static int j; + static int k; + static int l; + static const int m = 16; + static const int n = 17; + }; + int A::j = 4; + int A::k; + const int A::m; +} + +int foo (void) +{ + return A::i + A::j + A::k + A::m + A::n + A::bar (); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon8.C b/gcc/testsuite/g++.dg/ext/visibility/anon8.C new file mode 100644 index 000000000..8ef8d6823 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon8.C @@ -0,0 +1,35 @@ +// PR c++/34213 +// { dg-do compile } + +template <void (*fn) ()> +void call () // { dg-message "note" } +{ + fn (); +} + +namespace +{ + struct B1 + { + static void fn1 () {} + static void fn4 (); + }; + void fn3 () {} + void B1::fn4 () {} + static void fn5 () {} +} + +int main () +{ + struct B2 + { + static void fn2 () {} + }; + call<&B1::fn1> (); + call<&B2::fn2> (); // { dg-error "not external linkage|no matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 29 } + call<&fn3> (); + call<&B1::fn4> (); + call<&fn5> (); // { dg-error "not external linkage|no matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 33 } +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon9.C b/gcc/testsuite/g++.dg/ext/visibility/anon9.C new file mode 100644 index 000000000..bb752253b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon9.C @@ -0,0 +1,11 @@ +// PR c++/34238 +// { dg-do compile } + +namespace +{ + template <typename T = int> struct A + { + static const bool a = true; + }; +} +struct A<> a; diff --git a/gcc/testsuite/g++.dg/ext/visibility/arm1.C b/gcc/testsuite/g++.dg/ext/visibility/arm1.C new file mode 100644 index 000000000..2c2e3d066 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/arm1.C @@ -0,0 +1,30 @@ +// { dg-do compile { target arm*-*-eabi* arm*-*-symbianelf* } } +// { dg-require-dll "" } +// { dg-options "-fvisibility=hidden" } +// Most class data should be exported. +// { dg-final { scan-not-hidden "_ZTV1S" } } +// { dg-final { scan-not-hidden "_ZTI1S" } } +// { dg-final { scan-not-hidden "_ZTS1S" } } +// { dg-final { scan-not-hidden "_ZTV1U" } } +// { dg-final { scan-not-hidden "_ZTT1U" } } +// { dg-final { scan-not-hidden "_ZTI1U" } } +// { dg-final { scan-not-hidden "_ZTS1U" } } +// The construction vtable should be hidden. +// { dg-final { scan-hidden "_ZTC1U0_1T" } } + +struct S { + virtual void f(); +}; + +void S::f() { +} + +struct T : public virtual S { + virtual void g(); +}; + +struct U : public virtual T { + virtual void h(); +}; + +void U::h() {} diff --git a/gcc/testsuite/g++.dg/ext/visibility/arm2.C b/gcc/testsuite/g++.dg/ext/visibility/arm2.C new file mode 100644 index 000000000..7eed18d7f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/arm2.C @@ -0,0 +1,11 @@ +// { dg-do compile { target arm*-*-*eabi* arm*-*-symbianelf* } } +// Class data should be exported. +// { dg-final { scan-not-hidden "_ZTV1S" } } +// { dg-final { scan-not-hidden "_ZTI1S" } } +// { dg-final { scan-not-hidden "_ZTS1S" } } + +struct S { + virtual void f(); +}; + +void S::f() {} diff --git a/gcc/testsuite/g++.dg/ext/visibility/arm3.C b/gcc/testsuite/g++.dg/ext/visibility/arm3.C new file mode 100644 index 000000000..9be7082ce --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/arm3.C @@ -0,0 +1,36 @@ +// { dg-do compile { target arm*-*-*eabi* } } +// { dg-require-dll "" } +// { dg-options "-fvisibility=hidden" } + +/* From ARM C++ ABI \S 3.2.5.5: + + A class should be exported unless explicitly tagged otherwise. + + This admonition applies even on DLL-based systems where hidden + visibility is the default. We want -fvisibility=hidden to behave + identically to the situation where hidden visibility is the + hard-wired default. So, both A and B are exported classes. + + Furthermore: + + If CAG symbol Y names one of the impedimenta associated with an + exported class X: + + ... + + * Otherwise, if X has no key function: + + - Y is exported from ... each DLL that refers to X and uses Y. + + So, the type-info and virtual-table symbols associated with A and B + must be exported. */ + +// { dg-final { scan-not-hidden "_ZTI1A" } } +// { dg-final { scan-not-hidden "_ZTS1A" } } +// { dg-final { scan-not-hidden "_ZTV1B" } } +// { dg-final { scan-not-hidden "_ZTI1B" } } +// { dg-final { scan-not-hidden "_ZTS1B" } } + +struct A {}; +struct B : virtual public A {}; +B b; diff --git a/gcc/testsuite/g++.dg/ext/visibility/assign1.C b/gcc/testsuite/g++.dg/ext/visibility/assign1.C new file mode 100644 index 000000000..b25999e8e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/assign1.C @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-final { scan-hidden "_ZN1DaSERKS_" } } */ + +struct B { + B& operator=(const B&); +}; + +struct __attribute__((visibility("hidden"))) D : public B { + // The implicit assignment operator should be hidden. +}; + +__attribute__((visibility("hidden"))) D d1; +__attribute__((visibility("hidden"))) D d2; + +void f() { + d1 = d2; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/class1.C b/gcc/testsuite/g++.dg/ext/visibility/class1.C new file mode 100644 index 000000000..792fc7891 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/class1.C @@ -0,0 +1,22 @@ +// PR c++/26905 +// Init should not be hidden, so calling it should use the PLT. + +// { dg-options "-fpic" } +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } +// { dg-require-visibility "" } +// { dg-require-effective-target fpic } +// { dg-final { scan-assembler "InitEv@PLT" } } + +#pragma GCC visibility push(hidden) +struct __attribute__ ((visibility ("default"))) nsINIParser +{ + static void Init(); +}; + +__attribute__ ((visibility ("default"))) +void +CheckCompatibility(void) +{ + nsINIParser::Init(); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-2.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-2.C new file mode 100644 index 000000000..ed38ebefe --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-2.C @@ -0,0 +1,19 @@ +/* Test that -fvisibility-inlines-hidden doesn't affect static variables. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility-inlines-hidden" } */ +/* { dg-final { scan-not-hidden "_ZZN3foo7my_funcEvE1x" } } */ + +struct foo +{ + int my_func() { + static int x; + return x++; + } +}; + +int t() +{ + foo f; + return f.my_func(); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-3.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-3.C new file mode 100644 index 000000000..50885a798 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden-3.C @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility-inlines-hidden" } */ +/* { dg-final { scan-not-hidden "_ZN1IIiE3fooEv" } } */ +/* { dg-final { scan-not-hidden "_ZN1OIiE3fooEv" } } */ +/* { dg-final { scan-hidden "_ZN1S3fooEv" } } */ + +template <class T> +struct O { + static inline void foo() { } +}; + +template void O<int>::foo(); + +template <class T> +struct I { + static inline void foo() { } +}; + +extern template void I<int>::foo(); + +struct S { + static inline void foo() { } +}; + +void bar() { + I<int>::foo(); + O<int>::foo(); + S::foo(); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden.C new file mode 100644 index 000000000..2ee8f0767 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-inlines-hidden.C @@ -0,0 +1,18 @@ +/* Test that -fvisibility-inlines-hidden affects class members. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility-inlines-hidden" } */ +/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */ + +class Foo +{ +public: + void method() { } +}; + +int main(void) +{ + Foo f; + f.method(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override1.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override1.C new file mode 100644 index 000000000..685cd1309 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override1.C @@ -0,0 +1,12 @@ +/* Test that -fvisibility does not override class member specific settings. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility=hidden" } */ +/* { dg-final { scan-not-hidden "methodEv" } } */ + +class __attribute__ ((visibility ("default"))) Foo +{ + void method(); +}; + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C new file mode 100644 index 000000000..4b4b54d5a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility-override2.C @@ -0,0 +1,12 @@ +/* Test that -fvisibility does not override class member specific settings. */ +/* { dg-do compile } */ +/* { dg-require-visibility "internal" } */ +/* { dg-options "-fvisibility=hidden" } */ +/* { dg-final { scan-not-hidden "Foo.methodEv" } } */ + +class Foo +{ + __attribute__ ((visibility ("internal"))) void method(); +}; + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/fvisibility.C b/gcc/testsuite/g++.dg/ext/visibility/fvisibility.C new file mode 100644 index 000000000..4358d25a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/fvisibility.C @@ -0,0 +1,12 @@ +/* Test that -fvisibility affects class members. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility=hidden" } */ +/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */ + +class Foo +{ + void method(); +}; + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/guard1.C b/gcc/testsuite/g++.dg/ext/visibility/guard1.C new file mode 100644 index 000000000..5290e2f8e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/guard1.C @@ -0,0 +1,29 @@ +// { dg-options "-fvisibility=hidden" } +// { dg-require-visibility "" } +// { dg-final { scan-not-hidden "_ZGVZN5otherclEvE4s_cd" } } + +extern "C" int printf (const char *, ...); + +#define DLLEXPORT __attribute__ ((visibility("default"))) + +struct class_data +{ + int apple; + class_data() { printf("non trivial ctor\n"); } +}; + +struct DLLEXPORT other +{ + class_data* operator ()() + { + static class_data s_cd; + return &s_cd; + } +}; + +int main() +{ + other aFoo; + aFoo(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/local1.C b/gcc/testsuite/g++.dg/ext/visibility/local1.C new file mode 100644 index 000000000..7a04db601 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/local1.C @@ -0,0 +1,25 @@ +// PR c++/19238 +// Test that hidden visibility on an inline function is inherited by static +// local variables and local classes. + +// { dg-require-visibility "" } +// { dg-final { scan-hidden "_Z1fv" } } +// { dg-final { scan-hidden "_ZZ1fvE1i" } } +// { dg-final { scan-hidden "_ZZ1fvEN1A1fEv" } } + +__attribute ((visibility ("hidden"))) inline int +f() +{ + static int i = 2; + struct A + { + void f () { } + } a; + a.f(); + return i; +} + +int main() +{ + f(); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/memfuncts.C b/gcc/testsuite/g++.dg/ext/visibility/memfuncts.C new file mode 100644 index 000000000..45eb641b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/memfuncts.C @@ -0,0 +1,11 @@ +/* Test that setting visibility for class member functions works. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */ + +class __attribute__ ((visibility ("hidden"))) Foo +{ + void method(); +}; + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/ms-compat-1.C b/gcc/testsuite/g++.dg/ext/visibility/ms-compat-1.C new file mode 100644 index 000000000..bce2aac55 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/ms-compat-1.C @@ -0,0 +1,28 @@ +/* { dg-require-visibility "" } */ +/* { dg-options "-fvisibility-ms-compat" } */ + +/* { dg-final { scan-not-hidden "_ZTI1S" } } */ +/* { dg-final { scan-hidden "_ZTI1T" } } */ +/* { dg-final { scan-not-hidden "_ZTI1U" } } */ +/* { dg-final { scan-not-hidden "_ZN1U6hide_4Ev" } } */ + +class S { + virtual void hide_2(); +} hide_1; + +void S::hide_2() { +} + +class __attribute__((visibility("hidden"))) T { + virtual void hide_4(); +} hide_3; + +void T::hide_4() { +} + +class __attribute__((visibility("default"))) U { + virtual void hide_4(); +}; + +void U::hide_4() { +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/namespace1.C b/gcc/testsuite/g++.dg/ext/visibility/namespace1.C new file mode 100644 index 000000000..b7773dc9d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/namespace1.C @@ -0,0 +1,30 @@ +// PR c++/21764 +// Test for namespace visibility attribute semantics. + +// { dg-require-visibility "" } +// { dg-final { scan-hidden "_ZN3foo1fEv" } } +// { dg-final { scan-hidden "_ZN3foo1gEv" } } +// { dg-final { scan-hidden "_ZN3foo1A1mEv" } } +// { dg-final { scan-hidden "_ZN3foo1tIiEEvv" } } +// { dg-final { scan-not-hidden "_ZN3foo1hEv" } } + +namespace foo __attribute ((visibility ("hidden"))) +{ + int f() { } + void g(); + template <typename T> void t() { } + class A + { + void m (); + }; +} + +namespace foo +{ + void h() {} +} + +void foo::g() { t<int> (); } + +void foo::A::m() { } + diff --git a/gcc/testsuite/g++.dg/ext/visibility/namespace2.C b/gcc/testsuite/g++.dg/ext/visibility/namespace2.C new file mode 100644 index 000000000..96c5b0953 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/namespace2.C @@ -0,0 +1,20 @@ +// PR c++/32470 + +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } +// { dg-final { scan-hidden "_ZN4Test4testEv" } } + +namespace std __attribute__((__visibility__("default"))) { + template<typename _CharT> + class basic_streambuf + { + friend void getline(); + }; + extern template class basic_streambuf<char>; +} + +class Test +{ + void test(); +}; +void Test::test() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/namespace3.C b/gcc/testsuite/g++.dg/ext/visibility/namespace3.C new file mode 100644 index 000000000..a07abdcd8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/namespace3.C @@ -0,0 +1,6 @@ +// PR c++/41774 +// { dg-do compile } + +namespace std __attribute__ ((__visibility__ ("default"))) { +#pragma GCC visibility pop // { dg-warning "no matching push for" } +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/new1.C b/gcc/testsuite/g++.dg/ext/visibility/new1.C new file mode 100644 index 000000000..ec201cbc2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/new1.C @@ -0,0 +1,13 @@ +// { dg-require-visibility "" } +// { dg-options "-fvisibility=hidden" } +// { dg-final { scan-not-hidden "_Znwj" } } + +void f() { + new int; +} + +void *g(); + +void *operator new(__SIZE_TYPE__) { + return g(); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/noPLT.C b/gcc/testsuite/g++.dg/ext/visibility/noPLT.C new file mode 100644 index 000000000..38af05fd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/noPLT.C @@ -0,0 +1,20 @@ +/* Test that -fvisibility=hidden prevents PLT. */ +/* { dg-do compile { target fpic } } */ +/* { dg-require-visibility "" } */ +/* { dg-options "-fPIC -fvisibility=hidden" } */ +/* { dg-final { scan-assembler-not "methodEv@PLT|indirect_symbol.*methodEv" } } */ + +class Foo +{ +public: + void method(); +}; + +void Foo::method() { } + +int main(void) +{ + Foo f; + f.method(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/overload-1.C b/gcc/testsuite/g++.dg/ext/visibility/overload-1.C new file mode 100644 index 000000000..d841c53fb --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/overload-1.C @@ -0,0 +1,9 @@ +/* Test that visibility of function parameters propagates to an undecorated + function. */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "_Z3fooP8a_struct" } } */ + +struct __attribute__((visibility("hidden"))) a_struct; + +void foo(a_struct * p) +{ } diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C new file mode 100644 index 000000000..4300d1ab1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C @@ -0,0 +1,14 @@ +/* Test that #pragma GCC visibility does not override class member specific settings. */ +/* { dg-do compile } */ +/* { dg-require-visibility "internal" } */ +/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } } } } */ +/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */ + +#pragma GCC visibility push(hidden) +class __attribute__ ((visibility ("internal"))) Foo +{ + void method(); +}; +#pragma GCC visibility pop + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C new file mode 100644 index 000000000..f566cd2f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C @@ -0,0 +1,14 @@ +/* Test that #pragma GCC visibility does not override class member specific settings. */ +/* { dg-do compile } */ +/* { dg-require-visibility "internal" } */ +/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } } } } */ +/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */ + +#pragma GCC visibility push(hidden) +class Foo +{ + __attribute__ ((visibility ("internal"))) void method(); +}; +#pragma GCC visibility pop + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma.C b/gcc/testsuite/g++.dg/ext/visibility/pragma.C new file mode 100644 index 000000000..98384c9c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/pragma.C @@ -0,0 +1,13 @@ +/* Test that #pragma GCC visibility affects class members. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */ + +#pragma GCC visibility push(hidden) +class Foo +{ + void method(); +}; +#pragma GCC visibility pop + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/prop1.C b/gcc/testsuite/g++.dg/ext/visibility/prop1.C new file mode 100644 index 000000000..f4574820d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/prop1.C @@ -0,0 +1,23 @@ +// Test for propagation of visibility through template arguments + +// { dg-do compile } +// { dg-require-visibility "" } +// { dg-final { scan-hidden "_Z1fIN1N1AEEvT_" } } +// { dg-final { scan-hidden "_Z1hIXadL_ZN1N1iEEEEvv" } } + +namespace N __attribute ((__visibility__ ("hidden"))) +{ + struct A { }; + int i; +} + +template <class T> void f (T) { } +template <int *I> void h() { } + +void g() +{ + N::A a; + f(a); + h<&N::i>(); +} + diff --git a/gcc/testsuite/g++.dg/ext/visibility/redecl1.C b/gcc/testsuite/g++.dg/ext/visibility/redecl1.C new file mode 100644 index 000000000..b53335ef5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/redecl1.C @@ -0,0 +1,7 @@ +// Test that we complain about redeclaration with different visibility + +struct __attribute((visibility("hidden"))) B; +struct __attribute((visibility("default"))) B; // { dg-error "visibility" } + +__attribute ((visibility ("hidden"))) void f(); // { dg-warning "previous" } +__attribute ((visibility ("default"))) void f(); // { dg-warning "visibility" } diff --git a/gcc/testsuite/g++.dg/ext/visibility/staticdatamem.C b/gcc/testsuite/g++.dg/ext/visibility/staticdatamem.C new file mode 100644 index 000000000..4ec9479a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/staticdatamem.C @@ -0,0 +1,20 @@ +// PR c++/18925 +// { dg-do compile { target ia64-*-linux* } } +// { dg-options "-fPIC -fvisibility=hidden" } +// { dg-final { scan-assembler-not "gprel" } } + +class __attribute__ ((visibility("default"))) Type +{ + private: + static long _staticTypeCount; + public: + Type() { _staticTypeCount++; } + ~Type(); +}; + +long Type::_staticTypeCount = 0; + +Type::~Type() +{ + _staticTypeCount--; +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/staticmemfuncts.C b/gcc/testsuite/g++.dg/ext/visibility/staticmemfuncts.C new file mode 100644 index 000000000..e745caa5a --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/staticmemfuncts.C @@ -0,0 +1,11 @@ +/* Test that setting visibility for static class member functions works. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-final { scan-hidden "_ZN3Foo6methodEv" } } */ + +class __attribute__ ((visibility ("hidden"))) Foo +{ + static void method(); +}; + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/symbian1.C b/gcc/testsuite/g++.dg/ext/visibility/symbian1.C new file mode 100644 index 000000000..864ab2bb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/symbian1.C @@ -0,0 +1,22 @@ +// { dg-do compile { target arm*-*-symbianelf* } } +// Class data should not be exported. +// { dg-final { scan-hidden "_ZTV2K3" } } +// But the constructor and destructor should be exported. +// { dg-final { scan-not-hidden "_ZN2K3C2Ev" } } +// { dg-final { scan-not-hidden "_ZN2K3D0Ev" } } + +class __declspec(notshared) K3 { +public: + __declspec(dllimport) K3(); + __declspec(dllimport) virtual ~K3(); + virtual int m1(); +}; + +__declspec(dllexport) + K3::K3(){} + +__declspec(dllexport) + K3::~K3(){} + +int K3::m1() { return 1; } + diff --git a/gcc/testsuite/g++.dg/ext/visibility/symbian2.C b/gcc/testsuite/g++.dg/ext/visibility/symbian2.C new file mode 100644 index 000000000..767f0b54e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/symbian2.C @@ -0,0 +1,11 @@ +// { dg-do compile { target arm*-*-symbianelf* } } +// Class data should not be exported. +// { dg-final { scan-hidden "_ZTI1A" } } +// { dg-final { scan-hidden "_ZTS1A" } } +// { dg-final { scan-hidden "_ZTV1B" } } +// { dg-final { scan-hidden "_ZTI1B" } } +// { dg-final { scan-hidden "_ZTS1B" } } + +struct A {}; +struct B : virtual public A {}; +B b; diff --git a/gcc/testsuite/g++.dg/ext/visibility/template1.C b/gcc/testsuite/g++.dg/ext/visibility/template1.C new file mode 100644 index 000000000..c5cee0d4b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template1.C @@ -0,0 +1,35 @@ +// PR c++/19134 +// -fvisibility-inlines-hidden doesn't apply to non-inline specializations + +// { dg-require-visibility "" } +// { dg-options "-fvisibility-inlines-hidden" } +// { dg-final { scan-not-hidden "_ZN1AIiE3fooEv" } } +// { dg-final { scan-not-hidden "_ZN1AIiE3barEv" } } +// { dg-final { scan-hidden "_ZN1AIlE3fooEv" } } +// { dg-final { scan-hidden "_ZN1AIlE3barEv" } } +// { dg-final { scan-hidden "_ZN1AIcE3barEv" } } + +template<class T> +struct A { + void foo() {}; + __attribute ((visibility ("hidden"))) void bar(); +}; + +// This has default visibility. +template<> void A<int>::foo() {} + +// This has hidden visibility because of -fvisibility-inlines-hidden. +template<> inline void A<long>::foo() {} +// Force the inline out. +void f () { A<long> a; a.foo(); } + +// This has default visibility. +template<> __attribute ((visibility ("default"))) void A<int>::bar() {} + +// This inherits hidden visibility from its template. +template<> void A<long>::bar() { } + +// This also has hidden visibility; #pragma vis doesn't affect class members. +#pragma GCC visibility push(default) +template<> void A<char>::bar() { } +#pragma GCC visibility pop diff --git a/gcc/testsuite/g++.dg/ext/visibility/template2.C b/gcc/testsuite/g++.dg/ext/visibility/template2.C new file mode 100644 index 000000000..8db96db56 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template2.C @@ -0,0 +1,35 @@ +// PR c++/27000 +// Implicitly instantiated templates should not be affected by +// #pragma visibility. + +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-final { scan-not-hidden "_ZN1SIiED1Ev" } } */ +/* { dg-final { scan-not-hidden "_ZN1SIiEC1ERKi" } } */ + +template <class T> +struct S +{ + S (const T &); + ~S (); + T t; +}; + +template <class T> +S<T>::S (const T &x) +{ + t = x; +} + +template <class T> +S<T>::~S () +{ +} + +#pragma GCC visibility push(hidden) +struct U +{ + S<int> s; + U () : s (6) { } +} u; +#pragma GCC visibility pop diff --git a/gcc/testsuite/g++.dg/ext/visibility/template3.C b/gcc/testsuite/g++.dg/ext/visibility/template3.C new file mode 100644 index 000000000..69cb6caba --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template3.C @@ -0,0 +1,22 @@ +// PR c++/17470 +// Test that we can give visibility to explicit template instantiations + +// { dg-require-visibility "" } +// { dg-final { scan-hidden "_ZN1AIlE1fEl" } } +// { dg-final { scan-hidden "_ZN1AIiE1fEi" } } +// { dg-final { scan-not-hidden "_ZN1AIcE1fEc" } } +// { dg-final { scan-hidden "_Z8identityIdET_S0_" } } +// { dg-final { scan-not-hidden "_Z8identityIiET_S0_" } } + +template <class T> T identity(T t) { return t; } +template __attribute__((visibility("hidden"))) double identity(double); +template int identity(int); + + +template <class T> struct A { void f (T); }; +template <class T> void A<T>::f (T) { } +template struct __attribute ((visibility ("hidden"))) A<int>; +template<> struct __attribute ((visibility ("hidden"))) A<long> { void f(long); }; +// inherits hidden visibility from its class +void A<long>::f (long) { } +template struct A<char>; diff --git a/gcc/testsuite/g++.dg/ext/visibility/template4.C b/gcc/testsuite/g++.dg/ext/visibility/template4.C new file mode 100644 index 000000000..add63a593 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template4.C @@ -0,0 +1,39 @@ +// Test for explicit visibility on template vs. #pragma vis at explicit +// instantiation/specialization point for plain function templates. + +// { dg-require-visibility "" } +// { dg-final { scan-hidden "_Z3fooIdEvT_" } } +// { dg-final { scan-hidden "_Z3fooIlEvT_" } } +// { dg-final { scan-hidden "_Z3fooIcEvT_" } } +// { dg-final { scan-hidden "_Z3fooIiEvT_" } } +// { dg-final { scan-not-hidden "_Z3fooIfEvT_" } } +// { dg-final { scan-not-hidden "_Z3fooIsEvT_" } } + +// { dg-final { scan-hidden "_Z3barIdEvT_" } } +// { dg-final { scan-hidden "_Z3barIlEvT_" } } +// { dg-final { scan-hidden "_Z3barIiEvT_" } } +// { dg-final { scan-hidden "_Z3barIcEvT_" } } +// { dg-final { scan-not-hidden "_Z3barIfEvT_" } } +// { dg-final { scan-not-hidden "_Z3barIsEvT_" } } + +#pragma GCC visibility push(hidden) +template <class T> void bar(T) { } +#pragma GCC visibility pop +template void bar (long); +template<> void bar (double) { } +template __attribute ((visibility ("default"))) void bar (short); +template<> __attribute ((visibility ("default"))) void bar (float) { } +#pragma GCC visibility push(default) +template<> void bar(char) { } +template void bar(int); +#pragma GCC visibility pop + +template <class T> __attribute ((visibility ("hidden"))) void foo(T) { } +template void foo (long); +template<> void foo (double) { } +template __attribute ((visibility ("default"))) void foo (short); +template<> __attribute ((visibility ("default"))) void foo (float) { } +#pragma GCC visibility push(default) +template<> void foo(char) { } +template void foo(int); +#pragma GCC visibility pop diff --git a/gcc/testsuite/g++.dg/ext/visibility/template6.C b/gcc/testsuite/g++.dg/ext/visibility/template6.C new file mode 100644 index 000000000..7892a46e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/template6.C @@ -0,0 +1,17 @@ +// Test for explicit visibility taking precedence + +// { dg-require-visibility "" } +// { dg-final { scan-not-hidden "_ZN1AIiE1fEv" } } + +template <class T> struct A +{ + // This attribute takes precedence over... + __attribute ((visibility ("default"))) void f (); +}; + +template <class T> +void A<T>::f () +{ } + +// ...this attribute. +template struct __attribute ((visibility ("hidden"))) A<int>; diff --git a/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C b/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C new file mode 100644 index 000000000..99dfc1cd7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/typeinfo1.C @@ -0,0 +1,19 @@ +// PR c++/26984 +// lazily generated typeinfos should not be affected by #pragma vis, but +// they should be affected by the visibility of the type they describe. + +// { dg-require-visibility "" } +// { dg-options "-fvisibility-inlines-hidden" } +// { dg-final { scan-not-hidden "_ZTIPPi" } } +// { dg-final { scan-not-hidden "_ZTSPPi" } } +// { dg-final { scan-hidden "_ZTIP1A" } } +// { dg-final { scan-hidden "_ZTSP1A" } } + +#include <typeinfo> + +#pragma GCC visibility push(hidden) +const std::type_info* t = &(typeid(int **)); +struct A { }; +#pragma GCC visibility pop + +const std::type_info* t2 = &(typeid(A *)); diff --git a/gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C b/gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C new file mode 100644 index 000000000..54f541d85 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/typeinfo2.C @@ -0,0 +1,23 @@ +// PR c++/35368 +// { dg-require-visibility "" } + +#pragma GCC visibility push (hidden) + +struct A +{ + A(); + virtual ~A() { } +}; + +A::A() +{ +} + +void foo(A *a) +{ + delete a; +} + +// { dg-final { scan-not-hidden "_ZTVN10__cxxabiv117__class_type_infoE" } } +// { dg-final { scan-hidden "_ZTI1A" } } +// { dg-final { scan-hidden "_ZTV1A" } } diff --git a/gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C b/gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C new file mode 100644 index 000000000..5102b6492 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/typeinfo3.C @@ -0,0 +1,24 @@ +// PR c++/35368 +// { dg-require-visibility "" } + +#pragma GCC visibility push (hidden) + +#include <typeinfo> + +const std::type_info& info1 = typeid(int []); +const std::type_info& info2 = typeid(int); +enum E { e = 0 }; +const std::type_info& info3 = typeid(E); +struct S { S (); }; +const std::type_info& info4 = typeid(S); +const std::type_info& info5 = typeid(int *); + +// { dg-final { scan-not-hidden "_ZTVN10__cxxabiv117__array_type_infoE" } } +// { dg-final { scan-not-hidden "_ZTVN10__cxxabiv116__enum_type_infoE" } } +// { dg-final { scan-hidden "_ZTI1S" } } +// { dg-final { scan-hidden "_ZTS1S" } } +// { dg-final { scan-hidden "info1" } } +// { dg-final { scan-hidden "info2" } } +// { dg-final { scan-hidden "info3" } } +// { dg-final { scan-hidden "info4" } } +// { dg-final { scan-hidden "info5" } } diff --git a/gcc/testsuite/g++.dg/ext/visibility/virtual.C b/gcc/testsuite/g++.dg/ext/visibility/virtual.C new file mode 100644 index 000000000..770600368 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/virtual.C @@ -0,0 +1,17 @@ +/* Test that setting visibility for class affects virtual table, VTT and + type_info name and node. */ +/* { dg-do compile } */ +/* { dg-require-visibility "" } */ +/* { dg-final { scan-hidden "ZTV3Foo" } } */ +/* { dg-final { scan-hidden "ZTT3Foo" } } */ +/* { dg-final { scan-hidden "ZTS3Foo" } } */ +/* { dg-final { scan-hidden "ZTI3Foo" } } */ + +struct A { }; + +class __attribute__ ((visibility ("hidden"))) Foo: virtual public A +{ + virtual void method(); +}; + +void Foo::method() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-1.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-1.C new file mode 100644 index 000000000..8ea270bf8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-1.C @@ -0,0 +1,8 @@ +/* Test visibility attribute on function definition. */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "_Z3foov" } } */ + +void +__attribute__((visibility ("hidden"))) +foo() +{ } diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-10.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-10.C new file mode 100644 index 000000000..312d32309 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-10.C @@ -0,0 +1,19 @@ +// { dg-require-visibility "" } +// { dg-require-dll "" } + +extern void __attribute__((dllimport, visibility("hidden"))) + f1(); // { dg-error "visibility" } +extern void __attribute__((visibility("hidden"), dllimport)) + f2(); // { dg-error "visibility" } +extern void __attribute__((dllexport, visibility("hidden"))) + f3(); // { dg-error "visibility" } +extern void __attribute__((visibility("hidden"), dllexport)) + f4(); // { dg-error "visibility" } +extern void __attribute__((visibility("default"), dllimport)) + f5(); +extern void __attribute__((dllimport, visibility("default"))) + f6(); +extern void __attribute__((visibility("default"), dllexport)) + f7(); +extern void __attribute__((dllexport, visibility("default"))) + f8(); diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-11.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-11.C new file mode 100644 index 000000000..78f40c62b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-11.C @@ -0,0 +1,18 @@ +// PR target/39175 +// { dg-do compile } +// { dg-require-visibility "" } +// { dg-options "-O2 -fvisibility=hidden -fpic" { target fpic } } + +__attribute__((noinline)) int +foo (int x) +{ + return x; +} + +int foo (int x); + +int +bar (int x) +{ + return foo (x); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-2.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-2.C new file mode 100644 index 000000000..26272abb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-2.C @@ -0,0 +1,7 @@ +/* Test that visibility attribute on declaration extends to definition. */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "_Z3foov" } } */ + +void __attribute__((visibility ("hidden"))) foo(); + +void foo() { } diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-3.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-3.C new file mode 100644 index 000000000..e4f499fcc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-3.C @@ -0,0 +1,7 @@ +/* Test visibility attribute on forward declaration of global variable */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "xyzzy" } } */ + +int +__attribute__((visibility ("hidden"))) +xyzzy = 5; diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-4.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-4.C new file mode 100644 index 000000000..f67659587 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-4.C @@ -0,0 +1,8 @@ +/* Test visibility attribute on forward declaration of global variable */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "xyzzy" } } */ + +extern int __attribute__ ((visibility ("hidden"))) +xyzzy; + +int xyzzy = 5; diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-5.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-5.C new file mode 100644 index 000000000..592529e66 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-5.C @@ -0,0 +1,11 @@ +/* Test visibility attribute on definition of a function that has + already had a forward declaration. */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "_Z3foov" } } */ + +void foo(); + +void + __attribute__((visibility ("hidden"))) +foo() +{ } diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-6.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-6.C new file mode 100644 index 000000000..0fecf6b74 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-6.C @@ -0,0 +1,10 @@ +/* Test visibility attribute on definition of global variable that has + already had a forward declaration. */ +/* { dg-require-visibility "" } +/* { dg-final { scan-hidden "xyzzy" } } */ + +extern int xyzzy; + +int +__attribute__((visibility ("hidden"))) +xyzzy = 5; diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-7.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-7.C new file mode 100644 index 000000000..ae4589397 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-7.C @@ -0,0 +1,11 @@ +/* Test warning from conflicting visibility specifications. */ +/* { dg-require-visibility "protected" } */ +/* { dg-final { scan-hidden "xyzzy" } } */ + +extern int +__attribute__((visibility ("hidden"))) +xyzzy; /* { dg-warning "previous declaration here" "" } */ + +int +__attribute__((visibility ("protected"))) +xyzzy = 5; /* { dg-warning "visibility attribute ignored" "" } */ diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-8.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-8.C new file mode 100644 index 000000000..f0139b362 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-8.C @@ -0,0 +1,56 @@ +// Test that a definition marked with dllexport has default +// visibility. +// { dg-require-visibility "" } +// { dg-require-dll "" } +// { dg-options "-fvisibility=hidden" } +// { dg-final { scan-not-hidden "_ZN1A1fEv" } } +// { dg-final { scan-not-hidden "_Z1gv" } } +// { dg-final { scan-not-hidden "_Z1hv" } } +// { dg-final { scan-not-hidden "_ZN1BC1Ev" } } +// { dg-final { scan-not-hidden "_ZN1BC2Ev" } } +// { dg-final { scan-not-hidden "_ZN1BD0Ev" } } +// { dg-final { scan-not-hidden "_ZN1BD1Ev" } } +// { dg-final { scan-not-hidden "_ZN1BD2Ev" } } +// { dg-final { scan-not-hidden "_ZN1B1iEv" } } +// { dg-final { scan-not-hidden "_ZN1B1jEv" } } +// { dg-final { scan-not-hidden "_ZN1A1a" } } +// { dg-final { scan-not-hidden "_ZN1B1b" } } +// { dg-final { scan-not-hidden "k" } } +// { dg-final { scan-not-hidden "l" } } + +struct __declspec(dllexport) A { + void f(); + static int a; +}; + +void A::f() {} + +int A::a; + +__declspec(dllexport) void g() {} + +__declspec(dllexport) void h(); +void h() {} + +struct B { + B(); + __declspec(dllexport) virtual ~B(); + void i(); + __declspec(dllexport) void j(); + __declspec(dllexport) static int b; +}; + +__declspec(dllexport) B::B() {} + +B::~B() {} + +__declspec(dllexport) void B::i() {} + +void B::j() {} + +int B::b; + +__declspec(dllexport) int k; + +__declspec(dllexport) extern int l; +int l; diff --git a/gcc/testsuite/g++.dg/ext/visibility/visibility-9.C b/gcc/testsuite/g++.dg/ext/visibility/visibility-9.C new file mode 100644 index 000000000..06b5a17e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/visibility-9.C @@ -0,0 +1,29 @@ +// Test that dllimport'd functions have default visibility. +// { dg-require-visibility "" } +// { dg-require-dll "" } +// { dg-options "-fvisibility=hidden" } +// { dg-final { scan-not-hidden "_Z2f1v" } } +// { dg-final { scan-not-hidden "_ZN1S2f3Ev" } } + +extern void __attribute__((dllimport)) f1(); +void f2() { + f1(); +} + +struct __attribute__((visibility("hidden")) S1 { + __attribute__((dllimport)) void f3(); +}; + +void f4() { + S1 s1; + s1.f3(); +} + +struct S2 { + __attribute__((dllimport)) void f5(); +}; + +void f6() { + S2 s2; + s2.f5(); +} diff --git a/gcc/testsuite/g++.dg/ext/visibility/warn2.C b/gcc/testsuite/g++.dg/ext/visibility/warn2.C new file mode 100644 index 000000000..475179fd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/warn2.C @@ -0,0 +1,16 @@ +// Complain when a class is specified with greater visibility than one of +// its members' types or bases. + +// { dg-require-visibility "" } + +namespace N __attribute ((__visibility__ ("hidden"))) +{ + struct A { }; +} + +struct B // { dg-warning "visibility" } +{ + N::A a; +}; + +struct C: public N::A { }; // { dg-warning "visibility" } diff --git a/gcc/testsuite/g++.dg/ext/visibility/warn3.C b/gcc/testsuite/g++.dg/ext/visibility/warn3.C new file mode 100644 index 000000000..d1d3ba486 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/warn3.C @@ -0,0 +1,26 @@ +// Tests for various visibility mismatch situations. + +// { dg-require-visibility "" } + +// { dg-final { scan-not-hidden "_ZN1A1fEv" } } + +struct __attribute ((visibility ("hidden"))) A +{ + // This is OK, A::f gets default visibility. + __attribute ((visibility ("default"))) void f (); +}; + +void A::f() { } + +// This gets a warning because B objects might rely +// on hidden symbols from A. +struct B // { dg-warning "visibility" } +{ + A a; +}; + +// This one has explicit visibility, so it doesn't get a warning. +struct __attribute ((visibility ("default"))) C +{ + A a; +}; diff --git a/gcc/testsuite/g++.dg/ext/visibility/warn4.C b/gcc/testsuite/g++.dg/ext/visibility/warn4.C new file mode 100644 index 000000000..33e6f6785 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/warn4.C @@ -0,0 +1,10 @@ +// Warn if we try to give an instantiation visibility after it's already +// been instantiated. + +// { dg-require-visibility "" } + +template <class T> struct A { void f (T); }; +template <class T> void A<T>::f (T) { } + +A<double> ad; +template struct __attribute ((visibility ("hidden"))) A<double>; // { dg-warning "already defined" } diff --git a/gcc/testsuite/g++.dg/ext/vla1.C b/gcc/testsuite/g++.dg/ext/vla1.C new file mode 100644 index 000000000..f3725354f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla1.C @@ -0,0 +1,26 @@ +// { dg-do compile } + +// Crash tests from PR middle-end/6994. See also gcc.dg/vla-2.c. +// A::A is acceptable extended C++ (VLA types brought over from C99); +// B::B is not, but is closely related to acceptable extended C, though +// not to acceptable C99. + +class A { A (int); }; + +A::A (int i) +{ + int ar[1][i]; // { dg-error "variable length array" } + + ar[0][0] = 0; +} + +class B { B (int); }; + +B::B (int i) +{ + struct S { + int ar[1][i]; // { dg-error "array" } + } s; + + s.ar[0][0] = 0; // { dg-prune-output "no member" } +} diff --git a/gcc/testsuite/g++.dg/ext/vla10.C b/gcc/testsuite/g++.dg/ext/vla10.C new file mode 100644 index 000000000..17cdb2f9f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla10.C @@ -0,0 +1,32 @@ +// PR c++/48446 +// { dg-options "" } + +template<typename T> +struct A +{ + ~A (); + T *operator-> () const; +}; + +struct B +{ + typedef A <B> P; + static P foo (int); +}; + +struct C +{ + typedef A<C> P; + static const int c = 80; +}; + +C::P bar (); + +void +baz () +{ + char z[bar ()->c]; + { + B::P m = B::foo (sizeof (z)); + } +} diff --git a/gcc/testsuite/g++.dg/ext/vla2.C b/gcc/testsuite/g++.dg/ext/vla2.C new file mode 100644 index 000000000..f6a9debca --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla2.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-options "" } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Mar 2003 <nathan@codesourcery.com> + +// PR 9708. We unified a VLA size as a constant. Then issued bogus +// errors. + +template <unsigned int N> +char* begin(char (&a) [N] ); // { dg-message "note" } + +void bar(int i) +{ + char d[i] ; + + begin(d); // { dg-error "no matching function" "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 17 } +} diff --git a/gcc/testsuite/g++.dg/ext/vla3.C b/gcc/testsuite/g++.dg/ext/vla3.C new file mode 100644 index 000000000..329cc7dde --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla3.C @@ -0,0 +1,24 @@ +// PR c++/28903 +// { dg-options "" } + +template <class> +struct View +{ + int n; +}; +template <class ViewA> +struct ViewDom : View<ViewA> +{ + using View<ViewA>::n; + ViewDom(); +}; +template <class ViewA> +ViewDom<ViewA>::ViewDom() +{ + char a[n]; +} +void element( ) +{ + ViewDom<int> a; +} + diff --git a/gcc/testsuite/g++.dg/ext/vla4.C b/gcc/testsuite/g++.dg/ext/vla4.C new file mode 100644 index 000000000..ecec90807 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla4.C @@ -0,0 +1,21 @@ +// PR c++/29318 +// { dg-options "" } + +#include <typeinfo> + +void f(int i) { + try { + int a[i]; + throw &a; // { dg-error "variable size" } + } catch (int (*)[i]) { // { dg-error "variable size" } + } +} + +int main() +{ + int i = 5; + int va[i]; + const std::type_info& info(typeid(&va)); // { dg-error "variable size" } + + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/vla5.C b/gcc/testsuite/g++.dg/ext/vla5.C new file mode 100644 index 000000000..021d48469 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla5.C @@ -0,0 +1,10 @@ +// PR c++/37417 +// Testcase by Martin Michlmayr <tbm@cyrius.com> +// { dg-do compile } +// { dg-options "-O" } + +void +test (int a) +{ + new (char[a]); +} diff --git a/gcc/testsuite/g++.dg/ext/vla6.C b/gcc/testsuite/g++.dg/ext/vla6.C new file mode 100644 index 000000000..83011f2f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla6.C @@ -0,0 +1,18 @@ +// PR c++/28879 +// { dg-options "" } + +struct A +{ + int i; + A(): i(1) {} +}; + +template<int> void foo() +{ + int x[A().i]; +} + +void f() +{ + foo<1>(); +} diff --git a/gcc/testsuite/g++.dg/ext/vla7.C b/gcc/testsuite/g++.dg/ext/vla7.C new file mode 100644 index 000000000..5246f9c8c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla7.C @@ -0,0 +1,30 @@ +// PR c++/40013 +// { dg-options "" } + +template <class T> +struct A +{ + struct B + { + struct + { + int fn () { return 0; } + } b; + }; + void test (); +}; + +template <class T> +void +A <T>::test () +{ + B a; + int vla[a.b.fn ()]; +} + +int +main () +{ + A <char> a; + a.test (); +} diff --git a/gcc/testsuite/g++.dg/ext/vla8.C b/gcc/testsuite/g++.dg/ext/vla8.C new file mode 100644 index 000000000..7b7428d07 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla8.C @@ -0,0 +1,15 @@ +// PR c++/42387 +// { dg-options "" } + +template<class PF> +struct AvlTreeIter +{ + int Num(); + + AvlTreeIter() + { + new (void* [Num()]); + } +}; + +AvlTreeIter<int> a; diff --git a/gcc/testsuite/g++.dg/ext/vla9.C b/gcc/testsuite/g++.dg/ext/vla9.C new file mode 100644 index 000000000..c58edbc9b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla9.C @@ -0,0 +1,38 @@ +// PR c++/43555 +// { dg-options "" } +// { dg-do run } + +extern "C" void * malloc (__SIZE_TYPE__); +extern "C" int printf (const char *, ...); +extern "C" void abort(void); + +int nx,ny; + +void f(double *x1d,int choice) +{ + double (*x2d)[nx][ny]=(double(*)[nx][ny])x1d; + unsigned long delta; +// (*x2d)[0][0]=123; // <- this line affects the result + if (choice!=0) + { + delta=&(*x2d)[1][0]-x1d; + } + else + { + delta=&(*x2d)[1][0]-x1d; + } + printf("Choice: %d, Delta: %ld\n",choice,delta); + if (delta != ny) + abort (); +} + +int main() +{ + double *data; + nx=100; + ny=100; + data=(double*)malloc(nx*ny*sizeof(double)); + f(data,0); + f(data,1); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/vlm1.C b/gcc/testsuite/g++.dg/ext/vlm1.C new file mode 100644 index 000000000..9cb6c38be --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vlm1.C @@ -0,0 +1,13 @@ +// { dg-options "" } + +template <class T> struct A {}; + +struct B { + static const int s; + A<int[s]> a; // { dg-error "array|template" } +}; + +const int B::s=16; + +B b; + diff --git a/gcc/testsuite/g++.dg/ext/vlm2.C b/gcc/testsuite/g++.dg/ext/vlm2.C new file mode 100644 index 000000000..3a0b33526 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vlm2.C @@ -0,0 +1,13 @@ +// { dg-options "" } + +int n; + +struct Y +{ + void f () { + typedef int X[n]; + struct Z { + X x; // { dg-error "variably modified" } + }; + } +}; diff --git a/gcc/testsuite/g++.dg/ext/weak1.C b/gcc/testsuite/g++.dg/ext/weak1.C new file mode 100644 index 000000000..b7a448f37 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/weak1.C @@ -0,0 +1,13 @@ +// Test for #pragma weak where the weak alias symbol isn't declared, +// although the symbol it is an alias for is defined in the +// translation unit. Bug 7544. +// Origin: Joseph Myers <joseph@codesourcery.com> +// { dg-do compile } +// { dg-require-weak "" } +// { dg-require-alias "" } +// { dg-options "-fno-common" } + +// { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?bar1" } } + +#pragma weak bar1 = foo1 +extern "C" void foo1 (void) {} diff --git a/gcc/testsuite/g++.dg/ext/weak2.C b/gcc/testsuite/g++.dg/ext/weak2.C new file mode 100644 index 000000000..1bf2ddcb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/weak2.C @@ -0,0 +1,17 @@ +// Test for #pragma weak with declaration not at file scope. +// { dg-do compile } +// { dg-require-weak "" } +// { dg-options "" } + +// { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?_Z3foov" } } + +#pragma weak _Z3foov + +int +main (void) +{ + extern int foo (void); + if (&foo) + return foo (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/weak3.C b/gcc/testsuite/g++.dg/ext/weak3.C new file mode 100644 index 000000000..360821acc --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/weak3.C @@ -0,0 +1,17 @@ +// PR c++/20961 +// Test for #pragma weak and __attribute__((weak)) being used together. +// { dg-do compile } +// { dg-require-weak "" } +// { dg-options "" } + +// { dg-final { scan-assembler "weak\[^ \t\]*\[ \t\]_?_Z3foov" } } + +int foo (); +#pragma weak foo + +int +__attribute__((weak)) +foo () +{ + return 0; +} |