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/template | |
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/template')
949 files changed, 18423 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/template/access1.C b/gcc/testsuite/g++.dg/template/access1.C new file mode 100644 index 000000000..1622e087d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access1.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 19 Jan 2002 <nathan@codesourcery.com> + +// It is legal to specialize a template with a different class-key. + +template<typename T> class X; + +template<typename T> struct X<T *> +{ + int i; +}; +template<> struct X<int> +{ + int i; +}; + +void foo () +{ + X<int *> xip; + X<int> xi; + + xip.i; + xi.i; +} + diff --git a/gcc/testsuite/g++.dg/template/access10.C b/gcc/testsuite/g++.dg/template/access10.C new file mode 100644 index 000000000..8b4883c25 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access10.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// PR c++/10849: Incorrect access checking on template specialization. + +class X { + private: + template <typename T> struct Y; +}; + +template <> struct X::Y<int> {}; + +template <typename T> struct X::Y {}; + +template struct X::Y<int>; diff --git a/gcc/testsuite/g++.dg/template/access11.C b/gcc/testsuite/g++.dg/template/access11.C new file mode 100644 index 000000000..c9364a823 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access11.C @@ -0,0 +1,24 @@ +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +// Access checking during explicit instantiation. + +class A { + typedef int X; // { dg-error "private" } +}; + +class X { + private: + template <typename T> struct Y; +}; + +template <> struct X::Y<int> { + A::X x; // { dg-error "this context" } +}; + +template <typename T> struct X::Y { + typename T::X x; // { dg-error "this context" } +}; + +template struct X::Y<A>; // { dg-message "instantiated from here" } diff --git a/gcc/testsuite/g++.dg/template/access12.C b/gcc/testsuite/g++.dg/template/access12.C new file mode 100644 index 000000000..9185d5125 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access12.C @@ -0,0 +1,13 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// PR c++/10849: Incorrect access checking on class template partial +// specialization. + +class X { + private: + template <typename T> struct Y; +}; + +template <typename T> struct X::Y<T*> {}; diff --git a/gcc/testsuite/g++.dg/template/access13.C b/gcc/testsuite/g++.dg/template/access13.C new file mode 100644 index 000000000..3a1442bb0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access13.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: Francesco Monica <fmonica@ce.unipr.it> + +// PR c++/13262: Access checking during instantiation of static data +// member. + +template <typename T> class Aclass { + private: + Aclass() {} + static Aclass instance; +}; + +template <typename T> Aclass<T> Aclass<T>::instance; + +template class Aclass<int>; diff --git a/gcc/testsuite/g++.dg/template/access14.C b/gcc/testsuite/g++.dg/template/access14.C new file mode 100644 index 000000000..047f9258f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access14.C @@ -0,0 +1,16 @@ +// PR c++/14777 + +template <typename T> +struct B +{ +protected: + typedef int M; +}; + +template <typename T> +struct A : B<T> { + typedef typename B<T>::M N; + A (int = N ()); +}; + +A<int> a = A<int> (); diff --git a/gcc/testsuite/g++.dg/template/access15.C b/gcc/testsuite/g++.dg/template/access15.C new file mode 100644 index 000000000..e28716366 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access15.C @@ -0,0 +1,12 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 23 Aug 2004 <nathan@codesourcery.com> +// Origin: stefaandr@hotmail.com + +// Bug 17149: ICE with TEMPLATE_TYPE_PARM + + +template <class super, + int (super::tdata::*member)() const = &super::tdata::operator()> +struct x {}; diff --git a/gcc/testsuite/g++.dg/template/access16.C b/gcc/testsuite/g++.dg/template/access16.C new file mode 100644 index 000000000..bb7ebccb8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access16.C @@ -0,0 +1,16 @@ +// PR c++/23842 + +struct S; +extern S *p; +template <class T> int f(T*, int y = ((T*)p)->x) { + return y; +} +struct S { +private: + int x; + template <class U> friend int f(U*, int); +}; +int g() { + return f(p); +} + diff --git a/gcc/testsuite/g++.dg/template/access17.C b/gcc/testsuite/g++.dg/template/access17.C new file mode 100644 index 000000000..0c4510005 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access17.C @@ -0,0 +1,23 @@ +// PR c++/27339 + +class A +{ +private: + enum private_enum {a}; + + template<A::private_enum v> // OK + struct B + { + void bm(); + }; +public: + void am() + { + B<a> instance; //OK + instance.bm(); + } +}; + +template<A::private_enum v> // FAIL +void +A::B<v>::bm(){} diff --git a/gcc/testsuite/g++.dg/template/access18.C b/gcc/testsuite/g++.dg/template/access18.C new file mode 100644 index 000000000..3338bc932 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access18.C @@ -0,0 +1,19 @@ +// DR 401 + +class X { + typedef int a; // { dg-error "private" } + static const int b = 5; // { dg-error "private" } + template <typename> + struct c; // { dg-error "private" } +}; + +template <typename = X::a> // { dg-error "context" } +struct A; + +template <int = X::b> // { dg-error "context" } +struct B; + +template <template <typename> class T = X::c> // { dg-error "context" } +struct C; + + diff --git a/gcc/testsuite/g++.dg/template/access19.C b/gcc/testsuite/g++.dg/template/access19.C new file mode 100644 index 000000000..6420b1cbe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access19.C @@ -0,0 +1,24 @@ +/* PR c++/29475 The error diagnostic contained "U = U" instead of "U = char" */
+/* { dg-do compile } */
+
+template< class T >
+class explicit_t
+{
+public:
+ explicit_t( const T& c ): value( c ) { }
+ operator T&() { return value; }
+private:
+ template< class U >
+ explicit_t( U t ); /* { dg-error "with U = char, T = int|is private" } */
+ T value;
+};
+
+int foo( int x, explicit_t< int > y )
+{
+ return x + y;
+}
+
+int main()
+{
+ return foo( 5, 'c' ); /* { dg-error "this context" } */
+}
diff --git a/gcc/testsuite/g++.dg/template/access2.C b/gcc/testsuite/g++.dg/template/access2.C new file mode 100644 index 000000000..c5e3f1103 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access2.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// PR c++/5387 +// Enforcing access of typename type. + +template <class T> struct A { + typename T::X x; // { dg-error "this context" } + int f() { return T::i; } // { dg-error "this context" } +}; + +class B { + typedef int X; // { dg-error "private" } + static int i; // { dg-error "private" } +}; + +int main() +{ + A<B> ab; // { dg-message "instantiated" } + ab.f(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/access20.C b/gcc/testsuite/g++.dg/template/access20.C new file mode 100644 index 000000000..ebf575e6c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access20.C @@ -0,0 +1,18 @@ +// PR c++/29470 + +template <typename T> struct B +{ + protected: + T v; // { dg-error "protected" } +}; +template <typename T> struct D : B<T> +{ + protected: + using B<T>::v; +}; +int main() +{ + D<int> d; + d.v = 0; // { dg-error "context" } + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/access21.C b/gcc/testsuite/g++.dg/template/access21.C new file mode 100644 index 000000000..8414c4371 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access21.C @@ -0,0 +1,23 @@ +// PR c++/48884 + +class X +{ + static const int I = 42; + friend struct Y; +}; + +template <int I> struct A { }; + +struct Y +{ + template <typename T> + static A<T::I> f(T t) + { + return A<T::I>(); + } +}; + +int main() +{ + Y::f(X()); +} diff --git a/gcc/testsuite/g++.dg/template/access22.C b/gcc/testsuite/g++.dg/template/access22.C new file mode 100644 index 000000000..9ee28a2a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access22.C @@ -0,0 +1,15 @@ +template <int I> struct B { }; + +template <class T> +B<T::I> f(); + +class A +{ + static const int I = 42; + template <class T> friend B<T::I> f(); +}; + +int main() +{ + f<A>(); +} diff --git a/gcc/testsuite/g++.dg/template/access3.C b/gcc/testsuite/g++.dg/template/access3.C new file mode 100644 index 000000000..c7a155e8b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access3.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// PR c++/5387 +// Enforcing access of typename type. + +template <class T> struct A { + typename T::template X<int> x; // { dg-error "this context" } +}; + +class B { + template <class T> class X {}; // { dg-error "private" } +}; + +int main() +{ + A<B> ab; // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/access4.C b/gcc/testsuite/g++.dg/template/access4.C new file mode 100644 index 000000000..9451ecc22 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access4.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <wolfgang.bangerth@iwr.uni-heidelberg.de> + +// PR c++/7347 +// Access control for typename during instantiation + +template <int dim> class Base { + protected: + typedef int T; +}; + +template <int dim> class D : public Base<dim> { + public: + typedef typename Base<dim>::T T1; + D (T1 t); +}; + +D<2> d(1); diff --git a/gcc/testsuite/g++.dg/template/access5.C b/gcc/testsuite/g++.dg/template/access5.C new file mode 100644 index 000000000..b2da190ff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access5.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <wolfgang.bangerth@iwr.uni-heidelberg.de> + +// PR c++/7348 +// Access control for typename in function return type + +class Outer { + template <int dim> struct Inner { + typedef int T; + T foo (); + }; + public: + Outer(); +}; + +template <int dim> +typename Outer::Inner<dim>::T Outer::Inner<dim>::foo () { + return 1; +} + +template struct Outer::Inner<2>; diff --git a/gcc/testsuite/g++.dg/template/access6.C b/gcc/testsuite/g++.dg/template/access6.C new file mode 100644 index 000000000..cbc8000d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access6.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// Origin: Detlef Vollmann <dv@vollmann.ch> + +// PR c++/8389 +// Access control ICE for typename during instantiation and name mangling + +template <class> class Base { + protected: + typedef int Type; +}; + +template <class T> struct Derived : public Base<T> { + typedef typename Base<T>::Type Type; + template <class Arg> void f(Type = Type()) {} +}; + +template void Derived<char>::f<int> (Type); diff --git a/gcc/testsuite/g++.dg/template/access7.C b/gcc/testsuite/g++.dg/template/access7.C new file mode 100644 index 000000000..412ad00c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access7.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// PR c++/3663 +// Enforce access of nested type. + +template <typename A> +class S { + class T {}; // { dg-error "private" } +}; + +template <typename A> +typename A::T* f (A) { // { dg-error "this context" } + return 0; +} + +void g () { + f (S<int> ()); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/access8.C b/gcc/testsuite/g++.dg/template/access8.C new file mode 100644 index 000000000..4bdadae3c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access8.C @@ -0,0 +1,16 @@ +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +// Template instantiate during deferred access check + +template <class T> struct C { + typedef typename T::X Y; +}; + +class A { + typedef int X; + template <class T> friend struct C; +}; + +C<A>::Y f(int); diff --git a/gcc/testsuite/g++.dg/template/access9.C b/gcc/testsuite/g++.dg/template/access9.C new file mode 100644 index 000000000..b24c93f8d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access9.C @@ -0,0 +1,19 @@ +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +// Template instantiate during deferred access check + +template <void (*)(int)> struct C { + typedef int Y; +}; + +template <class T> void f(typename T::X) { +} + +class A { + typedef int X; + template <class T> friend void f(typename T::X); +}; + +C<&f<A> >::Y g(int); diff --git a/gcc/testsuite/g++.dg/template/addr1.C b/gcc/testsuite/g++.dg/template/addr1.C new file mode 100644 index 000000000..dd5e3870f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/addr1.C @@ -0,0 +1,12 @@ +// PR c++/15542 + +template <typename> struct S_T { + const char** operator & (); +}; + +template <class T> void foo(T **) {} + +template <typename> void templateTest() { + S_T<const char> s_t; + foo(&s_t); +} diff --git a/gcc/testsuite/g++.dg/template/alignof1.C b/gcc/testsuite/g++.dg/template/alignof1.C new file mode 100644 index 000000000..50a32183c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/alignof1.C @@ -0,0 +1,13 @@ +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/template/anon1.C b/gcc/testsuite/g++.dg/template/anon1.C new file mode 100644 index 000000000..ef73df6b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anon1.C @@ -0,0 +1,21 @@ +struct x { + int foo () {} +}; + +template <class T> +struct vector { + T& bar () {} +}; + +template <class T> +struct y { + typedef struct { + x t; + } s; + + vector<s> array; + + int foo () + { return array.bar().t.foo(); } +}; +int i = y<x>().foo (); diff --git a/gcc/testsuite/g++.dg/template/anon2.C b/gcc/testsuite/g++.dg/template/anon2.C new file mode 100644 index 000000000..75285ade3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anon2.C @@ -0,0 +1,15 @@ +// PR c++/28279 +// finish_static_data_member_decl was confused by the anonymous +// namespace causing TREE_PUBLIC to be unset + +template<typename T> +struct is_pointer_impl { + static const bool value = true; +}; + +namespace { + class prefix_name_mapper {}; +} + +static const bool val = is_pointer_impl<prefix_name_mapper>::value; + diff --git a/gcc/testsuite/g++.dg/template/anon3.C b/gcc/testsuite/g++.dg/template/anon3.C new file mode 100644 index 000000000..eee7acd82 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anon3.C @@ -0,0 +1,20 @@ +// PR c++/28370 +// { dg-do run } + +namespace +{ + template<typename T> struct A { static int *a; }; + template<typename T> int *A<T>::a = 0; +} + +int * +foo () +{ + return A<int>::a; +} + +int +main () +{ + return foo() != 0; +} diff --git a/gcc/testsuite/g++.dg/template/anon4.C b/gcc/testsuite/g++.dg/template/anon4.C new file mode 100644 index 000000000..59bfee1e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anon4.C @@ -0,0 +1,10 @@ +// PR c++/28407 +// A declaration in the anonymous namespace still has external linkage. + +template <int *P> class A { }; +namespace +{ + int i; +} + +A<&i> a; diff --git a/gcc/testsuite/g++.dg/template/anon5.C b/gcc/testsuite/g++.dg/template/anon5.C new file mode 100644 index 000000000..34599c061 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anon5.C @@ -0,0 +1,6 @@ +// PR c++/45651 + +namespace { template <int T> struct A {}; } +template <int T> struct B { void f(A<T>); }; +template struct B<1>; +template<int T> void B<T>::f(A<T>) {} diff --git a/gcc/testsuite/g++.dg/template/anonunion1.C b/gcc/testsuite/g++.dg/template/anonunion1.C new file mode 100644 index 000000000..89a8c5bec --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anonunion1.C @@ -0,0 +1,24 @@ +// PR c++/47303 +// { dg-do compile } +// { dg-options "-fabi-version=1" } + +struct Z +{ + void foo (int); +}; + +struct F +{ + typedef void (Z::*zm) (int); + typedef void (F::*fm) (int); + template <zm> + void bar (int) + { + union + { + Z z; + }; + } +}; + +F::fm m = &F::bar <&Z::foo>; diff --git a/gcc/testsuite/g++.dg/template/anonunion2.C b/gcc/testsuite/g++.dg/template/anonunion2.C new file mode 100644 index 000000000..cb3c12dff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anonunion2.C @@ -0,0 +1,6 @@ +template <int i> +struct S +{ + S () { union { int a; }; a = 0; } +}; +S<0> s; diff --git a/gcc/testsuite/g++.dg/template/arg1.C b/gcc/testsuite/g++.dg/template/arg1.C new file mode 100644 index 000000000..f7a8b3150 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg1.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Mar 2003 <nathan@codesourcery.com> + +// PR 9978. We rejected a constant expression. + +enum { val = 1 }; + +template <class T> +struct Bar +{ + static const int A = val; + static const int B = A + 1; +}; diff --git a/gcc/testsuite/g++.dg/template/arg2.C b/gcc/testsuite/g++.dg/template/arg2.C new file mode 100644 index 000000000..9fb7a68cc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg2.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Mar 2003 <nathan@codesourcery.com> + +// PR 9708. We accepted a local class + +template <typename T> class X {}; + +void fn () +{ + class L {}; + X<L> f; // { dg-error "uses local type|trying to instantiate|no type|invalid type" "" } +} diff --git a/gcc/testsuite/g++.dg/template/arg3.C b/gcc/testsuite/g++.dg/template/arg3.C new file mode 100644 index 000000000..050aa33bc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg3.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Mar 2003 <nathan@codesourcery.com> + +// PR 10224. Rejected a valid constant argument. + +template <bool B> struct X { + struct I {}; +}; + +template <typename T> struct Y { + static const bool selector = true; + typedef typename X<selector>::I helper; +}; + +Y<int> i; diff --git a/gcc/testsuite/g++.dg/template/arg4.C b/gcc/testsuite/g++.dg/template/arg4.C new file mode 100644 index 000000000..9c9d9ea96 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg4.C @@ -0,0 +1,9 @@ +// PR c++/23437 + +template <void (*p)()> struct S { + static const int i = 10; +}; + +void g(); + +int a[S<g>::i]; diff --git a/gcc/testsuite/g++.dg/template/arg5.C b/gcc/testsuite/g++.dg/template/arg5.C new file mode 100644 index 000000000..87cbd0268 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg5.C @@ -0,0 +1,9 @@ +// PR c++/30534 +// { dg-do compile } + +template<bool> struct A; + +template<int> void foo() +{ + A<__builtin_constant_p(.)> a; // { dg-error "template argument|invalid" } +} diff --git a/gcc/testsuite/g++.dg/template/arg6.C b/gcc/testsuite/g++.dg/template/arg6.C new file mode 100644 index 000000000..ef05abaee --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg6.C @@ -0,0 +1,15 @@ +// PR c++/33744 +// { dg-do run } + +template <bool B> struct A { bool b; A() : b(B) {}; }; +A<bool(1)> a; +A<bool(1<2)> b; +A<(bool)(2>1)> c; +A<bool((2>1))> d; +A<bool(2>1)> e; + +int +main () +{ + return (a.b && b.b && c.b && d.b && e.b) ? 0 : 1; +} diff --git a/gcc/testsuite/g++.dg/template/arg7.C b/gcc/testsuite/g++.dg/template/arg7.C new file mode 100644 index 000000000..a9333b26a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arg7.C @@ -0,0 +1,11 @@ +// PR c++/27425, 34274 + +template<typename T> struct A +{ + template<template<T> class> struct B {}; // { dg-error "void|mismatch|expected" } + // { dg-bogus "not supported" "" { target *-*-* } 5 } + template<T> struct C; // { dg-error "void" } + B<C> b; +}; + +A<void> a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/array1-1.C b/gcc/testsuite/g++.dg/template/array1-1.C new file mode 100644 index 000000000..97fe7cde2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array1-1.C @@ -0,0 +1,32 @@ +// { dg-do compile } +// { dg-options "-fabi-version=1" } + +// Contributed by Nathan Sidwell 22 Dec 2003 <nathan@codesourcery.com> +// Origin: Roger Sayle <roger@eyesopen.com> + +// PR c++/12774 Array domains compared unequal + +void Foo(double r[3][3]) +{ +} + +void Baz() +{ + double m[3][3]; + Foo(m); +} + +template <class T> +void Bar() +{ + double m[3][3]; + Foo(m); +} + +int main() +{ + Baz(); + Bar<int>(); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/array1-2.C b/gcc/testsuite/g++.dg/template/array1-2.C new file mode 100644 index 000000000..7214517b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array1-2.C @@ -0,0 +1,32 @@ +// { dg-do compile } +// { dg-options "-fabi-version=2" } + +// Contributed by Nathan Sidwell 22 Dec 2003 <nathan@codesourcery.com> +// Origin: Roger Sayle <roger@eyesopen.com> + +// PR c++/12774 Array domains compared unequal + +void Foo(double r[3][3]) +{ +} + +void Baz() +{ + double m[3][3]; + Foo(m); +} + +template <class T> +void Bar() +{ + double m[3][3]; + Foo(m); +} + +int main() +{ + Baz(); + Bar<int>(); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/array10.C b/gcc/testsuite/g++.dg/template/array10.C new file mode 100644 index 000000000..81aac84b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array10.C @@ -0,0 +1,20 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 5 Jan 2005 <nathan@codesourcery.com> + +// PR 19270: ICE +// Origin: Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + +template<class T> struct Vec { + T* data; + T& operator[](int i) const; +}; + +template<class T> inline T& Vec<T>::operator[](int i) const +{ + return (&data[0])[i]; +} + +inline double foo(Vec<double> v) +{ + return v[0]; +} diff --git a/gcc/testsuite/g++.dg/template/array11.C b/gcc/testsuite/g++.dg/template/array11.C new file mode 100644 index 000000000..259c9fabc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array11.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +// PR c++/19208: Fold dependent array domains + +template <class C> struct if_t { typedef int type; }; +template <class T> struct ffff { static const bool value = true; }; +template <class A> +struct bound_member_action +{ + typedef char f[ffff<A>::value ? 1 : 2]; + template <class CT> + bound_member_action(CT i, typename if_t<f>::type g) {} +}; +bound_member_action<int> a(0, 1); diff --git a/gcc/testsuite/g++.dg/template/array13.C b/gcc/testsuite/g++.dg/template/array13.C new file mode 100644 index 000000000..3bc152ce4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array13.C @@ -0,0 +1,14 @@ +// PR c++/20208 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort(); + +template <typename T> +inline void *Foo (T arg) { return &arg[0]; } + +int main () { + int bry[2]; + if (Foo<int[2]>(bry) != bry) + abort(); +} diff --git a/gcc/testsuite/g++.dg/template/array14.C b/gcc/testsuite/g++.dg/template/array14.C new file mode 100644 index 000000000..71a03f3bf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array14.C @@ -0,0 +1,10 @@ +// PR c++/23993 + +const int data[2][4] = { + { 0, 1, 2, 3 } +}; + +template <typename T> +void t(int k) { + int candidate = data[1][k]; +} diff --git a/gcc/testsuite/g++.dg/template/array15.C b/gcc/testsuite/g++.dg/template/array15.C new file mode 100644 index 000000000..b1e047d1d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array15.C @@ -0,0 +1,13 @@ +// PR c++/28595 + +template<int> struct A +{ + static const int i; +}; + +template<int N> struct B +{ + char c[A<N>::i], d; // { dg-error "constant" } +}; + +B<0> b; diff --git a/gcc/testsuite/g++.dg/template/array16.C b/gcc/testsuite/g++.dg/template/array16.C new file mode 100644 index 000000000..c51441041 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array16.C @@ -0,0 +1,9 @@ +// PR c++/28886 + +template<typename> struct A; + +template<typename T, int N> struct A<T[N]> {}; + +template<typename T, int N> struct A<const T[N]> {}; + +A<const int[1]> a; diff --git a/gcc/testsuite/g++.dg/template/array17.C b/gcc/testsuite/g++.dg/template/array17.C new file mode 100644 index 000000000..12a5c4720 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array17.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +template <typename T> +struct V { + T& operator[](int); +}; + +struct S { + S operator +(int); + template <typename T> T value(); +}; + +template <typename T> +void R (T v) +{ + v[(S() + 0).template value<int>()][0] = 0; +} + +int +main () +{ + R(V<V<int> >()); +} diff --git a/gcc/testsuite/g++.dg/template/array18.C b/gcc/testsuite/g++.dg/template/array18.C new file mode 100644 index 000000000..b2b1e3502 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array18.C @@ -0,0 +1,13 @@ +// PR c++/30924 + +template<typename T> +struct x {}; + +template<typename T, unsigned N> +struct x<T*[N]> {}; + +int main() { + x<int> a; + x<int*[10]> b; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/array19.C b/gcc/testsuite/g++.dg/template/array19.C new file mode 100644 index 000000000..79abf47c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array19.C @@ -0,0 +1,22 @@ +// PR c++/33553 +// { dg-do compile } + +template <class T> struct S { static const int sz = 2; }; +template <class T> struct U { enum { sz = 2 }; }; + +template <class R> +struct P +{ + template <class T> void bar (int (&x)[S<T>::sz]); + template <class T> void baz (int (&x)[U<T>::sz]); +}; + +P<int> p; + +void +foo (void) +{ + int x[2]; + p.bar<int> (x); + p.baz<int> (x); +} diff --git a/gcc/testsuite/g++.dg/template/array2-1.C b/gcc/testsuite/g++.dg/template/array2-1.C new file mode 100644 index 000000000..2980a1fd1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array2-1.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-fabi-version=1" } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2003 <nathan@codesourcery.com> + +// PR c++/13494. ICE + +template<typename T> +int foo(int d[][4]) +{ + return d[0][0]; +} + diff --git a/gcc/testsuite/g++.dg/template/array2-2.C b/gcc/testsuite/g++.dg/template/array2-2.C new file mode 100644 index 000000000..dd3e7f0e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array2-2.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-fabi-version=2" } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2003 <nathan@codesourcery.com> + +// PR c++/13494. ICE + +template<typename T> +int foo(int d[][4]) +{ + return d[0][0]; +} + diff --git a/gcc/testsuite/g++.dg/template/array20.C b/gcc/testsuite/g++.dg/template/array20.C new file mode 100644 index 000000000..2e5c1e33a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array20.C @@ -0,0 +1,10 @@ +// PR c++/38950 + +template <typename T, T N> void f(T(&)[N]); + +int main() { + int x[2]; + unsigned int y[2]; + f(x); // works + f(y); // ICE +} diff --git a/gcc/testsuite/g++.dg/template/array21.C b/gcc/testsuite/g++.dg/template/array21.C new file mode 100644 index 000000000..5c5f2f65d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array21.C @@ -0,0 +1,50 @@ +// PR c++/42447 + +template<int> + void* get(int); + +template<typename> + struct unique_ptr; + +template<typename _Tp> + struct unique_ptr<_Tp[]> + { + typedef int __tuple_type; + + void* + get() const + { return ::get<0>(_M_t); } + + __tuple_type _M_t; + }; + +template <typename T> class dynamic_dispatch; + +template <typename TC> + struct dynamic_dispatch<void (TC::*)(int&)> + { + struct entry { }; + unique_ptr<entry[]> m_Start; + + template <typename UC> + void attach_handler(void (UC::*m)(int&)) + { + entry* p = 0; + do { + } while(--p != m_Start.get()); + } + }; + +template <typename TC> + class request_dispatcher + : private dynamic_dispatch<void (TC::*)(int&)> + { request_dispatcher(); }; + +struct file_reader +{ + void execute_command(int&); +}; + +template <> + request_dispatcher<file_reader>::request_dispatcher() + { this->attach_handler(&file_reader::execute_command); } diff --git a/gcc/testsuite/g++.dg/template/array22.C b/gcc/testsuite/g++.dg/template/array22.C new file mode 100644 index 000000000..e10158773 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array22.C @@ -0,0 +1,14 @@ +// PR c++/48029 + +template <class T> struct A { }; +template <class T, class U> struct B +{ + struct N { }; + typedef U u; +}; + +typedef B<int, A<int>(*)[2]> btype; +A<int> v1[2]; +btype v2; + + diff --git a/gcc/testsuite/g++.dg/template/array24.C b/gcc/testsuite/g++.dg/template/array24.C new file mode 100644 index 000000000..07879d250 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array24.C @@ -0,0 +1,22 @@ +// PR c++/55032 + +template<typename T> +struct vec3t { + T c[3]; +}; + +typedef vec3t<float> vec3; + +class Bounds { + public: + Bounds(const vec3 bb[2]); + void foo(const vec3 & v) { v.c[0]; } +}; + +template<typename T> +void work(T& value); + +void foo() { + vec3 bb[2]; + work(bb); +} diff --git a/gcc/testsuite/g++.dg/template/array25.C b/gcc/testsuite/g++.dg/template/array25.C new file mode 100644 index 000000000..4f3ccbf70 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array25.C @@ -0,0 +1,18 @@ +// PR c++/55249 + +template <typename _Tp> struct A +{ + _Tp _M_instance[1]; +}; +template <class> struct inner_type +{ + inner_type () {} + inner_type (inner_type &); + inner_type (const inner_type &) {} +}; + +int +main () +{ + A <inner_type <int> > a, b = a; +} diff --git a/gcc/testsuite/g++.dg/template/array3.C b/gcc/testsuite/g++.dg/template/array3.C new file mode 100644 index 000000000..27d72f972 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array3.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// Origin: Graeme Prentice <gprentice at paradise dot net dot nz> +// PR c++/13474: An array domain which is value-dependent must be folded +// in time for deduction. + +template< int X, int Y, int (*array_ptr)[Y] > +class A; + +int array[5]; + +template< int X > +class A<X,5,&array> {}; + +int main() +{ + A<6,5,&array> z1; +} diff --git a/gcc/testsuite/g++.dg/template/array4.C b/gcc/testsuite/g++.dg/template/array4.C new file mode 100644 index 000000000..c72782b10 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array4.C @@ -0,0 +1,11 @@ +// PR c++/14122 + +extern const char str[]; + +template <const char* P> +struct A +{ + template <const char* R> void foo(); +}; + +template class A<str>; diff --git a/gcc/testsuite/g++.dg/template/array5.C b/gcc/testsuite/g++.dg/template/array5.C new file mode 100644 index 000000000..a54358067 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array5.C @@ -0,0 +1,14 @@ +// PR c++/15427 + +template<class T> +struct A +{ + T foo; +}; + +template<class T> +struct B +{ + A<int> _squares[2]; +}; + diff --git a/gcc/testsuite/g++.dg/template/array6.C b/gcc/testsuite/g++.dg/template/array6.C new file mode 100644 index 000000000..0dc5161b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array6.C @@ -0,0 +1,13 @@ +// PR c++/15287 + +struct S {}; + +struct Array { + S operator[](int); +} array; + +void (S::*mem_fun_ptr)(); + +template <int> void foo() { + (array[0].*mem_fun_ptr)(); +} diff --git a/gcc/testsuite/g++.dg/template/array7.C b/gcc/testsuite/g++.dg/template/array7.C new file mode 100644 index 000000000..1fb130f99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array7.C @@ -0,0 +1,11 @@ +// PR c++/16246 + +template <typename T> void foo (T, T); + +template <unsigned N, unsigned M> +int bar( const char(&val)[M] ) +{ + foo (N,M); +} + +int i = bar<10>("1234"); diff --git a/gcc/testsuite/g++.dg/template/array8.C b/gcc/testsuite/g++.dg/template/array8.C new file mode 100644 index 000000000..9fd33a4aa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array8.C @@ -0,0 +1,16 @@ +// PR c++/18121 + +// We were trying to layout the array +// type but since the type/value of A<N>::i +// was not known at template declation type, +// we were crashing + +template<int> struct A +{ + static int const i = 1; +}; + +template<int N> struct B +{ + typedef int (*p)[A<N>::i]; +}; diff --git a/gcc/testsuite/g++.dg/template/array9.C b/gcc/testsuite/g++.dg/template/array9.C new file mode 100644 index 000000000..f3e8335c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array9.C @@ -0,0 +1,18 @@ +// PR c++/18429 + +int subtrees = 4; +template< class T > +struct Tree { + Tree* L[subtrees]; // { dg-error "" } + Tree* R[subtrees]; // { dg-error "" } + ~Tree() + { + delete [] L[0]; // { dg-error "" } + delete [] R[0]; // { dg-error "" } + } +}; + +void f() +{ + Tree<int> t; +} diff --git a/gcc/testsuite/g++.dg/template/asm1.C b/gcc/testsuite/g++.dg/template/asm1.C new file mode 100644 index 000000000..741759fd2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/asm1.C @@ -0,0 +1,14 @@ +// PR c++/24761 +// { dg-do compile } + +template <int> +int f (int i) +{ + asm ("# %0 %1" : "+r" (i)); + return i; +} + +int main () +{ + return f<0> (0) + f<1> (0); +} diff --git a/gcc/testsuite/g++.dg/template/asmgoto1.C b/gcc/testsuite/g++.dg/template/asmgoto1.C new file mode 100644 index 000000000..6a3cbcef4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/asmgoto1.C @@ -0,0 +1,18 @@ +// PR c++/52247 +// { dg-do compile } + +template <int N> +bool +bar () +{ + __asm goto ("" : : : : lab); + return true; +lab: + return false; +} + +bool +foo () +{ + return bar<0> (); +} diff --git a/gcc/testsuite/g++.dg/template/assign1.C b/gcc/testsuite/g++.dg/template/assign1.C new file mode 100644 index 000000000..d0e134a47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/assign1.C @@ -0,0 +1,15 @@ +// PR c++/16623 + +template <int N> +struct C +{ + C& operator= (int); +}; + +template <int N> +C<N>& C<N>::operator= (int) +{ + return *this; +} + +C<0> a; diff --git a/gcc/testsuite/g++.dg/template/builtin1.C b/gcc/testsuite/g++.dg/template/builtin1.C new file mode 100644 index 000000000..a5b7271cb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/builtin1.C @@ -0,0 +1,11 @@ +// PR c++/26559 + +template<bool> struct cond; + +template<int> struct S { + void f(int i) { + cond<__builtin_constant_p(i)>(); + } +}; + +S<1> s; diff --git a/gcc/testsuite/g++.dg/template/call1.C b/gcc/testsuite/g++.dg/template/call1.C new file mode 100644 index 000000000..3b6e367af --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call1.C @@ -0,0 +1,17 @@ +//Origin: harinath@cs.umn.edu +//PR c++/10804 +// G++ was not emiting the function foo. + +// { dg-do run } + + +template<class T> +struct A +{ + A() { const void (*a)() = foo; } + static const void foo() {} +}; +int main(int argc, char *argv[]) +{ + A<int> a; +} diff --git a/gcc/testsuite/g++.dg/template/call2.C b/gcc/testsuite/g++.dg/template/call2.C new file mode 100644 index 000000000..86d5c2e82 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call2.C @@ -0,0 +1,14 @@ +// PR c++/13592 + +struct S { + void operator()(int); +}; + +struct A { + template <typename> void foo(); + S s; +}; + +template <typename> void A::foo() { + s(0); +} diff --git a/gcc/testsuite/g++.dg/template/call3.C b/gcc/testsuite/g++.dg/template/call3.C new file mode 100644 index 000000000..bbb6c7b3a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call3.C @@ -0,0 +1,15 @@ +// PR c++/18436 + +void foo(int); + +struct A +{ + static void foo(A); +}; + +template <typename T> struct B : T +{ + B() { foo(T()); } // { dg-error "cannot convert" } +}; + +B<A> b; diff --git a/gcc/testsuite/g++.dg/template/call4.C b/gcc/testsuite/g++.dg/template/call4.C new file mode 100644 index 000000000..1f7eb4c82 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call4.C @@ -0,0 +1,21 @@ +// PR c++/25364 + +class OFX_PropertySuiteV1 +{ + static int propGetDouble (); +}; +template<int dimension, + class T, + int (*PROPGET)() + > +struct OFX_AnimatedNumberParam +{ + virtual int paramSetValueAtTime() + { + return PROPGET(); + } +}; +void f() +{ + new OFX_AnimatedNumberParam<2,double,OFX_PropertySuiteV1::propGetDouble>(); +} diff --git a/gcc/testsuite/g++.dg/template/call5.C b/gcc/testsuite/g++.dg/template/call5.C new file mode 100644 index 000000000..55cf2ddac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call5.C @@ -0,0 +1,17 @@ +// PR c++/36631 +// { dg-options "-O0" } + +template <typename T> struct B +{ + struct C + { + __attribute__ ((always_inline)) C (C const &c) {} + }; + void __attribute__ ((always_inline)) g (C c) {} +}; + +void +trigger (B <int> b, B <int>::C c) +{ + b.g (c); +} diff --git a/gcc/testsuite/g++.dg/template/call6.C b/gcc/testsuite/g++.dg/template/call6.C new file mode 100644 index 000000000..b79d624a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call6.C @@ -0,0 +1,24 @@ +// PR c++/38577 +// { dg-do compile } + +struct A +{ + static A *bar (); +}; + +struct B : public A +{ + static void baz (); +}; + +template <class T> +void foo () +{ + (static_cast<B *> (A::bar ()))->baz (); +} + +void +bar () +{ + foo<int> (); +} diff --git a/gcc/testsuite/g++.dg/template/call7.C b/gcc/testsuite/g++.dg/template/call7.C new file mode 100644 index 000000000..0e9a4b7ae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call7.C @@ -0,0 +1,19 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/17395 +// { dg-do compile } + +template<int> struct X { }; + +void fu(int a, X<sizeof(a)>) { } + +template<class T> +void bhar(T a, X<sizeof(a)>) { } + +int +main() +{ + int x; + X<sizeof(int)> y; + fu(x, y); + bhar(x, y); +} diff --git a/gcc/testsuite/g++.dg/template/canon-type-1.C b/gcc/testsuite/g++.dg/template/canon-type-1.C new file mode 100644 index 000000000..b467dffef --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-1.C @@ -0,0 +1,18 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +template < typename > struct A ; +template < typename T , typename = A < T > > struct B { } ; +template < class W , class > struct D +{ + typedef W X ; + A<X*> a ; +}; + +template < class Y > struct E +{ + B<Y*> b ; +} ; +E<int> e ; + diff --git a/gcc/testsuite/g++.dg/template/canon-type-10.C b/gcc/testsuite/g++.dg/template/canon-type-10.C new file mode 100644 index 000000000..0ff45e7af --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-10.C @@ -0,0 +1,23 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// { dg-do compile } + +template<class T> +struct C +{ +}; + +template<class T, + template<class TT_T0, template<class TT_T1> class TT_TT> class TT, + class U = TT<int, C> > +struct S +{ + void foo(TT<T, C>); +}; + +template<class T, + template<class TT_T0, template<class TT_T1> class TT_TT> class TT, + class U> +void +S<T, TT, U>::foo(TT<T, C>) +{ +} diff --git a/gcc/testsuite/g++.dg/template/canon-type-11.C b/gcc/testsuite/g++.dg/template/canon-type-11.C new file mode 100644 index 000000000..0fe99511e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-11.C @@ -0,0 +1,39 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// { dg-do compile } + +template<class T> +struct C +{ + void bar(); +}; + +template<class T> +void +C<T>::bar() +{ +} + + +template<class U, + template<class TT0_T0> class TT0 = C, + template<class TT1_T0> class TT1 = TT0> +struct S +{ + C<U> s; + + void foo(TT1<U>); + + void bar() + { + foo(s); + } +}; + +template<class T, + template<class TT0_T0> class TT0, + template<class TT1_T0> class TT1> +void +S<T, TT0, TT1>::foo(TT1<T>) +{ + C<T> c; +} diff --git a/gcc/testsuite/g++.dg/template/canon-type-12.C b/gcc/testsuite/g++.dg/template/canon-type-12.C new file mode 100644 index 000000000..08c86f0a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-12.C @@ -0,0 +1,21 @@ +// { dg-options "-std=c++0x" } + +template<class T, T t = (T)0> +struct S +{ + void + foo(decltype(t) = t); +}; + +template<class T, T t> +void +S<T, t>::foo(decltype(t)) +{ +} + +void +bar() +{ + S<int> s; + s.foo(); +} diff --git a/gcc/testsuite/g++.dg/template/canon-type-13.C b/gcc/testsuite/g++.dg/template/canon-type-13.C new file mode 100644 index 000000000..4f3702b84 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-13.C @@ -0,0 +1,27 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// { dg-do compile } + +template<class T> +struct S0 +{ +}; + +template<class T> +struct S1 +{ +}; + +template<class T, template<class T> class A, template<class T> class B = A> +struct C +{ + B<T> m; +}; + +void +foo() +{ + C<int, S0> s; + S0<int> s0; + + s.m = s0; +} diff --git a/gcc/testsuite/g++.dg/template/canon-type-2.C b/gcc/testsuite/g++.dg/template/canon-type-2.C new file mode 100644 index 000000000..a3f3f1b83 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-2.C @@ -0,0 +1,18 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +template < typename > struct A ; +template < typename T , typename = A < T > > struct B { } ; +template < class W , class > struct D +{ + typedef W X ; + A< X()> a ; +}; + +template < class Y > struct E +{ + B< Y()> b ; +}; +E<int> e ; + diff --git a/gcc/testsuite/g++.dg/template/canon-type-3.C b/gcc/testsuite/g++.dg/template/canon-type-3.C new file mode 100644 index 000000000..e47c7d350 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-3.C @@ -0,0 +1,20 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +template<typename> struct A ; +template<typename T , typename = A<T> > struct B { } ; +template<class W , class > struct D +{ + typedef W X ; + typedef X (FP) (); + A<FP&> a ; +} ; + +template < class Y > struct E +{ + typedef Y (FP) (); + B<FP&> b ; +} ; +E < int > e ; + diff --git a/gcc/testsuite/g++.dg/template/canon-type-4.C b/gcc/testsuite/g++.dg/template/canon-type-4.C new file mode 100644 index 000000000..673121bd2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-4.C @@ -0,0 +1,22 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +template<typename> struct A ; +template<typename T ,typename = A<T> > struct B { } ; + +template<class W, class> +struct D +{ + typedef W X; + A<X[2]> a; +} ; + +template<class Y> +struct E +{ + B<Y[2]> b; +}; + +E < int > e; + diff --git a/gcc/testsuite/g++.dg/template/canon-type-5.C b/gcc/testsuite/g++.dg/template/canon-type-5.C new file mode 100644 index 000000000..5f783df9b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-5.C @@ -0,0 +1,22 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +struct Foo {}; +template<typename> struct A ; +template<typename T ,typename = A<T> > struct B { } ; + +template<class W, class> +struct D +{ + typedef W X ; + A<X Foo::*> a ; +} ; + +template<class Y> +struct E +{ + B<Y Foo::*> b ; +} ; +E < int > e ; + diff --git a/gcc/testsuite/g++.dg/template/canon-type-6.C b/gcc/testsuite/g++.dg/template/canon-type-6.C new file mode 100644 index 000000000..951708747 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-6.C @@ -0,0 +1,22 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +struct Foo {}; +template<typename> struct A ; +template<typename T ,typename = A<T> > struct B { } ; + +template<class W, class> +struct D +{ + typedef W X; + A<void (Foo::*) (X)> a; +} ; + +template<class Y> +struct E +{ + B<void (Foo::*) (Y)> b; +}; +E < int > e ; + diff --git a/gcc/testsuite/g++.dg/template/canon-type-7.C b/gcc/testsuite/g++.dg/template/canon-type-7.C new file mode 100644 index 000000000..51c15342c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-7.C @@ -0,0 +1,21 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/39754 +// { dg-do compile } + +struct Foo {}; +template<typename> struct A ; +template<typename T ,typename = A<T> > struct B { } ; + +template<class W, class> +struct D +{ + typedef W X; + A<X (Foo::*) (X)> a ; +}; + +template<class Y> +struct E +{ + B<Y (Foo::*) (Y)> b ; +}; +E<int> e ; diff --git a/gcc/testsuite/g++.dg/template/canon-type-8.C b/gcc/testsuite/g++.dg/template/canon-type-8.C new file mode 100644 index 000000000..fd1fe3ce3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-8.C @@ -0,0 +1,38 @@ +// PR c++/45984 +// We were getting different canonical types for matching types because +// TYPE_ALIGN wasn't propagated to all the variants fast enough. +// { dg-options "" } + +typedef __SIZE_TYPE__ size_t; +enum { chunk_size = 16 }; +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); +typedef float __v4sf __attribute__ ((__vector_size__ (16))); +struct __attribute__((aligned((16)))) float4_t { + typedef float scalar_t; + typedef __m128 type_t; + typedef float4_t return_type_t; + type_t m; + inline __attribute__((artificial, gnu_inline, always_inline)) explicit + float4_t(scalar_t a) : m(((__m128) (__v4sf) { (a), (a), (a), (a) })) { } + inline __attribute__((artificial, gnu_inline, always_inline, pure)) friend + return_type_t operator+(float4_t lhs, float4_t rhs) { } +}; +template<size_t NumChans> class __attribute__((aligned((16)))) chunk_array_t { +public: + typedef float4_t value_type_t; + typedef value_type_t value_array_t[chunk_size/4]; + enum { num_scalars = chunk_size, num_values = num_scalars/4 }; + const value_array_t &chan(size_t c) const { } + value_type_t operator[](size_t i) const { } +}; +typedef chunk_array_t<1> chunk_array_mono_t; +typedef chunk_array_t<2> chunk_array_stereo_t; +class freeverb_stereo_t { + void process(const chunk_array_stereo_t & __restrict__ src, + chunk_array_stereo_t & __restrict__ dst) { + enum { chunk_size = chunk_array_t<1>::num_values }; + chunk_array_mono_t mix; + for (size_t i=0; i<chunk_size; ++i) + mix[i] = src.chan(0)[i] + src.chan(1)[i]; + } +}; diff --git a/gcc/testsuite/g++.dg/template/canon-type-9.C b/gcc/testsuite/g++.dg/template/canon-type-9.C new file mode 100644 index 000000000..4fcd52435 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-9.C @@ -0,0 +1,18 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// { dg-options "-std=c++0x" } +// { dg-do compile } + +struct F { F(int) {}}; + +template<class T, T* u> +struct S +{ + decltype(u) foo(T); +}; + +template<class T, T *u> +decltype(u) S<T, u>::foo(T) +{ + T t; + return t; +} diff --git a/gcc/testsuite/g++.dg/template/cast1.C b/gcc/testsuite/g++.dg/template/cast1.C new file mode 100644 index 000000000..fca3511e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cast1.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Dec 2004 <nathan@codesourcery.com> + +// PR 18949. Forgot to convert from reference. +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> + +struct A +{ + void foo(); +}; + +template<int> void bar(A& a) +{ + const_cast<A&>(a).foo(); + static_cast<A&>(a).foo(); + reinterpret_cast<A&>(a).foo(); + ((A&)a).foo(); +} + +template void bar<0>(A& a); diff --git a/gcc/testsuite/g++.dg/template/char1.C b/gcc/testsuite/g++.dg/template/char1.C new file mode 100644 index 000000000..51e72e7ad --- /dev/null +++ b/gcc/testsuite/g++.dg/template/char1.C @@ -0,0 +1,4 @@ +template <class CharType, CharType line_terminator = 0> +class String {}; + +String<signed char, 255> s; // { dg-warning "overflow" } diff --git a/gcc/testsuite/g++.dg/template/class1.C b/gcc/testsuite/g++.dg/template/class1.C new file mode 100644 index 000000000..96415fbc2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/class1.C @@ -0,0 +1,9 @@ +extern const int a; + +template <const int&> class X {}; + +template <typename> struct Y { + X<a> x; +}; + +template struct Y<int>; diff --git a/gcc/testsuite/g++.dg/template/class2.C b/gcc/testsuite/g++.dg/template/class2.C new file mode 100644 index 000000000..4144997fe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/class2.C @@ -0,0 +1,7 @@ +// PR c++/13451 + +template <class T> +struct A { + struct B; + struct A::B { }; // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/class3.C b/gcc/testsuite/g++.dg/template/class3.C new file mode 100644 index 000000000..44a02a60b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/class3.C @@ -0,0 +1,2 @@ +// PR c++/25634 +template<int> template<int> struct A; // { dg-error "too many" } diff --git a/gcc/testsuite/g++.dg/template/complit1.C b/gcc/testsuite/g++.dg/template/complit1.C new file mode 100644 index 000000000..218a7c929 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/complit1.C @@ -0,0 +1,11 @@ +// { dg-options "" } + +template <int D> struct C { + int d[3]; + C(); +}; + +template<int D> +C<D>::C() : d((int[]){1,2,3}) {} // { dg-error "array" } + +template class C<1>; diff --git a/gcc/testsuite/g++.dg/template/complit2.C b/gcc/testsuite/g++.dg/template/complit2.C new file mode 100644 index 000000000..cf3856d47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/complit2.C @@ -0,0 +1,17 @@ +// PR c++/31038 +// { dg-options "" } + +template<int> void foo() +{ + int i = (int) { 0 }; +} + +template void foo<0>(); +int f(); + +template<int> void bar() +{ + int i = (int) { f() }; +} + +template void bar<0>(); diff --git a/gcc/testsuite/g++.dg/template/cond.C b/gcc/testsuite/g++.dg/template/cond.C new file mode 100644 index 000000000..394a21c9a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond.C @@ -0,0 +1,23 @@ +// PR c++/8080 + +// Bug: the transformation in finish_while_stmt_cond produced something +// that tsubst_expr handled badly. Fixed by not doing the transformation +// while parsing a template. + +class TObject {}; + +struct TIter { + TObject *operator()(); +}; + + +template<class T> +void get_root_object(TIter& iobj) { + while ( TObject* pnew_obj = iobj() ) + ; +} + +void foo(TIter& iobj) +{ + get_root_object<int>(iobj); +} diff --git a/gcc/testsuite/g++.dg/template/cond2.C b/gcc/testsuite/g++.dg/template/cond2.C new file mode 100644 index 000000000..cf8df8cd9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond2.C @@ -0,0 +1,10 @@ +// PR c++/11962 +// { dg-options "" } + +template<int X> class c; + +template<int X, int Y> int test(c<X ? : Y>&); // { dg-error "omitted" } + +void test(c<2>*c2) { + test<0, 2>(*c2); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/cond3.C b/gcc/testsuite/g++.dg/template/cond3.C new file mode 100644 index 000000000..788b3754a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond3.C @@ -0,0 +1,15 @@ +// PR c++/13833 + +struct X { + template <typename T> + X & operator << (const T &t); + X & operator<< (int& (*p) (int&)); +}; + +X x; + +template <int> void foo () { + x << (1 ? "ok" : "failed"); +} + +template void foo<1>(); diff --git a/gcc/testsuite/g++.dg/template/cond4.C b/gcc/testsuite/g++.dg/template/cond4.C new file mode 100644 index 000000000..35416ba79 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond4.C @@ -0,0 +1,20 @@ +// PR c++/14369 + +struct A { }; + +template<class T> +struct X : A { + const A* bar() const + { return this; } + + const A& foo() const; +}; + +template<class T> +const A& X<T>::foo() const +{ + const A* t = bar(); + return *(t ? t : throw 0); +} + + diff --git a/gcc/testsuite/g++.dg/template/cond5.C b/gcc/testsuite/g++.dg/template/cond5.C new file mode 100644 index 000000000..bba31e6af --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond5.C @@ -0,0 +1,9 @@ +// PR c++/18464 + +struct A +{ + A(int); + operator void*() const; +}; + +template<int> void foo(const A& x) { 0 ? x : (x ? x : 0); } diff --git a/gcc/testsuite/g++.dg/template/cond6.C b/gcc/testsuite/g++.dg/template/cond6.C new file mode 100644 index 000000000..e4cede35b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond6.C @@ -0,0 +1,6 @@ +// PR c++/27801 + +template<int> int foo(int i) +{ + return !( (1 && i) ? 0 : 1 ); +} diff --git a/gcc/testsuite/g++.dg/template/cond7.C b/gcc/testsuite/g++.dg/template/cond7.C new file mode 100644 index 000000000..ce1c77e59 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cond7.C @@ -0,0 +1,15 @@ +// PR c++/34270 +// { dg-do compile } +// { dg-options "" } + +void foo () +{ + __typeof__ (0 ?: 0) x; + __decltype (0 ?: 0) y; +} + +template<int> void bar () +{ + __typeof__ (0 ?: 0) x; + __decltype (0 ?: 0) y; +} diff --git a/gcc/testsuite/g++.dg/template/const1.C b/gcc/testsuite/g++.dg/template/const1.C new file mode 100644 index 000000000..629c4d4a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/const1.C @@ -0,0 +1,30 @@ +// PR c++/28385 +// instantiating op() with void()() was making the compiler think that 'fcn' +// was const, so it could eliminate the call. + +// { dg-do run } + +extern "C" void abort (void); + +int barcnt = 0; + +class Foo { + public: + template<typename T> + void operator()(const T& fcn) { + fcn(); + } +}; + +void bar() { + barcnt++; +} + +int main() { + Foo myFoo; + myFoo(bar); + myFoo(&bar); + if (barcnt != 2) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/const2.C b/gcc/testsuite/g++.dg/template/const2.C new file mode 100644 index 000000000..5188fe29d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/const2.C @@ -0,0 +1,16 @@ +// PR c++/39608 +// We were improperly considering dependent members of the current +// instantiation to be non-constant (and therefore invalid template +// non-type arguments). + +template <int I> +struct C {}; + +template <class T> +struct A +{ + static const T x = 1; + C<A<T>::x> c; // { dg-bogus "invalid" } +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/const3.C b/gcc/testsuite/g++.dg/template/const3.C new file mode 100644 index 000000000..998b6976e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/const3.C @@ -0,0 +1,20 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/42251 +// { dg-do compile } + +struct foo +{ + static const bool b = false; +}; + +template<bool x> +struct S1 +{ +}; + +template<bool x> +struct S2 + : S1<foo::b> +{ +}; + diff --git a/gcc/testsuite/g++.dg/template/const4.C b/gcc/testsuite/g++.dg/template/const4.C new file mode 100644 index 000000000..6552ec6e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/const4.C @@ -0,0 +1,9 @@ +// PR c++/48657 + +template<unsigned> struct A { typedef int T; }; + +template<unsigned> void f() +{ + const unsigned D = 4; + A<D>::T t; +} diff --git a/gcc/testsuite/g++.dg/template/const5.C b/gcc/testsuite/g++.dg/template/const5.C new file mode 100644 index 000000000..5d3ec5b1c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/const5.C @@ -0,0 +1,12 @@ +// PR c++/49176 +// { dg-options -std=c++0x } + +struct A { static int a(); }; + +template<int> +struct B { static int const b; }; + +int f() { return B<0>::b; } + +template<int I> +int const B<I>::b=A::a(); diff --git a/gcc/testsuite/g++.dg/template/constant1.C b/gcc/testsuite/g++.dg/template/constant1.C new file mode 100644 index 000000000..a2c5a08d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/constant1.C @@ -0,0 +1,13 @@ +// PR c++/49855 + +extern void foo(int); + +template <class Key, class Value> void Basic() { + const int kT = 1.5e6; // <--- causes ICE + int size = kT*2/3; + do { + foo(size); + size = size * 0.5 - 1; + } while (size >= 0 ); + +} diff --git a/gcc/testsuite/g++.dg/template/constant2.C b/gcc/testsuite/g++.dg/template/constant2.C new file mode 100644 index 000000000..f71e4f56a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/constant2.C @@ -0,0 +1,22 @@ +// PR c++/49896 + +template<class C> +class test { + protected: + static const int versionConst = 0x80000000; + enum { versionEnum = versionConst }; + public: + int getVersion(); +}; + +template<class C> +int test<C>::getVersion() { + return versionEnum; +} + +class dummy_class {}; + +int main() { + test<dummy_class> t; + return t.getVersion(); +} diff --git a/gcc/testsuite/g++.dg/template/conv1.C b/gcc/testsuite/g++.dg/template/conv1.C new file mode 100644 index 000000000..e0c749203 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv1.C @@ -0,0 +1,28 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 4361. Template conversion operators were not overloaded. + +template <class T> struct Second; + +template<class T> struct First +{ + int Foo (); + + template <class U> operator Second<U>(); + template <class U> operator First<U>(); +}; + +template <class T> int First<T>::Foo () +{} // This is here to make sure we didn't smash Foo's decl in the + // method vector + +struct B { }; +struct D { }; + +void Foo () +{ + First<B> (First<D>::*pf)() = &First<D>::operator First<B>; +} diff --git a/gcc/testsuite/g++.dg/template/conv10.C b/gcc/testsuite/g++.dg/template/conv10.C new file mode 100644 index 000000000..0a001be14 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv10.C @@ -0,0 +1,9 @@ +// PR c++/41994 + +template<typename T> struct A +{ + operator T(); + A() { T (A::*f)() = &A::operator T; } +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/conv11.C b/gcc/testsuite/g++.dg/template/conv11.C new file mode 100644 index 000000000..57d06af3e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv11.C @@ -0,0 +1,11 @@ +int i; +struct A +{ + template <class T> operator T&() { return i; } // { dg-message "note" } +}; + +int main() +{ + A().operator int(); // { dg-error "operator int" } + // { dg-message "candidate" "candidate note" { target *-*-* } 9 } +} diff --git a/gcc/testsuite/g++.dg/template/conv2.C b/gcc/testsuite/g++.dg/template/conv2.C new file mode 100644 index 000000000..a0d08df55 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv2.C @@ -0,0 +1,39 @@ +// { dg-do run } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 4361. Template conversion operators were not overloaded. + +class C +{ +public: + + operator float () {return 2;} + + operator int () + { + return 0; + } + + template<typename T> + operator int () + { return 1; + } +}; + +int main () +{ + C p; + int r; + + r = p.operator int (); + if (r) + return r; + r = static_cast <int> (p); + + if (r) + return r + 2; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/conv3.C b/gcc/testsuite/g++.dg/template/conv3.C new file mode 100644 index 000000000..a6b0f639b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv3.C @@ -0,0 +1,43 @@ +// { dg-do run } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 4361. Template conversion operators were not overloaded. + +template <typename T> struct C +{ + operator T () + { + return 0; + } + template <typename T2> operator T2 () + { + return 1; + } + int Foo () + { + return operator T (); + } + template <typename T2> int Baz () + { + return static_cast <int> (operator T2 ()); + } +}; + +int main () +{ + int r; + C<int> c; + + r = c.Foo (); + if (r) + return 1; + r = c.Baz<int> (); + if (r) + return 2; + r = c.Baz<float> (); + if (!r) + return 3; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/conv4.C b/gcc/testsuite/g++.dg/template/conv4.C new file mode 100644 index 000000000..01f158aef --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv4.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 4361. Template conversion operators were not overloaded. + +struct C +{ + template <typename T2> operator T2 () + { + return 1; + } + int Foo () + { + return operator int (); + } +}; + +struct D +{ + int Foo () + { + return operator int (); // { dg-error "not defined" "" } + } +}; + diff --git a/gcc/testsuite/g++.dg/template/conv5.C b/gcc/testsuite/g++.dg/template/conv5.C new file mode 100644 index 000000000..80835437a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv5.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Dec 2002 <nathan@codesourcery.com> + +// PR 764. Failed to find friend in overload resolution + +template <class T> +struct S +{ + friend bool operator== (const S&, const S&) { + return true; + } +}; + +int main () +{ + // S<int> s; + + const S<int> *p = 0; + *p == *p; // error +} diff --git a/gcc/testsuite/g++.dg/template/conv6.C b/gcc/testsuite/g++.dg/template/conv6.C new file mode 100644 index 000000000..2a4a29952 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv6.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Mar 2003 <nathan@codesourcery.com> + +// PR 9898, DR 322. Conversion to reference type. + +template <typename> struct Ref {}; +template <typename> struct Val {}; + +struct Wrapper +{ + template <typename U> operator Ref<U> & (); + template <typename U> operator Val<U> (); +}; + +void Foo (Wrapper l) +{ + static_cast <Ref<int> &> (l); + static_cast <Ref<int> const &> (l); + static_cast <Ref<int> > (l); + static_cast <Val<int> const &> (l); + static_cast <Val<int> > (l); +} diff --git a/gcc/testsuite/g++.dg/template/conv7.C b/gcc/testsuite/g++.dg/template/conv7.C new file mode 100644 index 000000000..86758b362 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv7.C @@ -0,0 +1,12 @@ +// { dg-options "-fabi-version=0" } + +template <typename T> struct S { + struct I{}; + operator I* (); +}; + +template <typename T> struct S2 : S<T> { + operator typename S<T>::I* (); +}; + +template struct S2<int>; diff --git a/gcc/testsuite/g++.dg/template/conv8.C b/gcc/testsuite/g++.dg/template/conv8.C new file mode 100644 index 000000000..01d415b3e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv8.C @@ -0,0 +1,12 @@ +// { dg-options "-fabi-version=1 -Wno-abi" } + +template <typename T> struct S { + struct I{}; + operator I* (); +}; + +template <typename T> struct S2 : S<T> { + operator typename S<T>::I* (); +}; + +template struct S2<int>; diff --git a/gcc/testsuite/g++.dg/template/conv9.C b/gcc/testsuite/g++.dg/template/conv9.C new file mode 100644 index 000000000..269e338a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv9.C @@ -0,0 +1,16 @@ +// PR c++/28557 + +struct A +{ + template<typename T> operator T() { return T(); } +}; + +template<int> void foo() +{ + A().operator int(); +} + +void bar() +{ + foo<0>(); +} diff --git a/gcc/testsuite/g++.dg/template/copy1.C b/gcc/testsuite/g++.dg/template/copy1.C new file mode 100644 index 000000000..c6b3ff806 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/copy1.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: hkluender@otg.com + +// PR 5189 + +struct A +{ + A(A&); // { dg-message "note" } + template <class T> A(T); // { dg-message "note" } +}; + +A a = 0; // { dg-error "no matching function" } +// { dg-message "candidate" "candidate note" { target *-*-* } 13 } + diff --git a/gcc/testsuite/g++.dg/template/crash1.C b/gcc/testsuite/g++.dg/template/crash1.C new file mode 100644 index 000000000..a500da18b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash1.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 5125. ICE + +class S +{ + public: + template <class I> void Foo(int (*f)(S& o) ); +}; + +template <class I> +void S::Foo(int (*f)(TYPO&o) ) // { dg-error "Foo|f|TYPO|o" } +{ +} diff --git a/gcc/testsuite/g++.dg/template/crash10.C b/gcc/testsuite/g++.dg/template/crash10.C new file mode 100644 index 000000000..62647ca72 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash10.C @@ -0,0 +1,27 @@ +//Origin: benko@sztaki.hu +//PR c++/11432 +// The mainline ICE on this one between 2003-01-16 and 2003-07-29. + +// { dg-do compile } + + extern "C" void abort(); + + +template <int A> +struct a +{ + static int const value = A - 1; +}; + + +template <int B> +struct b +{ + static int foo() + { + return a<L>::value; + } + + + static int const L = a<B + 1>::value; +}; diff --git a/gcc/testsuite/g++.dg/template/crash100.C b/gcc/testsuite/g++.dg/template/crash100.C new file mode 100644 index 000000000..c67ae2eca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash100.C @@ -0,0 +1,24 @@ +// PR c++/44628 + +template <typename T> +class Temp +{ + int Val; + public: + operator T&(void) { return Val; } + + virtual T& operator=(T a ) // { dg-error "overriding" } + { + Val = a; + return Val; + } +}; + +class Int : public Temp<int> +{ + public: + Int& operator=(int a) // { dg-error "conflicting return type" } + { + return (*this); + } +}; diff --git a/gcc/testsuite/g++.dg/template/crash101.C b/gcc/testsuite/g++.dg/template/crash101.C new file mode 100644 index 000000000..c59737a89 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash101.C @@ -0,0 +1,12 @@ +// PR c++/44039 + +struct locale { }; + +template<class charT> + void + foo() + { locale::locale(); } // { dg-error "cannot call|function-style" } + +void +bar() +{ foo<char>(); } diff --git a/gcc/testsuite/g++.dg/template/crash102.C b/gcc/testsuite/g++.dg/template/crash102.C new file mode 100644 index 000000000..fd3c36eec --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash102.C @@ -0,0 +1,5 @@ +// PR c++/45043 + +template < typename > class A; +template < typename T > A < T >::B::~B () // { dg-error "type" } +{} diff --git a/gcc/testsuite/g++.dg/template/crash103.C b/gcc/testsuite/g++.dg/template/crash103.C new file mode 100644 index 000000000..9f3e224e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash103.C @@ -0,0 +1,4 @@ +// PR c++/45665 + +template < typename > struct S; +void (S <0>::*ptr) (); // { dg-error "type" } diff --git a/gcc/testsuite/g++.dg/template/crash104.C b/gcc/testsuite/g++.dg/template/crash104.C new file mode 100644 index 000000000..097c46982 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash104.C @@ -0,0 +1,26 @@ +// PR c++/46046 + +template <class T> + struct foo +{ + template <class U, class V = void> + struct type + {}; + + template <class V> + struct type< + typename T::template some_type<int>, + V + > + {}; +}; + +template <class T> + class bar +{}; + +int main() +{ + typedef foo<bar<int> > cont; + cont::type<char> obj; // { dg-error "cannot be defined" } +} diff --git a/gcc/testsuite/g++.dg/template/crash105.C b/gcc/testsuite/g++.dg/template/crash105.C new file mode 100644 index 000000000..649bf8b77 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash105.C @@ -0,0 +1,14 @@ +// PR c++/44118 + +template < typename > struct S; +template < typename > struct S < int >; // { dg-error "template" } +template < typename > struct S < int > +{ + void f (); +}; + +void +f () +{ + S < int >::f (); // { dg-error "cannot call" } +} diff --git a/gcc/testsuite/g++.dg/template/crash106.C b/gcc/testsuite/g++.dg/template/crash106.C new file mode 100644 index 000000000..c2d117e03 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash106.C @@ -0,0 +1,12 @@ +// PR c++/47974 + +typedef double T; + +struct A +{ + template<T> void foo(); // { dg-error "type" } +}; + +template<T N = 0, void (A::*)() = &A::foo<N> > struct B {}; // { dg-error "type|declared" } + +B<> b; // { dg-error "type|declaration" } diff --git a/gcc/testsuite/g++.dg/template/crash11.C b/gcc/testsuite/g++.dg/template/crash11.C new file mode 100644 index 000000000..3c69514e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash11.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +// Origin: kparz@iastate.edu + +// PR c++/7939: ICE for invalid function parameter after template +// substitution. + +template <class T, class U> void foo(T, U) {} +template <class T> void foo<T,void>(T, void) {} // { dg-error "incomplete|invalid|partial" } diff --git a/gcc/testsuite/g++.dg/template/crash12.C b/gcc/testsuite/g++.dg/template/crash12.C new file mode 100644 index 000000000..e2231e06b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash12.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: rmerkert@alphatech.com +// Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/12495: ICE looking up class template in local class. + +template <typename> struct A {}; + +template <typename T> void foo() +{ + struct B + { + B (const A<T>&); + }; +} diff --git a/gcc/testsuite/g++.dg/template/crash13.C b/gcc/testsuite/g++.dg/template/crash13.C new file mode 100644 index 000000000..0518666d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash13.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/11076: ICE for invalid access declaration containing typename. + +template<typename, typename T=void> struct A +{ + typedef A<T,T> B; +}; + +template <typename T> struct C +{ + typedef typename A<T>::B X; + X::Y; // { dg-error "not a base type" } +}; + +C<void> c; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/crash14.C b/gcc/testsuite/g++.dg/template/crash14.C new file mode 100644 index 000000000..cf6fffa1a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash14.C @@ -0,0 +1,5 @@ +// { dg-options -std=c++98 } + +template <int T> class foo { public: foo() { } class Z { };}; +template <int I[2]> void dep7(foo<I[0]> *) { } // { dg-error "" } + diff --git a/gcc/testsuite/g++.dg/template/crash15.C b/gcc/testsuite/g++.dg/template/crash15.C new file mode 100644 index 000000000..e0aad73c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash15.C @@ -0,0 +1,9 @@ +// PR c++/13310 + +struct A {}; + +template <typename> void foo() +{ + A a; + a.foo<int>(); // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/template/crash16.C b/gcc/testsuite/g++.dg/template/crash16.C new file mode 100644 index 000000000..f80dd1064 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash16.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Alexander Stippler <stip@mathematik.uni-ulm.de> +// PR c++/10079 + +template <bool> struct A {}; + +template <typename> struct B +{ + enum { e }; +}; + +template <typename T> A<(B<T>::e && 0)> foo(T) {} + +template <typename T> void foo(B<T>) {} + +void bar() +{ + B<int> b; + foo(b); +} diff --git a/gcc/testsuite/g++.dg/template/crash17.C b/gcc/testsuite/g++.dg/template/crash17.C new file mode 100644 index 000000000..9fa826b99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash17.C @@ -0,0 +1,19 @@ +template <int I> +struct A { +}; + +template <typename T> +struct B { + typedef typename T::type type; + static const type j = T::j; + + A<j> b; +}; + +struct C { + typedef int type; + static const int j = 3; +}; + +int i = B<C>::j; + diff --git a/gcc/testsuite/g++.dg/template/crash18.C b/gcc/testsuite/g++.dg/template/crash18.C new file mode 100644 index 000000000..5eb92929c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash18.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// Contributed by: <leif dot lonnblad at thep dot lu dot se> +// PR c++/15064: typeid does not form an integral constant expression + +#include <typeinfo> + +template <typename T> +void dummy() { + const std::type_info& t = typeid(T); + const std::type_info& t2 = typeid(float); +} + +template void dummy<int>(void); diff --git a/gcc/testsuite/g++.dg/template/crash19.C b/gcc/testsuite/g++.dg/template/crash19.C new file mode 100644 index 000000000..a28827f31 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash19.C @@ -0,0 +1,17 @@ +// PR c++/15165 + +struct S +{ + template <class T> S(const T &e); +}; +int operator *(const double, const S &); +template <class T> +struct X { + enum { SIXTY_FOUR=64 }; + struct node { + unsigned char *ptr[sizeof(T)*SIXTY_FOUR]; + void d() {} + }; + node *head; +}; +template struct X<int>; diff --git a/gcc/testsuite/g++.dg/template/crash2.C b/gcc/testsuite/g++.dg/template/crash2.C new file mode 100644 index 000000000..47c95ab06 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash2.C @@ -0,0 +1,31 @@ +// { dg-options "" } + +template <class EnumType> +class A +{ +public: + static const EnumType size = max; // { dg-error "" } + int table[size]; // { dg-error "constant" } +}; +template <class EnumType> +const EnumType A<EnumType>::size; + + +namespace N +{ +enum E { max = 5 }; + +struct B +{ + A<E> a; +}; + +} + +int +main() +{ + N::B b; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/crash20.C b/gcc/testsuite/g++.dg/template/crash20.C new file mode 100644 index 000000000..0492b72e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash20.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2004 <nathan@codesourcery.com> + +// ICE with incompletable type. + +class INC; + +template <typename T> class B {}; + +template<typename T> void Foo (B<T> &); + +void Foo (INC &); + +void Baz (INC *p) +{ + Foo (*p); +} + diff --git a/gcc/testsuite/g++.dg/template/crash21.C b/gcc/testsuite/g++.dg/template/crash21.C new file mode 100644 index 000000000..8b674910e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash21.C @@ -0,0 +1,40 @@ +// { dg-do compile } + +// Origin: Debian GCC maintainers <debian-gcc@lists.debian.org> +// Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/16706: Dependent type calculation during access checking + +template <typename> struct B { + B() throw() {} + struct S { }; + static int i; + typedef unsigned short int dummy; +}; + +template <typename _Tp> +struct allocator: B<_Tp> { + template<typename _Tp1> struct rebind + { typedef allocator<_Tp1> other; }; +}; + +template<typename T, typename> +struct X { + typename allocator<T>::template rebind<int>::other i; + typedef int* dummy; +}; + +template <class T> class A { + typedef typename X<T,allocator<T> >::dummy dummy; + template <class TP> class XWrapper; +}; + + +template <class T> +template <class TP> struct A<T>::XWrapper<TP *> +{ + XWrapper() {} + X<int,allocator<int> > x; +}; + +template class A<int>::XWrapper<int *>; diff --git a/gcc/testsuite/g++.dg/template/crash22.C b/gcc/testsuite/g++.dg/template/crash22.C new file mode 100644 index 000000000..4d0cfaa99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash22.C @@ -0,0 +1,26 @@ +// { dg-do compile } + +// Origin: Debian GCC maintainers <debian-gcc@lists.debian.org> +// Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/16706: Dependent type calculation during access checking + +template<typename> struct A +{ + A(); + template<typename> struct X {}; +}; + +template<typename T> struct B +{ + typename A<T>::template X<int> x; + template<typename> struct C; +}; + +template<typename T> template<typename U> struct B<T>::C<U*> +{ + C() {} + A<int> a; +}; + +template struct B<int>::C<int*>; diff --git a/gcc/testsuite/g++.dg/template/crash23.C b/gcc/testsuite/g++.dg/template/crash23.C new file mode 100644 index 000000000..0c3eac1ac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash23.C @@ -0,0 +1,9 @@ +// PR c++/17642 + +template<int dim> +int f(const int* const lsh, const int* const bbox, const int* const nghostzones, int d) +{ + for (int d=0; d<dim; ++d) + lsh[d] - (bbox[2*d+1] ? 0 : nghostzones[d]); +} + diff --git a/gcc/testsuite/g++.dg/template/crash24.C b/gcc/testsuite/g++.dg/template/crash24.C new file mode 100644 index 000000000..49b8c7e71 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash24.C @@ -0,0 +1,14 @@ +// PR c++/17826 + +struct A +{ + template<typename> static int foo(); +}; + +template<int> struct B {}; + +template<typename T> void bar() +{ + B<sizeof A::foo<T>()> b1; + B<sizeof A::foo<T>()> b2; +} diff --git a/gcc/testsuite/g++.dg/template/crash25.C b/gcc/testsuite/g++.dg/template/crash25.C new file mode 100644 index 000000000..fa77f0d4f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash25.C @@ -0,0 +1,3 @@ +// PR c++/18124 + +template <template <int> class class> class A {}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash26.C b/gcc/testsuite/g++.dg/template/crash26.C new file mode 100644 index 000000000..f1bc399a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash26.C @@ -0,0 +1,8 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/18471: ICE redeclaration of typedef as class template + +typedef int X; // { dg-error "previous" } +template<X> struct X {}; // { dg-error "typedef-name" } diff --git a/gcc/testsuite/g++.dg/template/crash27.C b/gcc/testsuite/g++.dg/template/crash27.C new file mode 100644 index 000000000..d2f6289d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash27.C @@ -0,0 +1,4 @@ +// PR c++/18586 +template <int> struct A { + template <int N> int A<N>::i; // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash28.C b/gcc/testsuite/g++.dg/template/crash28.C new file mode 100644 index 000000000..e8b2bbb29 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash28.C @@ -0,0 +1,13 @@ +// PR c++/18445 + +struct a +{ + int what(); +}; +void g(void*); +template<class T> +void f() +{ + a ex; + g(ex.what); // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/template/crash29.C b/gcc/testsuite/g++.dg/template/crash29.C new file mode 100644 index 000000000..55953ed80 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash29.C @@ -0,0 +1,8 @@ +// PR c++/18512 + +template <int> struct A {}; + +struct B : A<0> +{ + void foo() { this->A<0>; } // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash3.C b/gcc/testsuite/g++.dg/template/crash3.C new file mode 100644 index 000000000..21aa57b1e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash3.C @@ -0,0 +1,12 @@ +struct S { +}; + +extern S i[]; + +void g (S*); + +template <typename T> +void f () { + g (&i[2]); +} + diff --git a/gcc/testsuite/g++.dg/template/crash30.C b/gcc/testsuite/g++.dg/template/crash30.C new file mode 100644 index 000000000..145b07673 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash30.C @@ -0,0 +1,16 @@ +// PR c++/19034 + +template< bool C > struct B +{ +}; + +template<typename S> int foo(); +template<typename S> int foo1(); + +template<typename T> struct bar : public B <(sizeof(foo<T>()) == 1)> +{ +}; + +template<typename T> struct bar1 : public B <(sizeof(foo1<T>()) == 1)> +{ +}; diff --git a/gcc/testsuite/g++.dg/template/crash31.C b/gcc/testsuite/g++.dg/template/crash31.C new file mode 100644 index 000000000..2269f47ea --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash31.C @@ -0,0 +1,3 @@ +// PR c++/19063 + +template<operator< struct A {}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash32.C b/gcc/testsuite/g++.dg/template/crash32.C new file mode 100644 index 000000000..4c7af8a39 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash32.C @@ -0,0 +1,9 @@ +// PR c++/19667 + +struct integral_constant { }; + +template<typename _Tp> +struct is_function : public integral_constant { }; + +template<> +struct is_function : public integral_constant { }; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash33.C b/gcc/testsuite/g++.dg/template/crash33.C new file mode 100644 index 000000000..059e328f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash33.C @@ -0,0 +1,8 @@ +// PR c++/19253 + +namespace N {} + +template<typename> struct A +{ + A<typename N::X<int> > a; // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash34.C b/gcc/testsuite/g++.dg/template/crash34.C new file mode 100644 index 000000000..ef4d21b60 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash34.C @@ -0,0 +1,12 @@ +// { dg-do compile } + +// PR c++/20028 + +// We used to crash when referencing TYPE_SIZE_UNIT of the messed-up +// type used for x, because it was not initialized. + +class Foo; + +template <typename T> class Foo { }; // { dg-error "not a template type" } + +Foo<int> x; // { dg-error "not a template|incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/crash35.C b/gcc/testsuite/g++.dg/template/crash35.C new file mode 100644 index 000000000..348d91d0c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash35.C @@ -0,0 +1,9 @@ +// PR c++/20463 +// { dg-do compile } + +template <typename T> struct C; // { dg-error "declaration" } + +template <typename T> void C<T>::f() // { dg-error "invalid|template" } +{ + const foo bar; +} diff --git a/gcc/testsuite/g++.dg/template/crash36.C b/gcc/testsuite/g++.dg/template/crash36.C new file mode 100644 index 000000000..2f0ef921a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash36.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> +// Andrew Pinski <pinskia@gcc.gnu.org> + +// PR c++/20333: ICE parsing typename without nested-name-specifier + +template<class> struct f {}; +f<int> f2[2] = {typename f<int>()}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash37.C b/gcc/testsuite/g++.dg/template/crash37.C new file mode 100644 index 000000000..60724231e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash37.C @@ -0,0 +1,27 @@ +// PR c++/21352 + +struct coperator_stack +{ + template<class type> + void push3() + { + } +}; + +struct helper {}; + +template<class F> +void bla(F f) // { dg-message "bla|no known conversion" } +{ +} + +template <typename ScannerT> +struct definition +{ + definition() + { + bla(coperator_stack::push3<helper>); // { dg-error "matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 23 } + } +}; + diff --git a/gcc/testsuite/g++.dg/template/crash38.C b/gcc/testsuite/g++.dg/template/crash38.C new file mode 100644 index 000000000..c652cc86f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash38.C @@ -0,0 +1,8 @@ +// PR c++/23307 + +class A +{ + template<class R> + static void f(X&); // { dg-error "" } + inline void A::f<void>(X&); // { dg-error "f|expected" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash39.C b/gcc/testsuite/g++.dg/template/crash39.C new file mode 100644 index 000000000..ddecc173c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash39.C @@ -0,0 +1,11 @@ +// PR c++/22405 + +template <typename T> void foo(T &arg) { // { dg-error "declared" } + arg+=1; +} + +template <typename T> void foo(T &arg) { // { dg-error "redefinition" } + arg+=2; +} + +template void foo(float &arg); diff --git a/gcc/testsuite/g++.dg/template/crash4.C b/gcc/testsuite/g++.dg/template/crash4.C new file mode 100644 index 000000000..72b2bb18b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash4.C @@ -0,0 +1,12 @@ +namespace NS { + struct C {}; + void foo(); +} + +template <class T> struct X {}; + +template <class T> struct A { + A() { foo (X<T>()); } + void foo(X<T>); +}; +template struct A<NS::C>; diff --git a/gcc/testsuite/g++.dg/template/crash40.C b/gcc/testsuite/g++.dg/template/crash40.C new file mode 100644 index 000000000..45123dd0d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash40.C @@ -0,0 +1,10 @@ +// PR c++/22180 + +struct A {}; + +template<typename T> void foo() +{ + T::~T(); // { dg-error "member" } +} + +template void foo<A>(); // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/crash41.C b/gcc/testsuite/g++.dg/template/crash41.C new file mode 100644 index 000000000..9a440b076 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash41.C @@ -0,0 +1,18 @@ +// PR c++/22464 + +template<typename T> +void do_something(const T* A) // { dg-error "declared" } +{ + struct helper_t{ + helper_t() { + A[0]; // { dg-error "use" } + } + } helper; +} + +void sub1() { + double A[7]; + do_something (A); +} + + diff --git a/gcc/testsuite/g++.dg/template/crash42.C b/gcc/testsuite/g++.dg/template/crash42.C new file mode 100644 index 000000000..d36ced473 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash42.C @@ -0,0 +1,10 @@ +// { dg-do compile } + +// PR c++/22153 + +template<int> void foo(); + +template<int> struct A +{ + template<> friend void foo<0>(); // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash43.C b/gcc/testsuite/g++.dg/template/crash43.C new file mode 100644 index 000000000..cbb1221b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash43.C @@ -0,0 +1,8 @@ +// PR c++/24687 + +extern "C" { + template<typename _Tp> // { dg-error "C" } + struct ___is_pod { + enum { + __value = (sizeof(__gnu_internal::__test_type<_Tp>(0)))}; // { dg-error "declared|expected" } + diff --git a/gcc/testsuite/g++.dg/template/crash44.C b/gcc/testsuite/g++.dg/template/crash44.C new file mode 100644 index 000000000..d5596c199 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash44.C @@ -0,0 +1,7 @@ +// PR c++/25858 + +namespace N { + template<int> struct A {}; +} + +struct B N::A<0> {}; // { dg-error "invalid" } diff --git a/gcc/testsuite/g++.dg/template/crash45.C b/gcc/testsuite/g++.dg/template/crash45.C new file mode 100644 index 000000000..f138e3d61 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash45.C @@ -0,0 +1,13 @@ +// PR c++/26365 + +struct A {}; + +namespace N +{ + template<int> void foo(); +} + +void bar(A *p) +{ + p->N::foo<0>; // { dg-error "not a member" } +} diff --git a/gcc/testsuite/g++.dg/template/crash46.C b/gcc/testsuite/g++.dg/template/crash46.C new file mode 100644 index 000000000..6fbda7c07 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash46.C @@ -0,0 +1,5 @@ +// PR c++/27102 + +template <class T> +void T::foo() {} // { dg-error "invalid" } + diff --git a/gcc/testsuite/g++.dg/template/crash47.C b/gcc/testsuite/g++.dg/template/crash47.C new file mode 100644 index 000000000..9c2163209 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash47.C @@ -0,0 +1,3 @@ +// PR c++/27102 + +template<typename T> void T::X::foo() {} // { dg-error "invalid|not a type" } diff --git a/gcc/testsuite/g++.dg/template/crash48.C b/gcc/testsuite/g++.dg/template/crash48.C new file mode 100644 index 000000000..6aa3aa3ed --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash48.C @@ -0,0 +1,10 @@ +// PR c++/11471 +// Origin: <bagnara@cs.unipr.it> +// { dg-do compile } + +template<typename T> struct A +{ + typedef typename T::X X; +}; + +template<typename T> A<T>::X::X() {} // { dg-error "no type|invalid use|not a type|dependent" } diff --git a/gcc/testsuite/g++.dg/template/crash49.C b/gcc/testsuite/g++.dg/template/crash49.C new file mode 100644 index 000000000..41fc9be7b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash49.C @@ -0,0 +1,4 @@ +// PR c++/27102 + +template <typename T> +void T::foo; // { dg-error "invalid" } diff --git a/gcc/testsuite/g++.dg/template/crash50.C b/gcc/testsuite/g++.dg/template/crash50.C new file mode 100644 index 000000000..006056128 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash50.C @@ -0,0 +1,7 @@ +// PR c++/27398 +// { dg-do compile } + +struct A +{ + template<int> void* foo(; // { dg-error "primary-expression|initialization|static" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash51.C b/gcc/testsuite/g++.dg/template/crash51.C new file mode 100644 index 000000000..8c2553d10 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash51.C @@ -0,0 +1,11 @@ +// PR c++/26496 + +template< typename _Generator> int generate_n(_Generator __gen); +struct Distribution { }; +typedef double (Distribution::* Pstd_mem)(); +int main(void) +{ + Distribution* rng; + Pstd_mem ptr; + generate_n(rng->*ptr); // { dg-error "non-static member" } +} diff --git a/gcc/testsuite/g++.dg/template/crash52.C b/gcc/testsuite/g++.dg/template/crash52.C new file mode 100644 index 000000000..9fc3f6833 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash52.C @@ -0,0 +1,19 @@ +// PR c++/27665 + +template<int> struct A +{ + struct B + { + struct C {}; + }; +}; + +template<int N> void foo() +{ + class A<N>::B::C X; +} + +void bar() +{ + foo<0>(); +} diff --git a/gcc/testsuite/g++.dg/template/crash53.C b/gcc/testsuite/g++.dg/template/crash53.C new file mode 100644 index 000000000..bbd1e7fc7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash53.C @@ -0,0 +1,11 @@ +// PR c++/28110 +// { dg-do compile } + +template<int> struct A {}; + +template<typename T> struct B +{ + template<T I> B(A<I>); // { dg-error "template constant parameter" } +}; + +B<double> a=A<0>(); // { dg-error "non-scalar type" } diff --git a/gcc/testsuite/g++.dg/template/crash54.C b/gcc/testsuite/g++.dg/template/crash54.C new file mode 100644 index 000000000..26b487571 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash54.C @@ -0,0 +1,5 @@ +//PR c++/28269 + +template<int> struct A; + +struct __attribute__((unused)) A<0<; // { dg-error "template argument|unqualified-id" } diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C new file mode 100644 index 000000000..7cf9f1eae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash55.C @@ -0,0 +1,6 @@ +//PR c++/27668 + +template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" } +struct A {}; + +template<int> void foo(A<int>); // { dg-error "mismatch|constant|template argument" } diff --git a/gcc/testsuite/g++.dg/template/crash56.C b/gcc/testsuite/g++.dg/template/crash56.C new file mode 100644 index 000000000..03bddf42a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash56.C @@ -0,0 +1,16 @@ +// Origin: Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/28705 +// DR 218 is debating whether this is well formed or not. We've never +// accepted it (because we'd crash), so we continue to reject it, but +// without crashing. + +namespace N +{ + struct A { A (A*); }; +} + +template<typename T> void g (N::A *p) +{ + (void) A (p); // { dg-message "" "" } +} diff --git a/gcc/testsuite/g++.dg/template/crash57.C b/gcc/testsuite/g++.dg/template/crash57.C new file mode 100644 index 000000000..cf1c3c296 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash57.C @@ -0,0 +1,10 @@ +//PR c++/27397 + +template<int(> struct A; // { dg-error "token" } + +template<typename> struct B +{ + template<int(> struct C; // { dg-error "token" } +}; + +A<char> a; // { dg-error "type/value mismatch|constant|declaration" } diff --git a/gcc/testsuite/g++.dg/template/crash58.C b/gcc/testsuite/g++.dg/template/crash58.C new file mode 100644 index 000000000..5194ee263 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash58.C @@ -0,0 +1,10 @@ +//PR 26938 + +template<int, int = 0> struct A; // { dg-message "previous declaration" } + +template<int> struct A // { dg-error "template" } +{ + A(); +}; + +A<0> a; // { dg-error "incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/crash59.C b/gcc/testsuite/g++.dg/template/crash59.C new file mode 100644 index 000000000..61d2188fc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash59.C @@ -0,0 +1,19 @@ +//PR c++/27329 + +template<int> struct A // { dg-error "forward declaration" } +! // { dg-error "expected unqualified-id" } + ; + +template<int> struct A { int foo(); }; // { dg-error "not a template" } + +int i = A<0>().foo(); // { dg-error "not a template|invalid use" } + + +template<int> struct B +! // { dg-error "expected unqualified-id" } + ; + +template<int> struct B { static int bar(); }; // { dg-error "not a template" } + +int j = B<0>::bar(); // { dg-error "not a template|incomplete type" } + diff --git a/gcc/testsuite/g++.dg/template/crash6.C b/gcc/testsuite/g++.dg/template/crash6.C new file mode 100644 index 000000000..776e01ebb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash6.C @@ -0,0 +1,8 @@ +template <class> struct A { static const int n = 1; } ; +template <int> struct B; + +template <class S> +struct restype_order { + static const int s = A<S>::n; + typedef typename B<(s > 0)>::t t; +}; diff --git a/gcc/testsuite/g++.dg/template/crash60.C b/gcc/testsuite/g++.dg/template/crash60.C new file mode 100644 index 000000000..c57977591 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash60.C @@ -0,0 +1,9 @@ +//PR c++/27961 + +struct A +{ + template<int> void foo(X); // { dg-error "declared" } +}; + +template<int> void f()(0); // { dg-error "initialize" } + diff --git a/gcc/testsuite/g++.dg/template/crash61.C b/gcc/testsuite/g++.dg/template/crash61.C new file mode 100644 index 000000000..1f70bcb89 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash61.C @@ -0,0 +1,11 @@ +// PR c++/29733 + +template<typename T> void foo() +{ + T t = 0; // { dg-error "function type" } +} + +void bar() +{ + foo<int()>(); +} diff --git a/gcc/testsuite/g++.dg/template/crash62.C b/gcc/testsuite/g++.dg/template/crash62.C new file mode 100644 index 000000000..bd8a0f40e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash62.C @@ -0,0 +1,6 @@ +// PR c++/29728 + +template<int> void foo() +{ + int a[] = { X: 0 }; // { dg-error "designated initializer" } +} diff --git a/gcc/testsuite/g++.dg/template/crash63.C b/gcc/testsuite/g++.dg/template/crash63.C new file mode 100644 index 000000000..b7056e8d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash63.C @@ -0,0 +1,12 @@ +// PR c++/29729 + +template<typename T> void foo(T) +{ + struct A + { + template<int> struct B // { dg-error "local class" } + { + typedef B<0> C; + } + }; +} diff --git a/gcc/testsuite/g++.dg/template/crash64.C b/gcc/testsuite/g++.dg/template/crash64.C new file mode 100644 index 000000000..750e3daf1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash64.C @@ -0,0 +1,6 @@ +// PR c++/29730 + +struct A +{ + template<int> void foo()(0); // { dg-error "initializer" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash65.C b/gcc/testsuite/g++.dg/template/crash65.C new file mode 100644 index 000000000..4d49ecf31 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash65.C @@ -0,0 +1,7 @@ +// PR c++/29732 + +struct A +{ + template<int> template<typename T> friend void foo(T) {} // { dg-error "parameter" } + void bar() { foo(0); } // { dg-error "foo" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash66.C b/gcc/testsuite/g++.dg/template/crash66.C new file mode 100644 index 000000000..3517311b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash66.C @@ -0,0 +1,17 @@ +// PR c++/29535 +// { dg-do compile } + +template <class INDEX> struct SetRegion2D +{ + struct FloodFillControl + { + struct Allocator{}; + }; +}; +template <int DIM, class PIXELINDEX> +struct MotionSearcher +{ + typedef SetRegion2D<PIXELINDEX> Region_t; + MotionSearcher (typename Region_t::FloodFillControl::Allocator &a_rAllocator); +}; +class MotionSearcherY : public MotionSearcher<1, int> {}; diff --git a/gcc/testsuite/g++.dg/template/crash67.C b/gcc/testsuite/g++.dg/template/crash67.C new file mode 100644 index 000000000..c80f4fb93 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash67.C @@ -0,0 +1,3 @@ +// PR c++/32561 + +template<int N, int N> struct A; // { dg-error "redefinition|declared" } diff --git a/gcc/testsuite/g++.dg/template/crash68.C b/gcc/testsuite/g++.dg/template/crash68.C new file mode 100644 index 000000000..9171f8c62 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash68.C @@ -0,0 +1,16 @@ +// PR c++/33035 + +template<class A> +struct a { + template<class B> + struct b { + template<class C> + void f() + { + struct g + { + ~g() {} + }; + } + }; +}; diff --git a/gcc/testsuite/g++.dg/template/crash69.C b/gcc/testsuite/g++.dg/template/crash69.C new file mode 100644 index 000000000..957f1e19b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash69.C @@ -0,0 +1,12 @@ +// PR c++/31132 + +template<typename T> class A +{ + static int i; // { dg-error "is private" } + friend int T::foo(); // { dg-error "does not match" } +}; + +struct B +{ + void foo() { A<B>::i; } // { dg-error "within|candidate" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash7.C b/gcc/testsuite/g++.dg/template/crash7.C new file mode 100644 index 000000000..ae07d91e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash7.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> + +// PR c++/10108: ICE in tsubst_decl for error due to non-existence +// nested type. + +template <typename> struct A +{ // { not-dg-error "candidates" } + template <typename> A(typename A::X) {} // { dg-error "no type" } +}; + +A<void> a; // { not-dg-error "instantiated|no match" } +// We currently don't give the "no match" error because we don't add the +// invalid constructor template to TYPE_METHODS. diff --git a/gcc/testsuite/g++.dg/template/crash70.C b/gcc/testsuite/g++.dg/template/crash70.C new file mode 100644 index 000000000..742f77b22 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash70.C @@ -0,0 +1,7 @@ +// PR c++/32113 + +template<int> struct A; + +template<typename T> void foo (A<&T::template i>); // { dg-error "not a template" } + +template void foo<A<0> > (A<0>); // { dg-error "does not match" } diff --git a/gcc/testsuite/g++.dg/template/crash71.C b/gcc/testsuite/g++.dg/template/crash71.C new file mode 100644 index 000000000..86aa1521d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash71.C @@ -0,0 +1,3 @@ +// PR c++/30659 + +extern "C" template A<char> foo(); // { dg-error "forbids|static data|expected" } diff --git a/gcc/testsuite/g++.dg/template/crash72.C b/gcc/testsuite/g++.dg/template/crash72.C new file mode 100644 index 000000000..5ab536561 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash72.C @@ -0,0 +1,25 @@ +// PR c++/29225 +// { dg-do compile } + +template <typename L, typename R> bool operator< (L x, R y); +struct T { int t (); }; +class S {}; + +struct U +{ + typedef int (T::* M) (); + M m; + + bool operator() (S &x) + { + T a; + return (a.*m) < x; // { dg-error "invalid use of non-static member" } + } +}; + +void foo (S &x) +{ + U m; + m.m = &T::t; + m (x); +} diff --git a/gcc/testsuite/g++.dg/template/crash73.C b/gcc/testsuite/g++.dg/template/crash73.C new file mode 100644 index 000000000..5c3c87dad --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash73.C @@ -0,0 +1,9 @@ +// PR c++/34100 +// { dg-do compile } + +template<typename T> struct A +{ + typedef typename T::X Y __attribute__((vector_size(8))); // { dg-error "is not a class, struct" } +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/crash74.C b/gcc/testsuite/g++.dg/template/crash74.C new file mode 100644 index 000000000..9f2e415cf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash74.C @@ -0,0 +1,6 @@ +// PR c++/34089 +// { dg-do compile } +// { dg-options "" } + +template<typename F> void foo () { } +template<typename F> struct foo<F> { }; // { dg-error "redeclared as" } diff --git a/gcc/testsuite/g++.dg/template/crash75.C b/gcc/testsuite/g++.dg/template/crash75.C new file mode 100644 index 000000000..462be95b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash75.C @@ -0,0 +1,8 @@ +// PR c++/34776 + +template<typename T> struct A +{ + T::X<0> x; // { dg-error "non-template|T::template|base type" } +}; + +A<int*> a; diff --git a/gcc/testsuite/g++.dg/template/crash76.C b/gcc/testsuite/g++.dg/template/crash76.C new file mode 100644 index 000000000..851cdd8c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash76.C @@ -0,0 +1,13 @@ +// PR c++/34486 + +template<typename> struct A +{ + typedef A* X; +}; + +template<typename T> struct B +{ + using A<T>::X::Y; // { dg-error "not a base type" } +}; + +B<int> b; diff --git a/gcc/testsuite/g++.dg/template/crash77.C b/gcc/testsuite/g++.dg/template/crash77.C new file mode 100644 index 000000000..b4d6e8f4a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash77.C @@ -0,0 +1,5 @@ +// PR c++/34603 + +template<typename> struct A; // { dg-error "declaration" } + +template<typename T> A<T>::A( struct A; // { dg-error "definition|expected|incomplete" } diff --git a/gcc/testsuite/g++.dg/template/crash78.C b/gcc/testsuite/g++.dg/template/crash78.C new file mode 100644 index 000000000..10c36ef8c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash78.C @@ -0,0 +1,3 @@ +// PR c++/35077 + +template<typename=int struct A __attribute((aligned(4))); // { dg-error "declaration|expected" } diff --git a/gcc/testsuite/g++.dg/template/crash79.C b/gcc/testsuite/g++.dg/template/crash79.C new file mode 100644 index 000000000..a18eac336 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash79.C @@ -0,0 +1,9 @@ +// PR c++/36404 + +struct A +{ + A(int); + template<int> enum { e }; // { dg-error "template|expected" } +}; + +A a(A::e); // { dg-error "not a member" } diff --git a/gcc/testsuite/g++.dg/template/crash8.C b/gcc/testsuite/g++.dg/template/crash8.C new file mode 100644 index 000000000..a6f26b306 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash8.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: David Robinson <drtr@dial.pipex.com> + +// PR c++/11513: ICE due to incorrect decision whether the tag is template. + +template <typename T> +struct bar +{ + struct foo + { + int a; + }; + + template <typename U> + int wom(U c) + { + struct foo b; + } +}; diff --git a/gcc/testsuite/g++.dg/template/crash80.C b/gcc/testsuite/g++.dg/template/crash80.C new file mode 100644 index 000000000..a12bd8bdd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash80.C @@ -0,0 +1,9 @@ +// PR c++/37087 + +namespace a { + template <typename T> class Foo; +} + +namespace b { + template <> class ::a::Foo<double> {}; // { dg-error "global qualification of class name is invalid" } +} diff --git a/gcc/testsuite/g++.dg/template/crash81.C b/gcc/testsuite/g++.dg/template/crash81.C new file mode 100644 index 000000000..849470a5e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash81.C @@ -0,0 +1,8 @@ +// PR c++/34485 + +struct A +{ + template<T::X> struct X; // { dg-error "'T' has not been declared" "T" } + // { dg-error "declaration of 'template<int X> struct A::X'" "A::X" { target *-*-* } 5 } + // { dg-error "shadows template parm 'int X'" "shadow" { target *-*-* } 5 } +}; diff --git a/gcc/testsuite/g++.dg/template/crash82.C b/gcc/testsuite/g++.dg/template/crash82.C new file mode 100644 index 000000000..41456918f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash82.C @@ -0,0 +1,6 @@ +// PR c++/37649 + +struct A +{ + template<int> struct {}; // { dg-error "template class without a name" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash83.C b/gcc/testsuite/g++.dg/template/crash83.C new file mode 100644 index 000000000..b83dd2139 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash83.C @@ -0,0 +1,5 @@ +// PR c++/37650 + +template<int> struct A {}; + +template<typename = class A<0>: > struct B {}; // { dg-error "explicit specialization|expected" } diff --git a/gcc/testsuite/g++.dg/template/crash84.C b/gcc/testsuite/g++.dg/template/crash84.C new file mode 100644 index 000000000..f622aaa5e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash84.C @@ -0,0 +1,19 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/35405 +// { dg-do compile } + +template<typename T> struct a +{ + template <template <typename> class C, typename X, C<X>* =0> + struct b // { dg-error "class C' is not a template|is not a valid type" } + { + }; +}; + +void +foo () +{ + a<int> v; // { dg-message "instantiated from here" } +} + + diff --git a/gcc/testsuite/g++.dg/template/crash85.C b/gcc/testsuite/g++.dg/template/crash85.C new file mode 100644 index 000000000..e0b6ee198 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash85.C @@ -0,0 +1,15 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/37142 +// { dg-do compile } + +template<typename T, const T a, template <typename U, U u> class W> struct A {}; + +template<typename T, const T t> struct B {}; + +int +main () +{ + A<long, 0, B> a; + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/crash87.C b/gcc/testsuite/g++.dg/template/crash87.C new file mode 100644 index 000000000..7b8bf4ada --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash87.C @@ -0,0 +1,27 @@ +// Origin: PR c++/38357 +// { dg-do compile } + +class BUG +{ +public: + bool name() { return true; } +}; + +template <bool T> +struct BUG1_5 +{ + +}; + +template <bool name> +class BUG2 : BUG +{ +public: + typedef BUG1_5<name> ptr; // { dg-error "could not convert template argument" } +}; + +int main() +{ + BUG2<false> b; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/crash88.C b/gcc/testsuite/g++.dg/template/crash88.C new file mode 100644 index 000000000..438ab90cc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash88.C @@ -0,0 +1,6 @@ +// PR c++/34397 + +template<typename T, int = T()[0]> struct A +{ + typedef A<T> B; +}; diff --git a/gcc/testsuite/g++.dg/template/crash89.C b/gcc/testsuite/g++.dg/template/crash89.C new file mode 100644 index 000000000..e62b57a39 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash89.C @@ -0,0 +1,8 @@ +// PR c++/34397 + +template<typename T, int = T()[0]> struct A +{ + typedef A<T> B; +}; + +A<int> a; // { dg-error "subscripted|template|declaration" } diff --git a/gcc/testsuite/g++.dg/template/crash9.C b/gcc/testsuite/g++.dg/template/crash9.C new file mode 100644 index 000000000..7a568fe05 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash9.C @@ -0,0 +1,12 @@ +struct A { }; +struct B { }; + +A f(const B & b) { + return A(); +} + +template<> +B f(const A & a) { // { dg-error "" } + return B(); +} + diff --git a/gcc/testsuite/g++.dg/template/crash90.C b/gcc/testsuite/g++.dg/template/crash90.C new file mode 100644 index 000000000..6fe247cc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash90.C @@ -0,0 +1,8 @@ +// PR c++/39750 + +template < unsigned > +struct A ; +template < typename > +struct B ; +template < typename T , A < B < T > // { dg-error "initializer|parse error|valid type|expected" } +{ } diff --git a/gcc/testsuite/g++.dg/template/crash91.C b/gcc/testsuite/g++.dg/template/crash91.C new file mode 100644 index 000000000..39575cd9f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash91.C @@ -0,0 +1,8 @@ +// PR c++/28293 + +template<int> void foo(); + +struct A +{ + typedef void foo<0>(); // { dg-error "explicit template argument list not allowed" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash92.C b/gcc/testsuite/g++.dg/template/crash92.C new file mode 100644 index 000000000..c0219c4a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash92.C @@ -0,0 +1,7 @@ +// PR c++/42055 + +template<typename T> void foo(T, T); // { dg-error "candidates|template" } + +template<typename T> void foo(T, int); // { dg-error "template" } + +template void foo(int, int); // { dg-error "ambiguous template specialization" } diff --git a/gcc/testsuite/g++.dg/template/crash93.C b/gcc/testsuite/g++.dg/template/crash93.C new file mode 100644 index 000000000..696a04a07 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash93.C @@ -0,0 +1,12 @@ +// PR c++/40371 + +struct A +{ + typedef void (&F)(); + template<int> operator F(); +}; + +void foo() +{ + A()(); // { dg-error "no match" } +} diff --git a/gcc/testsuite/g++.dg/template/crash94.C b/gcc/testsuite/g++.dg/template/crash94.C new file mode 100644 index 000000000..810aed0a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash94.C @@ -0,0 +1,28 @@ +// Origin: PR c++/42697 +// { dg-do compile } + +template<class Value_t> +class fparser +{ + template<bool Option> + void eval2(Value_t r[2]); +public: + void evaltest(); +}; + +template<> +template<bool Option> +void fparser<int>::eval2(int r[2]) +{ + struct ObjType {}; +} + + +template<class Value_t> +void fparser<Value_t>::evaltest + () +{ + eval2<false>(0); +} + +template class fparser<int>; diff --git a/gcc/testsuite/g++.dg/template/crash95.C b/gcc/testsuite/g++.dg/template/crash95.C new file mode 100644 index 000000000..2ad9e9816 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash95.C @@ -0,0 +1,11 @@ +// PR c++/43705 + +template < typename > struct S +{ + template < > struct S < int > // { dg-error "explicit|specialization|template|parameter" } + { + S(int); + }; +}; + +S < int > s(0); // { dg-error "incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/crash96.C b/gcc/testsuite/g++.dg/template/crash96.C new file mode 100644 index 000000000..5c2aa9954 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash96.C @@ -0,0 +1,6 @@ +// PR c++/40406 + +template<int> struct A +{ + template<int> template<int> void A::foo() {} // { dg-error "extra qualification" } +}; diff --git a/gcc/testsuite/g++.dg/template/crash97.C b/gcc/testsuite/g++.dg/template/crash97.C new file mode 100644 index 000000000..3d177f4e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash97.C @@ -0,0 +1,14 @@ +// PR c++/34272 + +template<typename> struct A {}; + +template<typename> struct A<int> // { dg-error "not used|template\\-parameter" } +{ + template<int> void foo(); +}; + +void bar() +{ + A<int> a; // { dg-error "incomplete type" } + a.foo<0>(); // { dg-error "expected" } +} diff --git a/gcc/testsuite/g++.dg/template/crash98.C b/gcc/testsuite/g++.dg/template/crash98.C new file mode 100644 index 000000000..e3c224df1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash98.C @@ -0,0 +1,14 @@ +// PR c++/43630 + +template < typename > struct A; // { dg-error "declaration" } + +template < typename > struct A < int > // { dg-error "not used|template\\-parameter" } +{ + int i; + int f (); +}; + +int A < int >::f () // { dg-error "incomplete type" } +{ + return i; +} diff --git a/gcc/testsuite/g++.dg/template/crash99.C b/gcc/testsuite/g++.dg/template/crash99.C new file mode 100644 index 000000000..606d3e304 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash99.C @@ -0,0 +1,10 @@ +// PR c++/34491 + +template<typename> struct A; + +template<0> struct A<int> // { dg-error "expected|template|anonymous" } +{ + static const int i = 0; +}; + +int n = A<int>::i; // { dg-error "incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/ctor1.C b/gcc/testsuite/g++.dg/template/ctor1.C new file mode 100644 index 000000000..81caa1fb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor1.C @@ -0,0 +1,31 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com> + +// PR 5132. ICE on struct constructors in templates. + +// snippets from bits/huge_val.h + +#define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#define __huge_val_t union { unsigned char __c[8]; double __d; } +#define HUGE_VAL (__extension__ \ + ((__huge_val_t) { __c: __HUGE_VAL_bytes }).__d) + +void foo( const int&) { + HUGE_VAL; // no problem here +} + +template <class F> +void Tfoo( const F&) { + HUGE_VAL; // g++ fails here +} + +template <typename T> struct M { T m; }; + +void Foo () +{ + Tfoo (1.2f); + (__extension__ ((M<int>) {m:3})); + (__extension__ ((M<short> []) {{m:3}})); +} diff --git a/gcc/testsuite/g++.dg/template/ctor2.C b/gcc/testsuite/g++.dg/template/ctor2.C new file mode 100644 index 000000000..1c8d8a65d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor2.C @@ -0,0 +1,18 @@ +// { dg-do run } + +int i; + +template <class T> +struct S +{ + S () { i = 1; } +}; + +static S<int> s[1]; + +int main () +{ + if (!i) + return 1; +} + diff --git a/gcc/testsuite/g++.dg/template/ctor3.C b/gcc/testsuite/g++.dg/template/ctor3.C new file mode 100644 index 000000000..d3eb2c3f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor3.C @@ -0,0 +1,19 @@ +struct A {}; +struct B; + +template <class TP> struct X: virtual A { + template <class TP2> X(TP2* ptr) {} + template <class TP2> X(const X<TP2>) {} +}; + +struct Y : X<B> { + Y(A* a) : X<B>(a) {} +}; + +void func1(X<B>); + +void func2() { + A a; + Y y(&a); + func1(X<A>(&a)); +} diff --git a/gcc/testsuite/g++.dg/template/ctor4.C b/gcc/testsuite/g++.dg/template/ctor4.C new file mode 100644 index 000000000..18ed628ee --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor4.C @@ -0,0 +1,39 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 24 Jun 2004 <nathan@codesourcery.com> + +// Origin Rani Sharoni via giovannibajo@libero.it +// Bug 16174, SFINAE failure. + +template <class T> struct K +{ + K(); + + K(K<T> & rhs); + K(K<T> const& rhs); + template <class U> K(K<U> const& rhs); + +private: + template <class U> struct A; + template <class U> struct A< K<U> const> + { typedef typename K<U>::compile_time_error type; }; + + // This is used to reject calls to the copy constructor + // with objects which are top-level const. If they are + // const, the specialization of A is instantiated and + // causes a compile time error. Otherwise, the general + // template is picked up, it misses definition, so this + // ctor declaration is rejected by SFINAE and everybody + // is happy. + // GCC 3.4.1pre and 3.5.0 always matches A's specialization + // when instantiating from foo(), and this causes the error. + template <class U> + K(U& rhs, typename A<U>::type = 0); +}; + + +K<int> foo(void) +{ + return K<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/ctor5.C b/gcc/testsuite/g++.dg/template/ctor5.C new file mode 100644 index 000000000..6938b36b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor5.C @@ -0,0 +1,8 @@ +// PR c++/24278 + +template<typename T> struct A +{ + A() : T(0) {} // { dg-error "base" } +}; + +A<int*> a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/ctor6.C b/gcc/testsuite/g++.dg/template/ctor6.C new file mode 100644 index 000000000..4f21dc9eb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor6.C @@ -0,0 +1,11 @@ +// PR c++/25663 + +template<int> struct A +{ + A(int); +}; + +void foo() +{ + A<0>(A<0>(0)); +} diff --git a/gcc/testsuite/g++.dg/template/ctor7.C b/gcc/testsuite/g++.dg/template/ctor7.C new file mode 100644 index 000000000..ee65172fe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor7.C @@ -0,0 +1,19 @@ +// PR c++/27640 + +template < class T > struct refcounted : +virtual T +{ + template < class A1 > refcounted (const A1 & a1) : T () { } +}; +struct nfsserv {}; +template < class T > +void +sfsserver_cache_alloc (int *ns) +{ + new refcounted < nfsserv > (*ns); +} +void +usage () +{ + sfsserver_cache_alloc < int > ( 0); +} diff --git a/gcc/testsuite/g++.dg/template/ctor8.C b/gcc/testsuite/g++.dg/template/ctor8.C new file mode 100644 index 000000000..859bded41 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor8.C @@ -0,0 +1,11 @@ +// PR c++/28711 +// { dg-do compile } +// { dg-options "" } + +template<int> struct A +{ + int x[1][1]; + A() : x((int[1][]){{0}}) {} // { dg-error "except the first" } +}; + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/ctor9.C b/gcc/testsuite/g++.dg/template/ctor9.C new file mode 100644 index 000000000..819ca1c94 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor9.C @@ -0,0 +1,9 @@ +// PR c++/9050, DR 147, 318 + +struct Y +{ + template <typename T> Y (T); + template <typename T> void foo (T); +}; + +template <> Y::Y<int> (int) { } diff --git a/gcc/testsuite/g++.dg/template/debug1.C b/gcc/testsuite/g++.dg/template/debug1.C new file mode 100644 index 000000000..a2c157702 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/debug1.C @@ -0,0 +1,18 @@ +// PR c++/40274 +// { dg-options "-g" } + +template <class T> struct valuelist_types +{ + struct null { }; + template <T V, class next=null> struct list { }; +}; + +template <unsigned D> void foo() +{ + typename valuelist_types<unsigned>::template list<D> v; +} + +void bar() +{ + valuelist_types<unsigned>::list<2> v; +} diff --git a/gcc/testsuite/g++.dg/template/decl1.C b/gcc/testsuite/g++.dg/template/decl1.C new file mode 100644 index 000000000..50eef0866 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/decl1.C @@ -0,0 +1,16 @@ +// PR c++/3882 +// Verify that variable initialization can be +// self-referencing inside a template function. + +int foo(int); + +template <typename T> +void bar(const T&) +{ + int i = foo(i); +} + +void quus() +{ + bar(0); +} diff --git a/gcc/testsuite/g++.dg/template/decl2.C b/gcc/testsuite/g++.dg/template/decl2.C new file mode 100644 index 000000000..3a77777bd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/decl2.C @@ -0,0 +1,13 @@ +// PR c++/16162 + +template <int N> struct O { + struct I { + template <typename T> struct II { + void f(); + }; + }; +}; + +template <int N> +template <typename T> +void O<N>::I::II<T>::f () {} diff --git a/gcc/testsuite/g++.dg/template/decl3.C b/gcc/testsuite/g++.dg/template/decl3.C new file mode 100644 index 000000000..7f9385076 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/decl3.C @@ -0,0 +1,8 @@ +// c++/32560 + +namespace N {} + +template<typename> struct A +{ + int A<typename N::X>; // { dg-error "namespace|argument|before" } +}; diff --git a/gcc/testsuite/g++.dg/template/deduce1.C b/gcc/testsuite/g++.dg/template/deduce1.C new file mode 100644 index 000000000..262c4fe86 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce1.C @@ -0,0 +1,25 @@ +// { dg-do run } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 13 Sep 2002 <nathan@codesourcery.com> + +template <typename T> int Foo (T const *) +{ + return 1; +} +template <typename T> int Foo (T const &) +{ + return 2; +} +template <typename T, __SIZE_TYPE__ I> int Foo (T const (&ref)[I]) +{ + return 0; +} + +int main () +{ + static int array[4] = {}; + + return Foo (array); +} + diff --git a/gcc/testsuite/g++.dg/template/deduce2.C b/gcc/testsuite/g++.dg/template/deduce2.C new file mode 100644 index 000000000..bcf77b30b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce2.C @@ -0,0 +1,30 @@ +template <typename T0> struct tuple { + typedef tuple<int> tail; +}; + +template <> struct tuple<int> { +}; + +template <typename L> +struct length { + static const int i = length<typename tuple<L>::tail>::i; +}; + +template<> +struct length<tuple<int> > { + static const int i = 1; +}; + +template <int> struct M {}; + +template <typename A> +M<length<tuple<A> >::i > foo (A*); + +template <typename A> +M<length<tuple<A> >::i> foo (const A*); + +const int i1 = 3; + +void bar() { + foo (&i1); +} diff --git a/gcc/testsuite/g++.dg/template/deduce3.C b/gcc/testsuite/g++.dg/template/deduce3.C new file mode 100644 index 000000000..e8a1d4e2b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/deduce3.C @@ -0,0 +1,11 @@ +template <typename T> +void f(int, T (*)() = 0); // { dg-message "note" } + +void g() { + typedef int A[2]; + f<A>(0); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 6 } + typedef void F(); + f<F>(0); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 9 } +} diff --git a/gcc/testsuite/g++.dg/template/defarg1.C b/gcc/testsuite/g++.dg/template/defarg1.C new file mode 100644 index 000000000..1b0e4a24a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg1.C @@ -0,0 +1,7 @@ +struct Outer { + template <int I, int J=I> struct Inner {}; +}; + +void f() { + Outer::Inner<2> i; +} diff --git a/gcc/testsuite/g++.dg/template/defarg10.C b/gcc/testsuite/g++.dg/template/defarg10.C new file mode 100644 index 000000000..281b10868 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg10.C @@ -0,0 +1,13 @@ +// PR c++/28363 +// { dg-do compile } + +template<typename T, template<int> class = T> // { dg-error "invalid use of type" } +struct A; + +typedef int I; +template<template<int> class = I> // { dg-error "invalid use of type" } +struct B; + +struct S; +template<template<int> class = S> // { dg-error "invalid use of type" } +struct C; diff --git a/gcc/testsuite/g++.dg/template/defarg11.C b/gcc/testsuite/g++.dg/template/defarg11.C new file mode 100644 index 000000000..00c4e658d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg11.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// We used to reject this code as the extension +// for default arguments being accepted as less the +// needed template arguments. + + +template<typename> struct match { }; + +template<template<typename> class t,typename T> +struct match<t<T> > { typedef int type; }; + +template<template<typename,typename> class t,typename T0,typename T1> +struct match<t<T0,T1> > { typedef int type; }; + +template<typename,typename =void> struct other { }; + +typedef match<other<void,void> >::type type; diff --git a/gcc/testsuite/g++.dg/template/defarg12.C b/gcc/testsuite/g++.dg/template/defarg12.C new file mode 100644 index 000000000..d11848af2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg12.C @@ -0,0 +1,10 @@ +// PR c++/35828 +// { dg-options "-std=c++0x" } + +template < typename > struct A ; +template < template < typename > class = A > +void test () +{ + test (); +} + diff --git a/gcc/testsuite/g++.dg/template/defarg13.C b/gcc/testsuite/g++.dg/template/defarg13.C new file mode 100644 index 000000000..ba2980bfa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg13.C @@ -0,0 +1,19 @@ +// PR c++/14912 +// Bug: We were instantiating A<B> in order to compare it to the matching +// argument for C<B,B>, which fails. + +template <class T> +struct A +{ + typedef typename T::F F; +}; + +struct B { }; + +template <class T, class U = typename A<T>::F > +struct C +{ + typename T::F f; // { dg-error "no type" } +}; + +C<B, B> c; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/defarg14.C b/gcc/testsuite/g++.dg/template/defarg14.C new file mode 100644 index 000000000..1fe87e39d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg14.C @@ -0,0 +1,13 @@ +// PR c++/46129 +// The default argument for A<int>::B::operator() should not be instantiated + +template <class T> +struct A { + struct B { + void operator () (const T& d_ = f(T()) ) { } + }; +}; + +int main() { + A<int>::B b; +} diff --git a/gcc/testsuite/g++.dg/template/defarg2.C b/gcc/testsuite/g++.dg/template/defarg2.C new file mode 100644 index 000000000..3670389c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg2.C @@ -0,0 +1,10 @@ +struct X { + X (); +}; + +template <int> struct O { + struct I { + I (const X & = X()); + }; +}; +template struct O<2>; diff --git a/gcc/testsuite/g++.dg/template/defarg3.C b/gcc/testsuite/g++.dg/template/defarg3.C new file mode 100644 index 000000000..da91cb7b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg3.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com> + +// PR c++ 11596 + +template <int V, bool F = V < 1> struct A { enum { value }; }; +template <int V> struct B { enum { value = A<1>::value }; }; +int ary[!B<1>::value ? 1 : -1]; + +template <int V, bool F = V < 1> struct A1 { enum { value = 1}; }; +template <int V> struct A1<V,false> { enum { value}; }; +template <int V> struct B1 { enum { value = A1<1>::value }; }; + +int ary1[!B1<1>::value ? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/template/defarg4.C b/gcc/testsuite/g++.dg/template/defarg4.C new file mode 100644 index 000000000..293538adb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg4.C @@ -0,0 +1,14 @@ +// PR c++/14763 + +struct A { + int get() const {} + static A *foo(); +}; + +template<bool> struct S { + S(unsigned int = A::foo()->get()) ; +}; + +void foo() throw() { + S<false> f; +} diff --git a/gcc/testsuite/g++.dg/template/defarg5.C b/gcc/testsuite/g++.dg/template/defarg5.C new file mode 100644 index 000000000..b43637416 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg5.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> +// Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/17344: Substitution failure is not an error +// for default template argument + +template <class> struct intTraits; + +template<> struct intTraits<int> { + static const int i = 0; +}; + +template<typename E, E i = intTraits<E>::i> struct A {}; + +struct S { + template <template <typename> class X> S(X<void>); +}; + +int bar(S); +int bar(A<int,0>); + +A<int> bed; +int i = bar(bed); diff --git a/gcc/testsuite/g++.dg/template/defarg6.C b/gcc/testsuite/g++.dg/template/defarg6.C new file mode 100644 index 000000000..f4d84685a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg6.C @@ -0,0 +1,25 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Oct 2005 <nathan@codesourcery.com> + +// PR 21353 missing error. +// Origin:Andrew Pinski <pinskia@gcc.gnu.org> + +enum X{ a, b, c }; + +struct C +{ + static void func (X &ref = a); // { dg-error "default argument" "" } +}; + +template <typename T> +struct D +{ + static void func (X &ref = a); // not an error at this point +}; + +void Foo (X & obj) +{ + D<int>::func (obj); + + D<int>::func (); // { dg-error "default argument" "" } +} diff --git a/gcc/testsuite/g++.dg/template/defarg7.C b/gcc/testsuite/g++.dg/template/defarg7.C new file mode 100644 index 000000000..77506d402 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg7.C @@ -0,0 +1,7 @@ +// PR c++/25337 + +template <typename T> T& MakeT(); +template <typename U, int N = sizeof (MakeT<U>().operator[](0))> +struct helper{}; +template <typename U> +static char is_here(helper<U>*); diff --git a/gcc/testsuite/g++.dg/template/defarg8.C b/gcc/testsuite/g++.dg/template/defarg8.C new file mode 100644 index 000000000..61d819c7c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg8.C @@ -0,0 +1,19 @@ +// PR c++/27094 +// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +struct A +{ + ~A(); +}; + +struct B : A +{ + B(); +}; + +template<int> struct C +{ + C(const B& = B()); +}; + +C<0> c; diff --git a/gcc/testsuite/g++.dg/template/defarg9.C b/gcc/testsuite/g++.dg/template/defarg9.C new file mode 100644 index 000000000..de7528f61 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg9.C @@ -0,0 +1,16 @@ +// PR c++/28048 + +template<typename T> struct Boom; + +template<typename T, bool D = Boom<T>::Internal::Value> // <--ICE + struct Foo + { + }; + +template<typename T> struct Boom +{ + struct Internal + { + static const bool Value = false; + }; +}; diff --git a/gcc/testsuite/g++.dg/template/delete1.C b/gcc/testsuite/g++.dg/template/delete1.C new file mode 100644 index 000000000..fc5327074 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/delete1.C @@ -0,0 +1,14 @@ +// PR c++/15890 + +template < typename T > +void operator delete ( void* raw ) { // { dg-error "" } + delete raw; +} + +class A { }; + +int main() { + A* a = new A; + delete a; +} + diff --git a/gcc/testsuite/g++.dg/template/dependent-args1.C b/gcc/testsuite/g++.dg/template/dependent-args1.C new file mode 100644 index 000000000..0b197cf55 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-args1.C @@ -0,0 +1,11 @@ +// PR c++/27582 +// { dg-do compile } + +struct A +{ + template<int> void foo(); +}; + +template<int N, void (A::*)() = &A::foo<N> > struct B {}; + +B<int> b; // { dg-error "type/value mismatch|expected a constant|invalid type" } diff --git a/gcc/testsuite/g++.dg/template/dependent-expr1.C b/gcc/testsuite/g++.dg/template/dependent-expr1.C new file mode 100644 index 000000000..79649861b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr1.C @@ -0,0 +1,29 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 30 Jun 2003 <nathan@codesourcery.com> + +// PR c++ 9779. ICE + +struct I +{ +}; + +void Foo (int); +namespace std +{ + template <typename X> + void Baz (I *x) + { + Foo (sizeof (I)); + Foo (sizeof (x)); + Foo (__alignof__ (I)); + Foo (__alignof__ (x)); + Foo (x->~I ()); // { dg-error "" } + // Foo (typeid (I)); + Foo (delete x); // { dg-error "" } + Foo (delete[] x); // { dg-error "" } + Foo (throw x); // { dg-error "" } + } + +} diff --git a/gcc/testsuite/g++.dg/template/dependent-expr2.C b/gcc/testsuite/g++.dg/template/dependent-expr2.C new file mode 100644 index 000000000..06f056b41 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr2.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Aug 2003 <nathan@codesourcery.com> + +// PR 11704. ICE + +struct A +{ + int foo() + { + return 5; + } +}; + +template <class T> // If B is not template it works +struct B +{ + bool bar(A& a) + { + return a.foo == 0; // { dg-error "" "" } + } +}; diff --git a/gcc/testsuite/g++.dg/template/dependent-expr3.C b/gcc/testsuite/g++.dg/template/dependent-expr3.C new file mode 100644 index 000000000..97fddbdd8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr3.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// Origin: jbrandmeyer at users dot sourceforge dot net +// PR c++/12573: COMPONENT_REFs must be inspected for dependness. + +template <bool> struct S; + +template <typename K> struct Y : K { + int x; +}; + +template <class T> struct Z { + S< (bool)(&static_cast<Y<T> *>(0)->x == 0) > // { dg-error "" } + s; +}; diff --git a/gcc/testsuite/g++.dg/template/dependent-expr4.C b/gcc/testsuite/g++.dg/template/dependent-expr4.C new file mode 100644 index 000000000..b36c8729b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr4.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// Origin: jbrandmeyer at users dot sourceforge dot net +// PR c++/12573: COMPONENT_REFs must be inspected for dependness. +// Or, more specifically OFFSETOF. + +template <bool> struct S; + +template <typename K> struct Y { + int x; +}; + +template <class T> struct Z { + S< (bool)(__builtin_offsetof (Y<T>*, x) == 0) > + s; +}; diff --git a/gcc/testsuite/g++.dg/template/dependent-expr5.C b/gcc/testsuite/g++.dg/template/dependent-expr5.C new file mode 100644 index 000000000..1e850cd54 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr5.C @@ -0,0 +1,130 @@ +// { dg-do compile } + +// Copyright 2005 Free Software Foundation +// contributed by Alexandre Oliva <aoliva@redhat.com> +// inspired in the failure reported in Red Hat bugzilla #168260. + +template<class F> void bind(F f) {} // { dg-message "note" } + +template<class F> void bindm(F f) {} // { dg-message "note" } +template<class F, class T> void bindm(F (T::*f)(void)) {} // { dg-message "note" } + +template<class F> void bindn(F f) {} +template<class F, class T> void bindn(F (*f)(T)) {} + +template<class F> void bindb(F f) {} +template<class F, class T> void bindb(F (*f)(T)) {} // { dg-message "note" } +template<class F, class T> void bindb(F (T::*f)(void)) {} // { dg-message "note" } + +struct foo { + static int baist; + int bait; // { dg-error "non-static data member" } + void barf (); + static void barf (int); + + struct bar { + static int baikst; + int baikt; + void bark (); + static void bark (int); + + bar() { + bind (&baist); + bind (&foo::baist); + bind (&bait); // { dg-error "from this location" } + bind (&foo::bait); + + bind (&baikst); + bind (&bar::baikst); + bind (&baikt); // ok, this->baikt + bind (&bar::baikt); + + bind (&barf); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 42 } + bind (&foo::barf); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 44 } + + bindm (&barf); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 47 } + bindm (&foo::barf); + + bindn (&barf); + bindn (&foo::barf); + + bindb (&barf); + bindb (&foo::barf); // { dg-error "ambiguous" } + // { dg-message "candidate" "candidate note" { target *-*-* } 55 } + + bind (&bark); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 58 } + bind (&bar::bark); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 60 } + + bindm (&bark); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 63 } + bindm (&bar::bark); + + bindn (&bark); + bindn (&bar::bark); + + bindb (&bark); + bindb (&bar::bark); // { dg-error "ambiguous" } + // { dg-message "candidate" "candidate note" { target *-*-* } 71 } + } + }; + + template <typename T> + struct barT { + static int baikst; + int baikt; + void bark (); + static void bark (int); + + barT() { + bind (&baist); + bind (&foo::baist); + bind (&bait); // { dg-error "from this location" } + bind (&foo::bait); + + bind (&baikst); + bind (&barT::baikst); + bind (&baikt); // ok, this->baikt + bind (&barT::baikt); + + bind (&barf); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 94 } + bind (&foo::barf); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 96 } + + bindm (&barf); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 99 } + bindm (&foo::barf); + + bindn (&barf); + bindn (&foo::barf); + + bindb (&barf); + bindb (&foo::barf); // { dg-error "ambiguous" } + // { dg-message "candidate" "candidate note" { target *-*-* } 107 } + + bind (&bark); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 110 } + bind (&barT::bark); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 112 } + + bindm (&bark); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 115 } + bindm (&barT::bark); + + bindn (&bark); + bindn (&barT::bark); + + bindb (&bark); + bindb (&barT::bark); // { dg-error "ambiguous" } + // { dg-message "candidate" "candidate note" { target *-*-* } 123 } + } + }; + + bar bard; + barT<void> bart; +} bad; diff --git a/gcc/testsuite/g++.dg/template/dependent-expr6.C b/gcc/testsuite/g++.dg/template/dependent-expr6.C new file mode 100644 index 000000000..423f1aeec --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr6.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Copyright 2007 Free Software Foundation +// Contributed by Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + +// PR C++ 34081 ICE + +class Foo; + +template < class Foo > class Bar +{ + enum Status + { OK, NO }; + + enum Status getStatus () + { + return status; + } + + Status status; +}; diff --git a/gcc/testsuite/g++.dg/template/dependent-expr7.C b/gcc/testsuite/g++.dg/template/dependent-expr7.C new file mode 100644 index 000000000..b24682035 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr7.C @@ -0,0 +1,22 @@ +// Origin PR c++/48574 +// { dg-do compile } + +struct A +{ + virtual void foo(); +}; + +template <typename T> +void +bar(T x) +{ + A &b = *x; + b.foo (); +} + +void +foo() +{ + A a; + bar(&a); +} diff --git a/gcc/testsuite/g++.dg/template/dependent-expr8.C b/gcc/testsuite/g++.dg/template/dependent-expr8.C new file mode 100644 index 000000000..20014d6e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-expr8.C @@ -0,0 +1,25 @@ +// Origin PR c++/48574 +// { dg-options "-std=c++0x" } +// { dg-do compile } + +struct A +{ + virtual int foo(); +}; + +void baz (int); + +template <typename T> +void +bar(T x) +{ + A &b = *x; + baz (b.foo ()); +} + +void +foo() +{ + A a; + bar(&a); +} diff --git a/gcc/testsuite/g++.dg/template/dependent-name1.C b/gcc/testsuite/g++.dg/template/dependent-name1.C new file mode 100644 index 000000000..60ab34498 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name1.C @@ -0,0 +1,11 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/10347: Dependent type checking of array new expression + +void bar (int *); + +template <int> void foo() { + bar(new int[1]); +} diff --git a/gcc/testsuite/g++.dg/template/dependent-name2.C b/gcc/testsuite/g++.dg/template/dependent-name2.C new file mode 100644 index 000000000..9e0cbcee1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name2.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Aug 2003 <nathan@codesourcery.com> + +// PR 10530. Thought a type was dependent. + +template <typename T> +struct Foo { + struct Inner { + typedef int type; + }; +}; + +template <typename A> struct Bar { + typedef typename Foo<int>::Inner::type type; +}; + diff --git a/gcc/testsuite/g++.dg/template/dependent-name3.C b/gcc/testsuite/g++.dg/template/dependent-name3.C new file mode 100644 index 000000000..bbe6fb662 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name3.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// Dependent arrays of invalid size generate appropriate error messages + +template<int I> struct A +{ + static const int zero = 0; + static const int minus_one = -1; +}; + +template<int N> struct B +{ + int x[A<N>::zero]; // { dg-error "zero" } + int y[A<N>::minus_one]; // { dg-error "negative" } +}; + +B<0> b; diff --git a/gcc/testsuite/g++.dg/template/dependent-name4.C b/gcc/testsuite/g++.dg/template/dependent-name4.C new file mode 100644 index 000000000..b2b5814be --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name4.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Dependent arrays of invalid size cause template instantiation failure. + +// We'll get an error message (duplicate matching templates) if the first +// pattern is incorrectly allowed to match. + +template<int M> void foobar (int (*) [M] = 0 ); +template<int M> void foobar ( ); + +void fn (void) +{ + foobar<0>(); + foobar<-1>(); +} diff --git a/gcc/testsuite/g++.dg/template/dependent-name5.C b/gcc/testsuite/g++.dg/template/dependent-name5.C new file mode 100644 index 000000000..681060c70 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name5.C @@ -0,0 +1,45 @@ +// PR c++/9634, c++/29469, c++/29607 +// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +// DR224: Make sure that a name is *truly* semantically dependent. + +struct D { + typedef int K; +}; + +template <typename T> +struct A +{ + typedef int Bar; + + template <typename> + struct N {}; + + typedef Bar type1; + typedef A::Bar type2; + typedef A<T>::Bar type3; + typedef A<T*>::Bar type4; // { dg-error "" } + typedef typename A<T*>::Bar type5; + + typedef N<int> type6; + typedef A::N<int> type7; + typedef A<T>::N<int> type8; + typedef A<T*>::template N<int> type9; // { dg-error "" } + typedef typename A<T*>::template N<int> type10; + + typedef D Bar2; + struct N2 { typedef int K; }; + + // Check that A::N2 is still considered dependent (because it + // could be specialized), while A::Bar2 (being just ::D) is not. + typedef A::Bar2 type11; + typedef type11::K k3; + + typedef A::N2 type12; + typedef typename type12::K k2; + typedef type12::K k1; // { dg-error "" } + + // Check that A::Bar2 is not considered dependent even if we use + // the typename keyword. + typedef typename A::Bar2 type13; + typedef type13::K k4; +}; diff --git a/gcc/testsuite/g++.dg/template/dependent-name6.C b/gcc/testsuite/g++.dg/template/dependent-name6.C new file mode 100644 index 000000000..e08bbe1aa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name6.C @@ -0,0 +1,17 @@ +// PR c++/26261 +// { dg-final { scan-assembler "_ZN1YIiE1fIiEE1XILi1EEv" } } + +template <int dim> class X {}; + +template <class T> struct Y { + static const unsigned int dim = 1; + template <class U> X<Y<T>::dim> f(); +}; + +template <class T> template <class U> +X<Y<T>::dim> Y<T>::f() { return X<dim>(); } + +int main() +{ + Y<int>().f<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/dr408.C b/gcc/testsuite/g++.dg/template/dr408.C new file mode 100644 index 000000000..d118ce45c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dr408.C @@ -0,0 +1,45 @@ +// DR 408 +// { dg-do link } + +// Test that a size given in the out-of-class definition isn't used until +// instantiation time. +template<typename T> +struct X +{ + static char s[]; + int c; +}; + +template<typename T> +char X<T>::s[sizeof(X<T>)]; + +#define sassert(EXP) int ar[(EXP)?1:-1] +sassert(sizeof (X<char>::s) == sizeof (int)); + +// Test that a specialization can have a different size. + +template <int> void g(); +template <> void g<2>() { } + +template <typename T> +struct S { + static int i[]; + void f(); +}; + +template <typename T> +int S<T>::i[] = { 1 }; + +template <typename T> +void S<T>::f() { + g<sizeof (i) / sizeof (int)>(); +} + +template <> +int S<int>::i[] = { 1, 2 }; + +int main() +{ + S<int> s; + s.f(); +} diff --git a/gcc/testsuite/g++.dg/template/dtor1.C b/gcc/testsuite/g++.dg/template/dtor1.C new file mode 100644 index 000000000..f5d9d6aad --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor1.C @@ -0,0 +1,8 @@ +struct A {}; + +template <typename T> struct B +{ + B() { A().A::~A(); } +}; + +B<void> b; diff --git a/gcc/testsuite/g++.dg/template/dtor2.C b/gcc/testsuite/g++.dg/template/dtor2.C new file mode 100644 index 000000000..04bea9cb6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor2.C @@ -0,0 +1,10 @@ +struct Foo +{ + template <int i> + ~Foo() {} // { dg-error "" } +}; + +int main() +{ + Foo f; +} diff --git a/gcc/testsuite/g++.dg/template/dtor3.C b/gcc/testsuite/g++.dg/template/dtor3.C new file mode 100644 index 000000000..98c2ef6c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor3.C @@ -0,0 +1,4 @@ +// PR c++/19762 + +template<int> struct A { ~A(){} }; // { dg-error "" } +template A<>::~A(); // { dg-error "template|declaration" } diff --git a/gcc/testsuite/g++.dg/template/dtor4.C b/gcc/testsuite/g++.dg/template/dtor4.C new file mode 100644 index 000000000..4f277b248 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor4.C @@ -0,0 +1,9 @@ +// PR c++/19440 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> + +// { dg-do compile } + +template<int> struct A +{ + ~A<0>(); // { dg-error "parse error|declaration" } +}; diff --git a/gcc/testsuite/g++.dg/template/dtor5.C b/gcc/testsuite/g++.dg/template/dtor5.C new file mode 100644 index 000000000..8fa4eeb6f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor5.C @@ -0,0 +1,21 @@ +// PR c++/23287 + +template <class T> struct A +{ + int i; + ~A(); +}; + +template <class T> void f(A<T> *ap) { + ap->~A(); +} + +template <class T> void g(A<T> *ap) { + ap->~B(); // { dg-error "destructor name" } +} + +int main() +{ + f(new A<int>); + g(new A<int>); +} diff --git a/gcc/testsuite/g++.dg/template/dtor6.C b/gcc/testsuite/g++.dg/template/dtor6.C new file mode 100644 index 000000000..c44b78029 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor6.C @@ -0,0 +1,16 @@ +// PR c++/40139 + +template<int> struct A +{ + static int i; +}; + +template<int N> int A<N>::i = { A::~A }; // { dg-error "non-static member function" } + +template class A<0>; + +struct X { }; + +int i1 = X::~X; // { dg-error "non-static member function" } +int i2 = &X::~X; // { dg-error "address of destructor" } +int i3 = &A<0>::~A; // { dg-error "address of destructor" } diff --git a/gcc/testsuite/g++.dg/template/dtor7.C b/gcc/testsuite/g++.dg/template/dtor7.C new file mode 100644 index 000000000..186b561e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor7.C @@ -0,0 +1,22 @@ +// PR c++/40373 +// { dg-do compile } + +struct A; +namespace +{ + struct A; +} + +struct B {}; + +template <typename T> void +foo (T t) +{ + t.~A (); // { dg-error "does not match destructor name" } +} + +void +bar () +{ + foo (B ()); // { dg-bogus "instantiated from here" "" { xfail *-*-* } } +} diff --git a/gcc/testsuite/g++.dg/template/dtor8.C b/gcc/testsuite/g++.dg/template/dtor8.C new file mode 100644 index 000000000..a96b7982f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor8.C @@ -0,0 +1,23 @@ +// PR c++/43648 + +namespace dealii +{ + namespace FEValuesViews + { + template <int dim, int spacedim> struct Scalar {}; + } + + template <int dim, int spacedim> + struct X + { + FEValuesViews::Scalar<dim,spacedim> scalars[dim*spacedim]; + + void f() + { + typedef dealii::FEValuesViews::Scalar<dim,spacedim> ScalarView; + scalars[0].ScalarView::~ScalarView (); + } + }; + + template struct X<2,2>; +} diff --git a/gcc/testsuite/g++.dg/template/duplicate1.C b/gcc/testsuite/g++.dg/template/duplicate1.C new file mode 100644 index 000000000..c9cdab4b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/duplicate1.C @@ -0,0 +1,7 @@ +//PR c++/19439 + +template<int> struct A +{ + ~A() {} // { dg-error "with" } + ~A() {} // { dg-error "cannot be overloaded" } +}; diff --git a/gcc/testsuite/g++.dg/template/eh1.C b/gcc/testsuite/g++.dg/template/eh1.C new file mode 100644 index 000000000..134a0e7a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/eh1.C @@ -0,0 +1,6 @@ +template <class T> +void foo() +{ + try {} + catch(T e) {} +} diff --git a/gcc/testsuite/g++.dg/template/eh2.C b/gcc/testsuite/g++.dg/template/eh2.C new file mode 100644 index 000000000..d2c049c8a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/eh2.C @@ -0,0 +1,10 @@ +// PR c++/23191 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// { dg-do compile } + +template<typename T> struct A +{ + void foo() throw(typename T::X); // { dg-error "not a class" } +}; + +A<void> a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/elab1.C b/gcc/testsuite/g++.dg/template/elab1.C new file mode 100644 index 000000000..778150f06 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/elab1.C @@ -0,0 +1,13 @@ +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +// Elaborate type specifier of class template + +template <class T> class A { + class B; +}; + +template <class T> class A<T>::B { + friend class A; +}; diff --git a/gcc/testsuite/g++.dg/template/enum1.C b/gcc/testsuite/g++.dg/template/enum1.C new file mode 100644 index 000000000..eaeb12c9c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum1.C @@ -0,0 +1,5 @@ +// PR c++/15554 + +template <int n> struct T1 { enum { N = 3 }; }; +template <int n> struct T2 { enum { N = 3, N1 = T1<N>::N }; }; + diff --git a/gcc/testsuite/g++.dg/template/enum2.C b/gcc/testsuite/g++.dg/template/enum2.C new file mode 100644 index 000000000..7a6c2072a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum2.C @@ -0,0 +1,4 @@ +// PR c++/15877 + +template <int n> struct T1 { enum { N = 3 }; }; +template <int n> struct T2 { enum { N = n, N1 = T1<N>::N }; }; diff --git a/gcc/testsuite/g++.dg/template/enum3.C b/gcc/testsuite/g++.dg/template/enum3.C new file mode 100644 index 000000000..b248d788c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum3.C @@ -0,0 +1,8 @@ +// PR c++/17327 + +enum E { E0, E1 }; +template <class T,class U> class A {}; +template <class T> void f(A<E,T>) {} +// We used to issue a "sorry" message. By using an explicit error +// message below, we make sure that we will not match "sorry". +template void f(A<int,E>); // { dg-error "template-id" } diff --git a/gcc/testsuite/g++.dg/template/enum4.C b/gcc/testsuite/g++.dg/template/enum4.C new file mode 100644 index 000000000..97e0b848d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum4.C @@ -0,0 +1,9 @@ +// PR c++/18020 + +template <typename> struct bar { + enum { + e1 = 1, + e2 = ~e1 + }; +}; +template struct bar<int>; diff --git a/gcc/testsuite/g++.dg/template/enum5.C b/gcc/testsuite/g++.dg/template/enum5.C new file mode 100644 index 000000000..b7a49f45d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum5.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: robertk@mathematik.uni-freiburg.de +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/14479: Template header check for enum + +template <int dim> +struct X { + enum { dimension = dim }; + template<int d> void bar (); +}; + +template <> +template <> +void X<0>::bar<0> () {} diff --git a/gcc/testsuite/g++.dg/template/enum6.C b/gcc/testsuite/g++.dg/template/enum6.C new file mode 100644 index 000000000..9df6d4106 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/enum6.C @@ -0,0 +1,10 @@ +// PR c++/34774 + +template<int shifts> +struct shift { + enum { + n0 = (unsigned)shifts, + n = n0 ? 0 : n0, + n_comp = -n + } x; +}; diff --git a/gcc/testsuite/g++.dg/template/error-recovery1.C b/gcc/testsuite/g++.dg/template/error-recovery1.C new file mode 100644 index 000000000..ef9dc141b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error-recovery1.C @@ -0,0 +1,9 @@ +// PR c++/43076 + +struct S; +template < typename > struct T +{ + template < typename > + template < bool > struct T < S > // { dg-error "" } + { + void f () { // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error-recovery2.C b/gcc/testsuite/g++.dg/template/error-recovery2.C new file mode 100644 index 000000000..d5ce12311 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error-recovery2.C @@ -0,0 +1,7 @@ +// PR c++/43621 + +template <typename T> +class A { + template <typename> + A<T> A<T>::f(); // { dg-error "extra qualification" } +}; diff --git a/gcc/testsuite/g++.dg/template/error1.C b/gcc/testsuite/g++.dg/template/error1.C new file mode 100644 index 000000000..03a832392 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error1.C @@ -0,0 +1,13 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 30 Jun 2003 <nathan@codesourcery.com> + +// PR c++ 10219. ICE + +template <class T> void make_pair(T x); + +void foo(){ + struct fps_chan_ID fps; // { dg-error "incomplete" "" } + make_pair(fps); // { dg-bogus "no matching function" "" } +} diff --git a/gcc/testsuite/g++.dg/template/error10.C b/gcc/testsuite/g++.dg/template/error10.C new file mode 100644 index 000000000..02ea64b79 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error10.C @@ -0,0 +1,71 @@ +// { dg-do compile } +// { dg-options "-std=gnu++98" } +// Origin: <tilps at hotmail dot com> +// c++/9154: poor error message for ">>" vs "> >" in template argument list + + +/* + * Test that the error message is issued properly + */ +template <class T> +class A {}; + +A<A<int>> blah; // { dg-error "should be '> >' within" } +A<int>> blah2; // { dg-error "spurious '>>'" } + + +/* + * Test that a few valid constructs containing a ">>" token in a + * template argument list are handled correctly. + */ +template <int N> +void B(void) {} + +int Btest() +{ + B<256 >> 4>(); +} + +template <int N = 123>>4> +struct C {}; + +template <int> struct D {}; +template <typename> struct E {}; + +E<D< 1>>2 > > E1; + +const int x = 0; +E<D< 1>>x > > E2; + +template <int> struct F { + typedef int I; +}; + +template <typename T = F< 1>>2 >::I> +struct G {}; + +/* + * In this special case, a valid type-id (H() is a function type) is followed + * by '>>', but the argument should still be parsed as an expression, which + * will then be rejected as non-constant expression. + */ +struct H +{ + int operator >>(int); +}; + +template <int V> struct L {}; +L<H() >> 5> l; // { dg-error "" "non-constant" } + + +/* + * This case used to not emit the nice error message because of a typo + * in the code. + */ +template <void (*)(void)> +struct K {}; + +void KFunc(void); + +A<K<&KFunc>> k1; // { dg-error "" } +K<&KFunc>> k2; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error11.C b/gcc/testsuite/g++.dg/template/error11.C new file mode 100644 index 000000000..3a469fd1a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error11.C @@ -0,0 +1,4 @@ +// PR c++/12132 + +inline template <int> void foo () {} // { dg-error "<" } +void abort (); // { dg-error ";" } diff --git a/gcc/testsuite/g++.dg/template/error12.C b/gcc/testsuite/g++.dg/template/error12.C new file mode 100644 index 000000000..c15961fc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error12.C @@ -0,0 +1,4 @@ +// PR c++/15044 + +template class <num_t> class a { num_t n; } // { dg-error "" } + diff --git a/gcc/testsuite/g++.dg/template/error13.C b/gcc/testsuite/g++.dg/template/error13.C new file mode 100644 index 000000000..13d8794d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error13.C @@ -0,0 +1,5 @@ +// PR c++/15227 + +template<typename> struct A {}; + +template<typename T> void A<T>::B::foo() {} // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error14.C b/gcc/testsuite/g++.dg/template/error14.C new file mode 100644 index 000000000..c5043cfb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error14.C @@ -0,0 +1,8 @@ +// PR c++/16904 + +template<typename T> struct X +{ + X() { this->T::i; } // { dg-error "" } +}; + +X<int> x; diff --git a/gcc/testsuite/g++.dg/template/error15.C b/gcc/testsuite/g++.dg/template/error15.C new file mode 100644 index 000000000..b7c7bc8ca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error15.C @@ -0,0 +1,24 @@ +// PR c++/16929 + +template <class T> +class A { + int x; +}; + +template <class T> +class B { +protected: + + A<T> a; // { dg-error "" } + + void f(const A<T> * a1 = &a); // { dg-error "this location" } + + void g(void); +}; + +template <class T> +void B<T>::g(void) { + f(); // { dg-error "default argument" } +} + +template class B<long>; diff --git a/gcc/testsuite/g++.dg/template/error16.C b/gcc/testsuite/g++.dg/template/error16.C new file mode 100644 index 000000000..0da024bc6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error16.C @@ -0,0 +1,16 @@ +// PR c++/18674 + +template <typename I> +static void g() { + enum I::t a; // { dg-error "" } + (void) a; +} + +struct B { + typedef int t; +}; + +void h() +{ + g<B>(); +} diff --git a/gcc/testsuite/g++.dg/template/error17.C b/gcc/testsuite/g++.dg/template/error17.C new file mode 100644 index 000000000..f34234da7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error17.C @@ -0,0 +1,10 @@ +// PR c++/20153 + +template <typename T> +void +foo() +{ + union { struct { }; }; // { dg-error "prohibits anonymous struct" "anon" } + // { dg-error "not inside" "not inside" { target *-*-* } 7 } + // { dg-warning "no members" "no members" { target *-*-* } 7 } +} diff --git a/gcc/testsuite/g++.dg/template/error18.C b/gcc/testsuite/g++.dg/template/error18.C new file mode 100644 index 000000000..7b7151a3b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error18.C @@ -0,0 +1,11 @@ +// PR c++/20157 + +template<typename AT> +struct A{ + template<typename T> + void function(T); +}; + +template<> +template<typename ABC,typename DEF> +void A<int>::function(ABC); // { dg-error "match" } diff --git a/gcc/testsuite/g++.dg/template/error19.C b/gcc/testsuite/g++.dg/template/error19.C new file mode 100644 index 000000000..d533e9a3b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error19.C @@ -0,0 +1,22 @@ +// PR c++/23293 + +template < typename > struct P; +struct S; + +void *unrelated_function() +{ + typedef S K; + P < K > * p; + return p; +} + +template < typename U > +void generate_warning() +{ + U::x(); // { dg-error "P<S>" } +} + +int main() +{ + generate_warning< P < S > >(); +} diff --git a/gcc/testsuite/g++.dg/template/error2.C b/gcc/testsuite/g++.dg/template/error2.C new file mode 100644 index 000000000..5bd9b870e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error2.C @@ -0,0 +1,30 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Aug 2003 <nathan@codesourcery.com> + +// instantiated from did not indicate the nested class + +template<class T> struct X +{ + T m; // { dg-error "as type 'void'" "void" } + // { dg-error "incomplete type" "incomplate" { target *-*-* } 10 } + // { dg-error "invalid" "invalid" { target *-*-* } 10 } +}; + +template<class T > +struct Derived +{ + class Nested : public X<T> // { dg-message "instantiated" "" } + { + }; + + Nested m; // { dg-message "instantiated" "" } + + void Foo (); +}; + +void Foo (Derived<void> &x) +{ + x.Foo (); // { dg-message "instantiated" "" } +} diff --git a/gcc/testsuite/g++.dg/template/error20.C b/gcc/testsuite/g++.dg/template/error20.C new file mode 100644 index 000000000..f81378fdb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error20.C @@ -0,0 +1,4 @@ +// PR c++/25439 + +template<int> struct A; +template<> int A<0>; // { dg-error "invalid" } diff --git a/gcc/testsuite/g++.dg/template/error21.C b/gcc/testsuite/g++.dg/template/error21.C new file mode 100644 index 000000000..c5f04f03e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error21.C @@ -0,0 +1,15 @@ +// PR c++/20173 + +template<typename AT> +struct A{ + template<typename T> + void function(T){} +}; + +template<> +template<typename T> +void A<int>::function(T){} + +template<> +template<typename T> +void A<double>::function(T*){} // { dg-error "match" } diff --git a/gcc/testsuite/g++.dg/template/error22.C b/gcc/testsuite/g++.dg/template/error22.C new file mode 100644 index 000000000..d793fe4df --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error22.C @@ -0,0 +1,9 @@ +//PR c++/27821 + +struct A +{ + template<void (A::*)()> struct B {}; + void ::foo(); // { dg-error "invalid use" } + B<&A::foo> b; // { dg-error "incomplete type|template argument" } +}; + diff --git a/gcc/testsuite/g++.dg/template/error23.C b/gcc/testsuite/g++.dg/template/error23.C new file mode 100644 index 000000000..f21d8d9d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error23.C @@ -0,0 +1,17 @@ +// PR c++/29632 + +struct nullptr_type { + + nullptr_type ( void ) {} + + template < typename T > + operator T* ( void ) const { + return ( 0 ); + } +} const nullptr_ob; + +int main ( void ) { + 0 == nullptr_ob; // { dg-error "match" } +} + + diff --git a/gcc/testsuite/g++.dg/template/error24.C b/gcc/testsuite/g++.dg/template/error24.C new file mode 100644 index 000000000..9ce5cbbc2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error24.C @@ -0,0 +1,8 @@ +// PR c++/30863 + +template <typename T> +struct s {}; + +void f() { + unsigned s<int> x; // { dg-error "invalid" } +} diff --git a/gcc/testsuite/g++.dg/template/error25.C b/gcc/testsuite/g++.dg/template/error25.C new file mode 100644 index 000000000..89011576e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error25.C @@ -0,0 +1,16 @@ +// PR c++/31923 + +template<class T> +static void f1 (); + +template<> +static void f1<void> (); // { dg-error "explicit template specialization cannot have a storage class" } + +template<class T> +extern void f2 (); + +template<> +extern void f2<void> (); // { dg-error "explicit template specialization cannot have a storage class" } + +export template<class T> // { dg-warning "keyword 'export' not implemented" } +static void* f3 (); diff --git a/gcc/testsuite/g++.dg/template/error26.C b/gcc/testsuite/g++.dg/template/error26.C new file mode 100644 index 000000000..cd8d46d1e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error26.C @@ -0,0 +1,5 @@ +// PR c++/32112 + +template<typename> struct A; + +template<typename T> void foo (A<&T::template i>); // { dg-error "T:: ?template i|mismatch|& T::i" } diff --git a/gcc/testsuite/g++.dg/template/error27.C b/gcc/testsuite/g++.dg/template/error27.C new file mode 100644 index 000000000..8d41d0248 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error27.C @@ -0,0 +1,5 @@ +// PR c++/27211 + +struct A {}; + +template<int> void A::foo() {} // { dg-error "member function" } diff --git a/gcc/testsuite/g++.dg/template/error28.C b/gcc/testsuite/g++.dg/template/error28.C new file mode 100644 index 000000000..e87d542d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error28.C @@ -0,0 +1,5 @@ +// PR c++/27211 + +struct A {}; + +template<int> void A::foo(); // { dg-error "member function" } diff --git a/gcc/testsuite/g++.dg/template/error29.C b/gcc/testsuite/g++.dg/template/error29.C new file mode 100644 index 000000000..2e2291d7e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error29.C @@ -0,0 +1,5 @@ +// PR c++/33209 + +template<typename T> void foo(int, T::x); // { dg-error "T::x" } + +template<template<typename> class T> void foo2(int, T<int>::x); // { dg-error "T<int>::x" } diff --git a/gcc/testsuite/g++.dg/template/error3.C b/gcc/testsuite/g++.dg/template/error3.C new file mode 100644 index 000000000..d3ee59908 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error3.C @@ -0,0 +1,5 @@ +// PR 12762 + +template <typename> struct A { A() {}}; +typedef A<int> Ac; +Ac<double> a; // { dg-error "template" } diff --git a/gcc/testsuite/g++.dg/template/error30.C b/gcc/testsuite/g++.dg/template/error30.C new file mode 100644 index 000000000..e1138d052 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error30.C @@ -0,0 +1,5 @@ +// PR c++/33210 + +template<int> struct A; + +template<template<typename> class B> A<B<int>::x> operator() (); // { dg-error "A<B<int>::x>" } diff --git a/gcc/testsuite/g++.dg/template/error31.C b/gcc/testsuite/g++.dg/template/error31.C new file mode 100644 index 000000000..4fd702623 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error31.C @@ -0,0 +1,3 @@ +// PR c++/33493 + +template<int> void foo() { delete 0 ? 1 : 0; } // { dg-error "delete 0" } diff --git a/gcc/testsuite/g++.dg/template/error32.C b/gcc/testsuite/g++.dg/template/error32.C new file mode 100644 index 000000000..be3c3a084 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error32.C @@ -0,0 +1,8 @@ +// PR c++/33843 + +struct A {}; + +void foo(A* p()) +{ + p->A::~A(); // { dg-error "A::~A" } +} diff --git a/gcc/testsuite/g++.dg/template/error33.C b/gcc/testsuite/g++.dg/template/error33.C new file mode 100644 index 000000000..b6a2a8ae8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error33.C @@ -0,0 +1,12 @@ +// PR c++/24791 + +template<int> struct A +{ + static int i; + A() { ++i; } +}; + +template<int> int A<0>::i(0); // { dg-error "template" "error" } +// { dg-message "note" "note" { target *-*-* } 9 } + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/error34.C b/gcc/testsuite/g++.dg/template/error34.C new file mode 100644 index 000000000..d0cbcaef2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error34.C @@ -0,0 +1,29 @@ +// PR c++/33842 +// { dg-do compile } + +template<typename T> struct A +{ + A<__builtin_offsetof(T, x)>(); // { dg-error "type/value mismatch|offsetof\\(T, x\\)" } +}; + +template<typename T> struct B +{ + B<__builtin_offsetof(T, x.y)>(); // { dg-error "type/value mismatch|offsetof\\(T, x.y\\)" } +}; + +template<typename T> struct C +{ + C<__builtin_offsetof(T, x[6])>(); // { dg-error "type/value mismatch|offsetof\\(T, x\\\[6\\\]\\)" } +}; + +template<typename T> struct D +{ + D<__builtin_offsetof(T, x.y[6].z)>(); // { dg-error "type/value mismatch|offsetof\\(T, x.y\\\[6\\\].z\\)" } +}; + +struct E { int x; }; + +template<typename T> struct F +{ + F<__builtin_offsetof(E, x)>(); // { dg-error "type/value mismatch|offsetof\\(E, x\\)" } +}; diff --git a/gcc/testsuite/g++.dg/template/error35.C b/gcc/testsuite/g++.dg/template/error35.C new file mode 100644 index 000000000..d52e59931 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error35.C @@ -0,0 +1,3 @@ +// PR c++/33494 + +template<int> void foo(int(*f=0)()); // { dg-error "declared void|scope|erroneous-expression" } diff --git a/gcc/testsuite/g++.dg/template/error36.C b/gcc/testsuite/g++.dg/template/error36.C new file mode 100644 index 000000000..b16b976e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error36.C @@ -0,0 +1,9 @@ +// PR c++/37719.C + +template <typename T> +class foo { + void bar() throw(int); // { dg-error "throw \\(int\\)" } +}; + +template <> +void foo<int>::bar() throw(float) {} // { dg-error "throw \\(float\\)" } diff --git a/gcc/testsuite/g++.dg/template/error37.C b/gcc/testsuite/g++.dg/template/error37.C new file mode 100644 index 000000000..7f1f9ed78 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error37.C @@ -0,0 +1,12 @@ +// { dg-do compile } +// PR C++/29388 +// We used to ICE in is_ancestor because we would use int as the context of foo +// but that is invalid. + +template<int> struct A +{ + typedef int T; + void foo(); +}; + +template<int N> void A<N>::T::foo() {} // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error38.C b/gcc/testsuite/g++.dg/template/error38.C new file mode 100644 index 000000000..14a213299 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error38.C @@ -0,0 +1,43 @@ +// Testcase for printing typename/typedef bindings as well as template args +// in diagnostics (PR c++/25185) + +template <class T> +struct A { + typename T::type f(); // { dg-message "typename T::type = void*" } + void f(int i = 0); // { dg-message "" } + + typedef typename T::type mytype; + mytype g(); // { dg-message "mytype = void*" } + void g(int i = 0); // { dg-message "" } +}; + +struct B +{ + typedef void* type; +}; + +// Also make sure that deduced template arguments get canonicalized. + +template <class T> +void f (T &t); // { dg-message "T = int" } + +template <class T> +void f (T &t, int = 0); // { dg-message "" } + +typedef int myint; +myint i; +myint *p; + +int main() +{ + A<B> a; + a.f(); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 34 } + a.g(); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 36 } + + f(i); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 39 } + f(p); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 41 } +} diff --git a/gcc/testsuite/g++.dg/template/error39.C b/gcc/testsuite/g++.dg/template/error39.C new file mode 100644 index 000000000..49faa3654 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error39.C @@ -0,0 +1,11 @@ +// PR c++/14912 + +template <class T, int N=0, int X=1> +struct A +{ +}; + +void foo(void) +{ + A<void> a = 0; // { dg-error "A<void>" } +} diff --git a/gcc/testsuite/g++.dg/template/error4.C b/gcc/testsuite/g++.dg/template/error4.C new file mode 100644 index 000000000..12942fcb7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error4.C @@ -0,0 +1,9 @@ +template<class T> struct C1 +{ + template<class U> struct C2 + { class Type { }; }; +}; + +template<class T, class U> +void foo(typename C1<T>::C2<U>::Type *) { } // { dg-error "template" "error " } +// { dg-message "note" "note" { target *-*-* } 8 } diff --git a/gcc/testsuite/g++.dg/template/error40.C b/gcc/testsuite/g++.dg/template/error40.C new file mode 100644 index 000000000..7746ed2ce --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error40.C @@ -0,0 +1,32 @@ +// { dg-options "-fno-pretty-templates" } + +template <class T, int N=0, int X=1> +struct A +{ + struct AN; +}; + +void foo(void) +{ + A<void> a = 0; // { dg-error "A<void, 0, 1>" } +} + +template <class T> T f(T); // { dg-message "int f<int>.int." } +template <class T> T f(T, int = 0); // { dg-message "" } + +template <class T> +struct B +{ + typedef typename T::AN BN; + + BN f(); // { dg-message "AN" } + BN f(int = 0); // { dg-message "" } +}; + +int main() +{ + f(1); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 28 } + B<A<int> >().f(); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 30 } +} diff --git a/gcc/testsuite/g++.dg/template/error41.C b/gcc/testsuite/g++.dg/template/error41.C new file mode 100644 index 000000000..c92b8497a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error41.C @@ -0,0 +1,12 @@ +// PR c++/40370 +// { dg-do compile } + +struct A +{ + static int i; +}; + +template <int> struct B +{ + int x[A::i]; // { dg-error "array bound is not an integer constant" } +}; diff --git a/gcc/testsuite/g++.dg/template/error42.C b/gcc/testsuite/g++.dg/template/error42.C new file mode 100644 index 000000000..0d651e316 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error42.C @@ -0,0 +1,20 @@ +// PR c++/40372 +// { dg-do compile } + +template <int> struct A +{ + int i; // { dg-error "invalid use of non-static data member" } + friend void foo () + { + int x[i]; // { dg-error "from this location" } + } +}; + +struct B +{ + int j; // { dg-error "invalid use of non-static data member" } + friend int bar () + { + return j; // { dg-error "from this location" } + } +}; diff --git a/gcc/testsuite/g++.dg/template/error43.C b/gcc/testsuite/g++.dg/template/error43.C new file mode 100644 index 000000000..876e0181a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error43.C @@ -0,0 +1,9 @@ +// PR c++/29363 + +template<int> void foo() +{ + throw A(); // { dg-message "declar" } + struct A {} a; +} + +template void foo<0>(); // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/error44.C b/gcc/testsuite/g++.dg/template/error44.C new file mode 100644 index 000000000..4f732cdd7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error44.C @@ -0,0 +1,7 @@ +// PR c++/32056 + +template <auto int T> struct A {}; // { dg-error "storage class specified" } +template <extern int T> struct B {}; // { dg-error "storage class specified" } +template <static int T> struct C {}; // { dg-error "storage class specified" } +template <register int T> struct D {}; // { dg-error "storage class specified" } +template <mutable int T> struct E {}; // { dg-error "storage class specified" } diff --git a/gcc/testsuite/g++.dg/template/error45.C b/gcc/testsuite/g++.dg/template/error45.C new file mode 100644 index 000000000..454acc631 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error45.C @@ -0,0 +1,22 @@ +// PR c++/47125 + +template < bool, typename > +struct enable_if {}; + +template < typename T > +struct enable_if< true, T > +{ + typedef T type; +}; + +template < typename T > +struct enable_if< true, T >::type +f( T x ); + +void +g( void ) +{ + f< int >( 0 ); // { dg-error "no match" } +} + +// { dg-prune-output "note" } diff --git a/gcc/testsuite/g++.dg/template/error5.C b/gcc/testsuite/g++.dg/template/error5.C new file mode 100644 index 000000000..0c793509d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error5.C @@ -0,0 +1,6 @@ +template <typename T> +struct X<T*> { // { dg-error "not a template" } + typedef int Y; +}; + +extern struct Z<int> s; // { dg-error "not a template" } diff --git a/gcc/testsuite/g++.dg/template/error6.C b/gcc/testsuite/g++.dg/template/error6.C new file mode 100644 index 000000000..7560dcfb5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error6.C @@ -0,0 +1,13 @@ +template<int n> +struct tento { + enum {value = 10*tento<n-1>::value}; +}; + +struct tento<0> { // { dg-error "" } + enum {value=1}; +}; + +int main() { + if (tento<4>::value != 10000) return -1; +} + diff --git a/gcc/testsuite/g++.dg/template/error7.C b/gcc/testsuite/g++.dg/template/error7.C new file mode 100644 index 000000000..3c1a0e1f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error7.C @@ -0,0 +1,6 @@ +// PR c++/13314 +// { dg-options "-O2" } + +struct A { template <int> struct B; }; +struct A::B {}; // { dg-error "" } +A::B<0> b; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/error8.C b/gcc/testsuite/g++.dg/template/error8.C new file mode 100644 index 000000000..30872a2e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error8.C @@ -0,0 +1,7 @@ +// PR c++/11116 + +template <typename T> struct S {}; + +void f() { + throw S (); // { dg-error "template" } +} diff --git a/gcc/testsuite/g++.dg/template/error9.C b/gcc/testsuite/g++.dg/template/error9.C new file mode 100644 index 000000000..60f550a7c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error9.C @@ -0,0 +1,7 @@ +// PR c++/10926 + +struct Foo +{ + template <int i> + ~Foo(); // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/explicit-args1.C b/gcc/testsuite/g++.dg/template/explicit-args1.C new file mode 100644 index 000000000..10d59e157 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit-args1.C @@ -0,0 +1,21 @@ +// PR c++/34950 + +template <class T = int> struct policy { + typedef int unnecessary; +}; + +template <class Policy> struct A { + typedef int type; + typedef typename Policy::unnecessary unused; +}; + +template <class T> struct S { + typedef int type; + typedef typename A<T>::type unused; +}; + +template <class, class T> typename S<T>::type foo(); +template <class> S<policy<> >::type foo(); + +template <typename T> int def(T); +const int i = def(foo<int>); diff --git a/gcc/testsuite/g++.dg/template/explicit-args2.C b/gcc/testsuite/g++.dg/template/explicit-args2.C new file mode 100644 index 000000000..d37b73420 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit-args2.C @@ -0,0 +1,44 @@ +// PR c++/37177 +// { dg-options -std=c++0x } + +#include <typeinfo> + +namespace N1 +{ + template<class T> bool foo(); +} + +struct S +{ + template <class T> + static bool foo(); + + template <class T> + bool bar(); +}; + +template<class T> bool foo(); + +int main() +{ + (void)(&S::bar<int>); + decltype(&S::bar<int>) a; + typeid(&S::bar<int>); + + (void*)(&S::foo<int>); + (void)(&S::foo<int>); + decltype(&S::foo<int>) b; + typeid(&S::foo<int>); + + (void*)(&N1::foo<int>); + (void)(&N1::foo<int>); + decltype(&N1::foo<int>) c; + typeid(&N1::foo<int>); + + (void*)(&foo<int>); + (void)(&foo<int>); + decltype(&foo<int>) d; + typeid(&foo<int>); + + &foo<int> == 0; +} diff --git a/gcc/testsuite/g++.dg/template/explicit-args3.C b/gcc/testsuite/g++.dg/template/explicit-args3.C new file mode 100644 index 000000000..c095e6688 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit-args3.C @@ -0,0 +1,12 @@ +// PR c++/37177 + +template <class T> +struct A { }; + +template <class T> +void operator+(T, T); // { dg-error "class or enum" } + +int main() +{ + operator+<int>; // { dg-error "cannot resolve" } +} diff --git a/gcc/testsuite/g++.dg/template/explicit-instantiation.C b/gcc/testsuite/g++.dg/template/explicit-instantiation.C new file mode 100644 index 000000000..67e44c49f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit-instantiation.C @@ -0,0 +1,16 @@ +// Contributed by Gabriel Dos Reis <gdr@codesourcery.com> +// Origin: Jens.Maurer@gmx.net +// { dg-do compile } + +// Fixed: PR 3381 + +namespace N +{ + template<class T> + class A { }; +} + +template class ::N::A<int>; + + + diff --git a/gcc/testsuite/g++.dg/template/explicit-instantiation2.C b/gcc/testsuite/g++.dg/template/explicit-instantiation2.C new file mode 100644 index 000000000..21109a765 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit-instantiation2.C @@ -0,0 +1,6 @@ +// Bug 10968: implicit instantiation overrides explicit instantiation +// { dg-final { scan-assembler "_Z1fIiET_S0_" } } + +template <class T> T f (T t) { return t; } +inline void g () { f (4); } +template int f (int); diff --git a/gcc/testsuite/g++.dg/template/explicit-instantiation3.C b/gcc/testsuite/g++.dg/template/explicit-instantiation3.C new file mode 100644 index 000000000..fac092e6c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit-instantiation3.C @@ -0,0 +1,31 @@ +// { dg-do compile } +// Origin: <sebor at roguewave dot com> +// c++/8266: Explicit instantiation of a template outside its namespace is +// broken + +namespace N +{ + template <class T> T foo (T) + { return T (); } + + struct A + { + template <int N> + struct B {}; + }; + + template <int M> + struct C {}; + + template double foo(double); + template float foo<float>(float); + template struct A::B<0>; + template struct C<0>; +} + +template int N::foo(int); +template char N::foo<char>(char); +template struct N::A::B<1>; +template struct N::C<1>; + + diff --git a/gcc/testsuite/g++.dg/template/explicit1.C b/gcc/testsuite/g++.dg/template/explicit1.C new file mode 100644 index 000000000..64f581e58 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit1.C @@ -0,0 +1,17 @@ +// { dg-do link } +// { dg-options "-fno-implicit-templates" } + +template <class T> struct C { + ~C(); +}; +template <class T> C<T>::~C() {} + +struct X { + C<X> *p; + ~X() { delete p; } +}; + +template class C<X>; +C<X> x; + +int main () {} diff --git a/gcc/testsuite/g++.dg/template/explicit2.C b/gcc/testsuite/g++.dg/template/explicit2.C new file mode 100644 index 000000000..79941cd8e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit2.C @@ -0,0 +1,10 @@ +struct X { + template <class B> void foo(B); +}; + +template <class D> +void bar() { + X().foo<D>(1); +} + +template void bar<int> (); diff --git a/gcc/testsuite/g++.dg/template/explicit3.C b/gcc/testsuite/g++.dg/template/explicit3.C new file mode 100644 index 000000000..49d0689a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit3.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Jul 2003 <nathan@codesourcery.com> + +// Failed to spot specialization using a template-id expr + +template <int n> class A {}; +template <int m> class R {}; + +template <int n, int x> struct Trait { enum {m = n}; }; + +template <int n, int x> R<Trait<n,x>::m> f(A<x>); +template <> R<Trait<1,1>::m> f<1>(A<1>) {return R<1>();} + +void Baz () +{ + R<Trait<1,1>::m> (*ptr) (A<1>); + + ptr = &f<1>; + +} diff --git a/gcc/testsuite/g++.dg/template/explicit4.C b/gcc/testsuite/g++.dg/template/explicit4.C new file mode 100644 index 000000000..3953f8fc7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit4.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Jul 2003 <nathan@codesourcery.com> + +// Failed to spot specialization using a template-id expr + +template <typename n> class A {}; +template <int m> class R {}; + +template <int n, int x> struct Trait { enum {m = n}; }; + +template <typename n, typename x> R<Trait<1,1>::m> f(A<x>); +template <> R<Trait<1,1>::m> f<int>(A<int>) {return R<1>();} diff --git a/gcc/testsuite/g++.dg/template/explicit5.C b/gcc/testsuite/g++.dg/template/explicit5.C new file mode 100644 index 000000000..a0e313354 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit5.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Jul 2003 <nathan@codesourcery.com> + +// Failed to spot specialization using a template-id expr + +template <typename n> class A {}; +template <int m> class R {}; + +template <typename n, typename x> struct Trait { enum {m = sizeof (n)}; }; + +template <typename n, typename x> R<Trait<n,x>::m> f(A<x>); +template <> R<Trait<char,char>::m> f<char>(A<char>) {return R<1>();} diff --git a/gcc/testsuite/g++.dg/template/explicit6.C b/gcc/testsuite/g++.dg/template/explicit6.C new file mode 100644 index 000000000..f740269bb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit6.C @@ -0,0 +1,8 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Feb 2005 <nathan@codesourcery.com> + +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> +// Bug 19895: ICE on invalid + +struct A; +template A<>::A(); // { dg-error "(not a template)|(explicit qualification)" "" } diff --git a/gcc/testsuite/g++.dg/template/explicit7.C b/gcc/testsuite/g++.dg/template/explicit7.C new file mode 100644 index 000000000..742467718 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit7.C @@ -0,0 +1,13 @@ +// PR c++/22263 +// { dg-do link } + +template <class T> struct S { T foo (); T bar (); }; +template <class T> T S<T>::foo () { return bar (); } +template struct S<int>; +template <class T> T S<T>::bar () { return T (); } + +#if !__GXX_WEAK__ +template int S<int>::bar (); +#endif + +int main () { return S<int>().foo (); } diff --git a/gcc/testsuite/g++.dg/template/explicit8.C b/gcc/testsuite/g++.dg/template/explicit8.C new file mode 100644 index 000000000..4b92dbe39 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/explicit8.C @@ -0,0 +1,13 @@ +namespace N { + template <typename T> + struct S { + void f() {} + }; + namespace I { + template void S<double>::f(); // { dg-error "namespace" } + } +} + +namespace K { + template void N::S<int>::f(); // { dg-error "namespace" } +} diff --git a/gcc/testsuite/g++.dg/template/expr1.C b/gcc/testsuite/g++.dg/template/expr1.C new file mode 100644 index 000000000..079865d4e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/expr1.C @@ -0,0 +1,8 @@ +// PR c++/18161 +// { dg-options "" } + +template <class T> struct Y; +template <> struct Y<bool> {}; + +template <typename T = typeof (1 == 1)> struct X { Y<T> a; }; +template struct X <>; diff --git a/gcc/testsuite/g++.dg/template/field1.C b/gcc/testsuite/g++.dg/template/field1.C new file mode 100644 index 000000000..c61437b28 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/field1.C @@ -0,0 +1,12 @@ +struct A { + void (*f)(void); +}; + +template< typename R > +struct B : public A { + void g() + { + A::f(); + } +}; +template class B<bool>; diff --git a/gcc/testsuite/g++.dg/template/fnspec1.C b/gcc/testsuite/g++.dg/template/fnspec1.C new file mode 100644 index 000000000..5d5324475 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fnspec1.C @@ -0,0 +1,16 @@ +// PR c++/35146 + +template <typename T> struct S {}; + +template <typename R> struct ref; +template <> struct ref<double> { typedef double result; }; + +template <typename T> +void foo(typename ref<T>::result, S<T>*); +template <> +void foo(S<double>, S<double>*); // { dg-error "does not match" } +template <> +void foo(double alpha, S<double>* x) +{ + alpha; x; +} diff --git a/gcc/testsuite/g++.dg/template/fntry1.C b/gcc/testsuite/g++.dg/template/fntry1.C new file mode 100644 index 000000000..494be5ab0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fntry1.C @@ -0,0 +1,43 @@ +// PR c++/26433 +// { dg-do link } + +int get_int() +{ + throw 1; + + return 0; +} + +template <class _T> class Test +{ +public: + Test() + try + : i(get_int()) + { + i++; + } + catch(...) + { + // Syntax error caused by undefined __FUNCTION__. + const char* ptr = __FUNCTION__; + } + +private: + int i; + _T t; +}; + +int main() +{ + try + { + Test<int> test; + } + catch(...) + { + return 1; + } + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/fntype1.C b/gcc/testsuite/g++.dg/template/fntype1.C new file mode 100644 index 000000000..d7be273aa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fntype1.C @@ -0,0 +1,26 @@ +bool f(int i) { return i != 5; } + +template <class X, class P = bool(X)> +struct Traits +{ + typedef P type; +}; + +template <class X, class P = typename Traits<X>::type> +struct S +{ + const P& p_; + S( const P& p ) : p_(p) {} // const reference +}; + +template <class X> +S<X> make_s(const typename Traits<X>::type & p) // const reference +{ + return S<X>(p); // << HERE +} + + +int main() +{ + make_s<int>(f); +} diff --git a/gcc/testsuite/g++.dg/template/for1.C b/gcc/testsuite/g++.dg/template/for1.C new file mode 100644 index 000000000..dc33afcda --- /dev/null +++ b/gcc/testsuite/g++.dg/template/for1.C @@ -0,0 +1,23 @@ +// PR c++/47388 +// { dg-do compile } +// { dg-options "-fno-for-scope" } + +template <int> +void +foo () +{ + int i; + for (i = 0; i < 16; i++) + ; + for (int j = 0; j < 16; j++) + ; + if (j != 16) + for (;;) + ; +} + +void +bar () +{ + foo <0> (); +} diff --git a/gcc/testsuite/g++.dg/template/friend.C b/gcc/testsuite/g++.dg/template/friend.C new file mode 100644 index 000000000..44cbce938 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend.C @@ -0,0 +1,30 @@ +// Contribued by Gabriel Dos Reis <gdr@codesourcery.com> +// Origin: iskey@i100.ryd.student.liu.se + +class ostream; +extern ostream& cout; + +template <class T> struct s; + +template <class T> +ostream& operator<<(ostream &o, const typename s<T>::t &x) // { dg-message "note" } +{ + return o; +} + +template <class T> +struct s { + struct t + { + friend ostream& + operator<<<T>(ostream&, const typename s<T>::t &); + }; + t x; +}; + +int main() +{ + s<int>::t y; + cout << y; // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 28 } +} diff --git a/gcc/testsuite/g++.dg/template/friend10.C b/gcc/testsuite/g++.dg/template/friend10.C new file mode 100644 index 000000000..cab5e346f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend10.C @@ -0,0 +1,45 @@ +// { dg-do run } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com> + +// PR 5116. template instantiation can add a friend into a namespace, +// and thus change overload resolution. + +#include <iostream> + +static int right; +static int wrong; + +struct Buggy {}; + +template <typename T>struct Handle +{ + Handle(T* p) {} + + operator bool() const { wrong++; return true; } + + friend std::ostream& operator<<(std::ostream& ostr, const Handle& r) + { + right++; + + return ostr << "in operator<<(ostream&, const Handle&)"; + } +}; + +typedef Handle<Buggy> Buggy_h; + +bool cmp (const Buggy_h& b1, const Buggy_h& b2) +{ + std::cout << b1 << " " << b2 << std::endl; + return false; +} + +int main() +{ + Buggy o; + + cmp (&o, &o); + + return !(right == 2 && !wrong); +} diff --git a/gcc/testsuite/g++.dg/template/friend11.C b/gcc/testsuite/g++.dg/template/friend11.C new file mode 100644 index 000000000..343b52752 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend11.C @@ -0,0 +1,18 @@ +/* PR c++/53 */ +/* { dg-do compile } */ + +template <class T> +struct A { + template <class U> class B; + + // Did not compile with gcc-2.95.2 (linux i686) :-( + template <class S> template <class U> friend class A<S>::B; +}; + +template <class S> template <class U> class A<S>::B { +}; + +int main(){ + A<double>::B<double> ab; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/friend12.C b/gcc/testsuite/g++.dg/template/friend12.C new file mode 100644 index 000000000..0cd561b5a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend12.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR 9030. Perform access checking to parameter and return type of +// function template correctly when the template is friend. + +template <class T> class Outer { + private: + struct Inner {}; + + template <class T_> + friend typename Outer<T_>::Inner foo (); +}; + +template <class T> +typename Outer<T>::Inner +foo () { + return typename Outer<T>::Inner(); +} + +void f() { + foo<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/friend13.C b/gcc/testsuite/g++.dg/template/friend13.C new file mode 100644 index 000000000..6eebf6b95 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend13.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Perform access checking to parameter and return type of +// function template correctly when only specialization is friend. + +template <class T> +typename T::Inner +foo () { + return typename T::Inner(); +} + +class Outer { + private: + struct Inner {}; + + friend Outer::Inner foo<Outer> (); +}; + +void f() { + foo<Outer>(); +} diff --git a/gcc/testsuite/g++.dg/template/friend14.C b/gcc/testsuite/g++.dg/template/friend14.C new file mode 100644 index 000000000..6e07b9893 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend14.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// Perform access checking to parameter and return type of +// function template correctly when the template is friend. + +template <class T> class O { + struct I { I (int); }; + + template <class T_> + friend typename O<T_>::I f (); +}; + +template <class T_> +typename O<T_>::I f () { return 1; } + +struct X { + void g() { f<int>(); } +}; diff --git a/gcc/testsuite/g++.dg/template/friend15.C b/gcc/testsuite/g++.dg/template/friend15.C new file mode 100644 index 000000000..4acbf2d1a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend15.C @@ -0,0 +1,19 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/9453 +// Access checking when template friend is defined in class. + +template <typename> class X { + private: + struct Inner; + + template <typename R> + friend typename X<R>::Inner * foo () { return 0; } +}; +template class X<void>; + +struct U { + void bar () { foo<void> (); } +}; diff --git a/gcc/testsuite/g++.dg/template/friend16.C b/gcc/testsuite/g++.dg/template/friend16.C new file mode 100644 index 000000000..3165ed2b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend16.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/9602: Inline friend/pure virtual tree data sharing in +// class template. + +template <typename T> struct X { + void foo (X); + friend void bar () {} +}; + +template <typename T> +void X<T>::foo (X x) {} + +template struct X<int>; diff --git a/gcc/testsuite/g++.dg/template/friend17.C b/gcc/testsuite/g++.dg/template/friend17.C new file mode 100644 index 000000000..50d602441 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend17.C @@ -0,0 +1,12 @@ +template <class T> +struct X { + template <class U> void operator+=(U); + + template <class V> + template <class U> + friend void X<V>::operator+=(U); +}; + +int main() { + X<int>() += 1.0; +} diff --git a/gcc/testsuite/g++.dg/template/friend18.C b/gcc/testsuite/g++.dg/template/friend18.C new file mode 100644 index 000000000..04ba26e98 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend18.C @@ -0,0 +1,19 @@ +// { dg-do run } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Mar 2003 <nathan@codesourcery.com> + +// PR 10158. implicit inline template friends ICE'd + +template <int N> struct X +{ + template <int M> friend int foo(X const &) + { + return N * 10000 + M; + } +}; +X<1234> bring; + +int main() { + return foo<5678> (bring) != 12345678; +} diff --git a/gcc/testsuite/g++.dg/template/friend19.C b/gcc/testsuite/g++.dg/template/friend19.C new file mode 100644 index 000000000..73883b2a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend19.C @@ -0,0 +1,28 @@ +// { dg-do compile } + +// Origin: Benjamin Li <benxbli@yahoo.com> + +// PR c++/11030: Template substitution of friend class that is +// a specialization. + +template <int S> +struct A +{ + void func(void); +}; + +template <class T> +class C +{ + static void private_func(void) {} +public: + friend class A<512>; +}; + +template <int S> +void A<S>::func(void) +{ + C<void>::private_func(); +} + +template class A<512>; diff --git a/gcc/testsuite/g++.dg/template/friend20.C b/gcc/testsuite/g++.dg/template/friend20.C new file mode 100644 index 000000000..496d52f5e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend20.C @@ -0,0 +1,15 @@ +template <class T> +struct A +{ + friend void bar(A<T> a) {} +}; + +void bar(A<int>); + +int main() +{ + A<int> a; + + bar(a); +} + diff --git a/gcc/testsuite/g++.dg/template/friend21.C b/gcc/testsuite/g++.dg/template/friend21.C new file mode 100644 index 000000000..854ed67d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend21.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: ajl13@bellatlantic.net + +// PR c++/5421: ICE for specialization of member function template +// as friend. + +struct B { + template <class T> void b(); +}; + +template <class T> class A { + friend void B::b<T>(); +}; + +static A<int> a; diff --git a/gcc/testsuite/g++.dg/template/friend22.C b/gcc/testsuite/g++.dg/template/friend22.C new file mode 100644 index 000000000..41a73bbb4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend22.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: Benoit Hudson <bh@techhouse.brown.edu> + +// PR c++/641: Duplicate friend diagnostics + +template <class T> class iterator { }; +template <class T> class item { + friend class iterator<T>; + friend class iterator<const T>; +}; + +class A { }; + +item<const A> i; diff --git a/gcc/testsuite/g++.dg/template/friend23.C b/gcc/testsuite/g++.dg/template/friend23.C new file mode 100644 index 000000000..96f8125b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend23.C @@ -0,0 +1,38 @@ +// { dg-do compile } + +// Origin: Alexandre Tolmos <ktulu@free.fr> + +// PR c++/11876: Friend of its own class diagnostics + +template <typename T> +class A +{ + friend class A<int>; + friend class A<float>; +protected: + T _data; + inline A() : _data(0) {} + template <typename U> + inline A(const A<U>& r) : _data(r._data) {} +}; + +class B : public A<int> +{ +public: + inline B() {} + inline B(const B& r) : A<int>(r) {} +}; + +class C : public A<float> +{ +public: + inline C() {} + inline C(const B& r) : A<float>(r) {} +}; + +int main(int, char*[]) +{ + B b1, b2(b1); + C c(b1); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/friend24.C b/gcc/testsuite/g++.dg/template/friend24.C new file mode 100644 index 000000000..5db4d31e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend24.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/495: Fail to locate primary class template that is +// injected by friend declaration. + +template <int N> struct X +{ + template <int dim> friend struct Y; +}; + +X<2> x; + +template <int dim> struct Y +{ + void f (Y); + void g (Y); +}; + +template <int dim> void Y<dim>::f (Y) +{ +} + +template <int dim> void Y<dim>::g (Y<dim>) +{ +} diff --git a/gcc/testsuite/g++.dg/template/friend25.C b/gcc/testsuite/g++.dg/template/friend25.C new file mode 100644 index 000000000..fa11defc2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend25.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Origin: Jiangbin Zhao <zhaojiangbin@yahoo.com> + +// PR c++/12369: ICE for specialization of member function template +// as friend in ordinary class. + +struct A { + template<class T> T* make() { return new T(); } +}; + +struct B { + friend B* A::make< B >(); // (1) +}; diff --git a/gcc/testsuite/g++.dg/template/friend26.C b/gcc/testsuite/g++.dg/template/friend26.C new file mode 100644 index 000000000..3cf659df4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend26.C @@ -0,0 +1,15 @@ +// PR c++/14359 + +template<typename> struct A {}; + +template<typename> struct B +{ + template<typename T> friend void foo(const A<T>& a, const B&) { a; } +}; + +void bar() +{ + A<void> a; + B<void> b; + foo(a,b); +} diff --git a/gcc/testsuite/g++.dg/template/friend27.C b/gcc/testsuite/g++.dg/template/friend27.C new file mode 100644 index 000000000..6317da577 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend27.C @@ -0,0 +1,22 @@ +// PR c++/15265 + +enum Relation {equalOp}; +template<typename B> +class A { +public: + static + bool Relop(const A&, const A&, Relation); + + friend + bool operator==(const A& a1, const A& a2) { + return Relop(a1, a2, equalOp); + } + B* b; +}; + +int main() { + A<int> a; a == a; + return 0; +} + + diff --git a/gcc/testsuite/g++.dg/template/friend28.C b/gcc/testsuite/g++.dg/template/friend28.C new file mode 100644 index 000000000..a7d160d5f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend28.C @@ -0,0 +1,23 @@ +// PR c++/15629 +// { dg-do link } + +template<int a, int b> class T; + +template<int a, int b> void func(T<a, b> * t); +template<int a> void func(T<a, 3> * t) {} +template void func<2>(T<2, 3>*); + +template<int a, int b> struct T { + friend void func<a, b>(T<a, b> * t); + friend void func<a> (T<a, 3> * t); + + void foo(); +}; + +template<int a, int b> void T<a, b>::foo() { + func((T<2,3>*)0); +} + +int main() { + T<2,3>().foo(); +} diff --git a/gcc/testsuite/g++.dg/template/friend29.C b/gcc/testsuite/g++.dg/template/friend29.C new file mode 100644 index 000000000..1c0c6f0f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend29.C @@ -0,0 +1,11 @@ +// PR c++/15701 + +template<template<int> class T> struct A : T<0> +{ + void foo(); + template<template<int> class U> friend void A<U>::foo(); +}; + +template<int> struct B {}; + +A<B> a; diff --git a/gcc/testsuite/g++.dg/template/friend3.C b/gcc/testsuite/g++.dg/template/friend3.C new file mode 100644 index 000000000..7400534ac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend3.C @@ -0,0 +1,31 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 28 Dec 2001 <nathan@codesourcery.com> + +// PR 775 friend classes with qualified names inside template classes. + +struct A +{ + struct B { + B () { } + }; +}; + +template <class T> +struct C: A { + friend A::B::B (); // 2.95.2 ICE + friend struct A; + friend struct A::B; // 2.97 error +}; + +template class C<char>; + +template <typename T> class TPL +{ + class nested; +}; + +template <typename T> class TPL<T>::nested +{ +}; diff --git a/gcc/testsuite/g++.dg/template/friend30.C b/gcc/testsuite/g++.dg/template/friend30.C new file mode 100644 index 000000000..055fc8d89 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend30.C @@ -0,0 +1,15 @@ +// PR c++/14930 + +template<typename T> class Point; + +template<> class Point<double> { + friend class Plane; + double v; +}; + +struct Plane { + double get(const Point<double>& p); +}; + +double Plane::get(const Point<double> &p) { return p.v; } + diff --git a/gcc/testsuite/g++.dg/template/friend31.C b/gcc/testsuite/g++.dg/template/friend31.C new file mode 100644 index 000000000..5e60540b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend31.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> + +// PR c++/15410: Declaration of friend class template with wrong +// template parameter. + +template <typename T, typename U> struct F; // { dg-message "previous declaration" } + +class W +{ + template<int i> friend class F; // { dg-error "template parameter" } + int x; // { dg-error "private" } +}; + +template <typename T, typename U> struct F +{ + void Look(W& w) { w.x = 3; } // { dg-error "within this context" } +}; + +int main() +{ + W w; + F<char, bool> f; + f.Look(w); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/friend32.C b/gcc/testsuite/g++.dg/template/friend32.C new file mode 100644 index 000000000..81e6390d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend32.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Steven Bosscher <steven@gcc.gnu.org> +// Serge Belyshev <belyshev@lubercy.com> + +// PR c++/18825: ICE member as friend + +template<class T> class A +{ + void f (); // { dg-error "private" } +}; + +template<class T> class B +{ + friend void A<T>::f (); // { dg-error "this context" } +}; + +int f () +{ + B<int> b; // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/friend33.C b/gcc/testsuite/g++.dg/template/friend33.C new file mode 100644 index 000000000..f1b5cb26a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend33.C @@ -0,0 +1,12 @@ +// { dg-do compile } +// PR c++/18733: Validation of template headers in friends + +template<int> struct A +{ + void foo(); +}; + +struct B +{ + friend void A<0>::foo(); +}; diff --git a/gcc/testsuite/g++.dg/template/friend34.C b/gcc/testsuite/g++.dg/template/friend34.C new file mode 100644 index 000000000..555cf358a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend34.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: mleone@pixar.com +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/9783: Forward declaration of class in template. + +template <typename T> +struct C { + void foo (struct X *); +}; + +struct X {}; + +template <typename T> +void C<T>::foo(struct X *) {} diff --git a/gcc/testsuite/g++.dg/template/friend35.C b/gcc/testsuite/g++.dg/template/friend35.C new file mode 100644 index 000000000..b150ccdab --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend35.C @@ -0,0 +1,28 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// PR c++/4403: Incorrect friend class chosen during instantiation. + +template <typename T> +struct A +{ + struct F; +}; + +template <typename T> +struct B : A<T> +{ + friend struct F; +private: + int priv; +}; + +struct F +{ + void func(void) + { + B<int> b; + b.priv = 0; + } +}; diff --git a/gcc/testsuite/g++.dg/template/friend36.C b/gcc/testsuite/g++.dg/template/friend36.C new file mode 100644 index 000000000..5f07db486 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend36.C @@ -0,0 +1,10 @@ +// PR c++/22139 +// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +template <int rank, int dim> class Tensor; +template <int rank, int dim> struct SymmetricTensor { + SymmetricTensor (const Tensor<2,dim> &t); + friend void foo(); +}; +template <> SymmetricTensor<2,2>::SymmetricTensor (const Tensor<2,2> &t) {} +template <> SymmetricTensor<2,3>::SymmetricTensor (const Tensor<2,3> &t) {} diff --git a/gcc/testsuite/g++.dg/template/friend37.C b/gcc/testsuite/g++.dg/template/friend37.C new file mode 100644 index 000000000..7c8682906 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend37.C @@ -0,0 +1,15 @@ +// PR c++/22147 + +template<typename> struct A; + +template<typename T> void foo(A<T>* p) { *p; } + +template<typename> struct A +{ + friend void foo<class X>(A<X>*); +}; + +void bar() +{ + foo<int>(0); +} diff --git a/gcc/testsuite/g++.dg/template/friend38.C b/gcc/testsuite/g++.dg/template/friend38.C new file mode 100644 index 000000000..41faf7911 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend38.C @@ -0,0 +1,12 @@ +// PR c++/22352 + +template <class A> +class s +{ + typedef int d; + template <class s, typename s::d> + friend class t; +}; + +s<int> t1; + diff --git a/gcc/testsuite/g++.dg/template/friend39.C b/gcc/testsuite/g++.dg/template/friend39.C new file mode 100644 index 000000000..9ebe226eb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend39.C @@ -0,0 +1,7 @@ +// PR c++/8355 + +namespace Foo { template <typename T> void foo();} +struct Bar +{ + friend void Foo::foo<int>(); +}; diff --git a/gcc/testsuite/g++.dg/template/friend4.C b/gcc/testsuite/g++.dg/template/friend4.C new file mode 100644 index 000000000..fabf3375b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend4.C @@ -0,0 +1,46 @@ +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 18 Dec 2001 <nathan@codesourcery.com> + +// PR 109, dependent member friends + +struct B +{ + static int foo (); + struct N + { + static int bar (); + }; +}; + + +template <class T> +class A +{ + friend int T::foo (); + friend int T::N::bar (); + + private: + static int m; +}; + +template <class T> +class C +{ + friend struct T::N; + + private: + static int m; +}; + + +int B::foo () +{ + return A<B>::m; +} + +int B::N::bar () +{ + return A<B>::m + C<B>::m; +} diff --git a/gcc/testsuite/g++.dg/template/friend40.C b/gcc/testsuite/g++.dg/template/friend40.C new file mode 100644 index 000000000..39dd994e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend40.C @@ -0,0 +1,16 @@ +// PR c++/24173 +// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +template <int> struct A; + +void foo(A<0>); + +template<int> struct A +{ + friend void foo(A<0>); +}; + +void bar() +{ + foo(A<0>()); +} diff --git a/gcc/testsuite/g++.dg/template/friend41.C b/gcc/testsuite/g++.dg/template/friend41.C new file mode 100644 index 000000000..6d686019d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend41.C @@ -0,0 +1,11 @@ +// PR c++/26912 + +struct Foo { + template<class T> int func() const; +}; + +class Bar { + friend int Foo::func<int>() const; +}; + + diff --git a/gcc/testsuite/g++.dg/template/friend42.C b/gcc/testsuite/g++.dg/template/friend42.C new file mode 100644 index 000000000..73d10df01 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend42.C @@ -0,0 +1,8 @@ +// { dg-do compile } + +template <class T> void foo (int); + +template <class T> +class Q { + friend void foo<T> (int = 3); // { dg-error "default argument" } +}; diff --git a/gcc/testsuite/g++.dg/template/friend43.C b/gcc/testsuite/g++.dg/template/friend43.C new file mode 100644 index 000000000..edbed8420 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend43.C @@ -0,0 +1,11 @@ +// PR c++/28111 +// { dg-do compile } + +template<typename> void foo(); + +template<typename T> struct A +{ + friend void foo<>(typename T::X); // { dg-error "not a class" } +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/friend44.C b/gcc/testsuite/g++.dg/template/friend44.C new file mode 100644 index 000000000..814fec1d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend44.C @@ -0,0 +1,9 @@ +// { dg-options "-fshow-column" } +//PR c++/28260 + +template<int> struct A +{ + friend int foo(); // { dg-error "14:new declaration" } +}; + +void foo() { A<0> a; } // { dg-error "6:ambiguates old declaration" } diff --git a/gcc/testsuite/g++.dg/template/friend45.C b/gcc/testsuite/g++.dg/template/friend45.C new file mode 100644 index 000000000..61c365617 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend45.C @@ -0,0 +1,17 @@ +// PR c++/28025 + +class BaseSubmit +{ + template<class T> friend class PeriodicSubmit; +}; + +template<class ID> +class ValuesSubmit +{ + template<class T> friend class PeriodicSubmit; +}; + +class A; +class MultiSubmit : public ValuesSubmit<A> +{ +}; diff --git a/gcc/testsuite/g++.dg/template/friend46.C b/gcc/testsuite/g++.dg/template/friend46.C new file mode 100644 index 000000000..17dc0db94 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend46.C @@ -0,0 +1,9 @@ +// PR c++/27714 + +template<typename> struct A +{ + static void* operator new(__SIZE_TYPE__); + template <typename T> friend void* A<T>::operator new(__SIZE_TYPE__); +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/friend47.C b/gcc/testsuite/g++.dg/template/friend47.C new file mode 100644 index 000000000..612173950 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend47.C @@ -0,0 +1,11 @@ +// PR c++/19809 + +template<int i> +struct n{ + friend void foo(){ } // { dg-error "defin" } +}; + +int main(){ + n<1> n1; + n<2> n2; +} diff --git a/gcc/testsuite/g++.dg/template/friend48.C b/gcc/testsuite/g++.dg/template/friend48.C new file mode 100644 index 000000000..604697dae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend48.C @@ -0,0 +1,12 @@ +// PR c++/29020 + +template<int> struct A +{ + void foo(); +}; + +struct B +{ + template<int N> friend void A<N>::A::foo(); +}; + diff --git a/gcc/testsuite/g++.dg/template/friend49.C b/gcc/testsuite/g++.dg/template/friend49.C new file mode 100644 index 000000000..b4d717f57 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend49.C @@ -0,0 +1,18 @@ +// PR c++/29054 +// { dg-do compile } + +struct A +{ + template <typename T, typename U> static void create (U) {} +}; + +struct B +{ + friend void A::create <B, const char *> (const char *); +}; + +int +main () +{ + A::create<B>("test"); +} diff --git a/gcc/testsuite/g++.dg/template/friend5.C b/gcc/testsuite/g++.dg/template/friend5.C new file mode 100644 index 000000000..1a63e71e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend5.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +namespace NS { template <typename number> class C; } + +template <typename T> class X { + template <typename N> friend class NS::C; +}; + +template class X<int>; diff --git a/gcc/testsuite/g++.dg/template/friend50.C b/gcc/testsuite/g++.dg/template/friend50.C new file mode 100644 index 000000000..93c429ab1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend50.C @@ -0,0 +1,9 @@ +// PR c++/34399 +template<int> struct X +{ + void foo(); +}; + +struct Y { + template<long N> friend void X<N>::X::foo(); // { dg-error "declared as friend" } +}; diff --git a/gcc/testsuite/g++.dg/template/friend51.C b/gcc/testsuite/g++.dg/template/friend51.C new file mode 100644 index 000000000..d2d1ad799 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend51.C @@ -0,0 +1,17 @@ +// PR c++/38392 +// { dg-do link } + +void Function(); + +int main() +{ + Function(); +} + +template <typename T> +struct Test +{ + friend void Function() { } +}; + +template class Test<int>; diff --git a/gcc/testsuite/g++.dg/template/friend6.C b/gcc/testsuite/g++.dg/template/friend6.C new file mode 100644 index 000000000..e330d9818 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend6.C @@ -0,0 +1,53 @@ +// { dg-do compile } + +namespace boost_no_member_template_friends{ + +template <class T> +class foobar; + +template <class T> +class foo +{ +private: + template<typename Y> friend class foobar; + template<typename Y> friend class foo; + template<typename Y> friend bool must_be_friend_proc(const foo<Y>& f); + int i; +public: + foo(){ i = 0; } + template <class U> + foo(const foo<U>& f){ i = f.i; } +}; + +template <class T> +class foo; + +template <class T> +bool must_be_friend_proc(const foo<T>& f); + +template <class T> +bool must_be_friend_proc(const foo<T>& f) +{ return f.i != 0; } + +template <class T> +class foobar +{ + int i; +public: + template <class U> + foobar(const foo<U>& f) + { i = f.i; } +}; + + +int test() +{ + foo<int> fi; + foo<double> fd(fi); + (void) &fd; // avoid "unused variable" warning + foobar<long> fb(fi); + (void) &fb; // avoid "unused variable" warning + return 0; +} + +} diff --git a/gcc/testsuite/g++.dg/template/friend7.C b/gcc/testsuite/g++.dg/template/friend7.C new file mode 100644 index 000000000..a954f8990 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend7.C @@ -0,0 +1,33 @@ +// { dg-do compile } + +template <typename V> +struct b +{ + template <typename T> + class a + { + template <typename> + friend class a; + + T t_; + + public: + a() {} + a(a<T *> const &); + }; +}; + +template <typename V> +template <typename T> +b<V>::a<T>::a(a<T *> const &rhs): t_(*rhs.t_) +{} + + +int +f () +{ + b<void *>::a<char *> q; + b<void *>::a<char> w(q); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/friend8.C b/gcc/testsuite/g++.dg/template/friend8.C new file mode 100644 index 000000000..21fd242f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend8.C @@ -0,0 +1,18 @@ +template <int N> struct ivector +{ + template <int r, int c> friend void + mult_mv (); +}; + +template struct ivector<3>; + +template <int r, int c> void +mult_mv () +{ + c; +} + +void get_local_point_pos () +{ + mult_mv<7, 3> (); +} diff --git a/gcc/testsuite/g++.dg/template/friend9.C b/gcc/testsuite/g++.dg/template/friend9.C new file mode 100644 index 000000000..add5fb0d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend9.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/8099 +// Partial specialization as friend class + +template <int N, typename T> struct X; +template <typename T> struct X<1,T>; + +template <typename P> class Y { + static int i; + template <int N, typename T> friend struct X; + friend struct X<1,P>; +}; + +template <typename T> struct X<1,T> { + X () { Y<T>::i; } // access private field +}; diff --git a/gcc/testsuite/g++.dg/template/func1.C b/gcc/testsuite/g++.dg/template/func1.C new file mode 100644 index 000000000..0d1677060 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/func1.C @@ -0,0 +1,13 @@ +template <typename T1,typename T2> +inline void f(const T1&,const T2&) { } + +template <typename T1,typename T2,void F(const T1&,const T2&)> +struct A { + template <typename T> void g(T& i) { } +}; + +int main() { + int i; + A<int,int,f> a; + a.g(i); +} diff --git a/gcc/testsuite/g++.dg/template/func2.C b/gcc/testsuite/g++.dg/template/func2.C new file mode 100644 index 000000000..b0f691d24 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/func2.C @@ -0,0 +1,12 @@ +// { dg-do compile } + +typedef void (*fptr)(); +fptr zeroptr = 0; +template<typename T, fptr F> struct foo { }; +template<typename T> struct foo<T,zeroptr> { }; +// { dg-error "not a valid template argument" "not valid" { target *-*-* } 6 } +// { dg-error "must be the address" "must be the address " { target *-*-* } 6 } + +// The rest is needed to trigger the ICE in 4.0 to 4.3: +void f() { } +foo<int,&f> m_foo; diff --git a/gcc/testsuite/g++.dg/template/function1.C b/gcc/testsuite/g++.dg/template/function1.C new file mode 100644 index 000000000..bceed9d68 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/function1.C @@ -0,0 +1,28 @@ +// PR c++/38647 +// { dg-do compile } +// { dg-prune-output "note" } + +template<const char *, int> struct A {}; +const char func[] = "abc"; +template<int N> struct A<func, N> {}; // { dg-error "cannot appear|is invalid|not a valid|constant expression" } + +char a1[1]; +A<a1, 0> a; + +template<const char *, int> struct B {}; +template<int N> struct B<__FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid|is not a valid|constant expression" } + +char b1[1]; +B<b1, 0> b; + +template<const char *, int> struct C {}; +template<int N> struct C<__PRETTY_FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid|is not a valid|constant expression" } + +char c1[1]; +C<c1, 0> c; + +template<const char *, int> struct D {}; +template<int N> struct D<__func__, N> {}; // { dg-error "cannot appear|is invalid|is not a valid|function scope|constant expression" } + +char d1[1]; +D<d1, 0> d; diff --git a/gcc/testsuite/g++.dg/template/incomplete1.C b/gcc/testsuite/g++.dg/template/incomplete1.C new file mode 100644 index 000000000..e4997ef01 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete1.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: Ivan Godard <igodard at pacbell dot net> +// PR c++/17447: Detect parameters of dependent types even in templates + +struct B; // { dg-error "forward declaration" } +template<typename T> struct A { + + friend A& operator <<(A& a, B b) { return a; } // { dg-error "incomplete" } + friend A& operator <<(A& a, T b) { return a; } + + void foo1(B b) {} // { dg-error "incomplete" } + void foo1a(T b) {} + + B foo2(void) {} // { dg-error "incomplete" } + T foo2a(void) {} + + void foo3(B b); +}; diff --git a/gcc/testsuite/g++.dg/template/incomplete2.C b/gcc/testsuite/g++.dg/template/incomplete2.C new file mode 100644 index 000000000..d86ea06bc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete2.C @@ -0,0 +1,14 @@ +// PR c++/27427 +// { dg-do compile } + +struct A; + +template<A&> void foo(); // { dg-message "note" } + +A a; // { dg-error "incomplete type" } + +void bar() +{ + foo<a>(); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 12 } +} diff --git a/gcc/testsuite/g++.dg/template/incomplete3.C b/gcc/testsuite/g++.dg/template/incomplete3.C new file mode 100644 index 000000000..8a20bba74 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete3.C @@ -0,0 +1,5 @@ +// PR c++/27315 +// { dg-do compile } + +struct A; // { dg-error "forward declaration" } +template void A::foo<0>(); // { dg-error "before|incomplete" } diff --git a/gcc/testsuite/g++.dg/template/incomplete4.C b/gcc/testsuite/g++.dg/template/incomplete4.C new file mode 100644 index 000000000..f2832a73c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete4.C @@ -0,0 +1,16 @@ +// PR c++/33501 +// { dg-do compile } + +class A; // { dg-error "forward declaration" } + +template <typename T> struct X +{ + static int f (T); // { dg-error "initializing" } + static const T &make (); +}; + +int +main () +{ + return X<A>::f (X<A>::make ()); // { dg-error "invalid use of incomplete type" } +} diff --git a/gcc/testsuite/g++.dg/template/incomplete5.C b/gcc/testsuite/g++.dg/template/incomplete5.C new file mode 100644 index 000000000..f7802825f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete5.C @@ -0,0 +1,17 @@ +// PR c++/33501 +// { dg-do compile } + +class A; // { dg-error "forward declaration" } + +template <typename T> struct X +{ + static int f (T); // { dg-error "initializing" } + static const T &make (); + static const bool value = sizeof (f (make ())) == sizeof (int); // { dg-error "invalid use of incomplete type" } +}; + +int +main () +{ + return X <A>::value; +} diff --git a/gcc/testsuite/g++.dg/template/incomplete6.C b/gcc/testsuite/g++.dg/template/incomplete6.C new file mode 100644 index 000000000..7138b6a3b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete6.C @@ -0,0 +1,22 @@ +// PR c++/48115 + +template<typename> struct templ { }; + +template<typename T> T declval(); + +typedef int (*F2)(...); + +template<int> struct Int { }; + +template<typename F, typename T> +struct S +{ + template<typename A> + Int<sizeof( declval<F>()(T()) )> + f(A); +}; + +int main() +{ + S<F2, templ<int> >().f(0); +} diff --git a/gcc/testsuite/g++.dg/template/inherit.C b/gcc/testsuite/g++.dg/template/inherit.C new file mode 100644 index 000000000..43af3cfc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit.C @@ -0,0 +1,13 @@ +// Contributed by Gabriel Dos Reis <gdr@codesourcery.com> +// { dg-do compile } + +template<typename T> +struct X { void f() { } }; + +struct Z : X<int> { }; + +int main() +{ + Z z; + z.X::f(); +} diff --git a/gcc/testsuite/g++.dg/template/inherit2.C b/gcc/testsuite/g++.dg/template/inherit2.C new file mode 100644 index 000000000..4fd7ec063 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit2.C @@ -0,0 +1,19 @@ +// PR c++/5658 + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Theodore.Papadopoulo 11 Feb 2002 <Theodore.Papadopoulo@sophia.inria.fr> + +struct A { + typedef int iterator; +}; +template <typename T> +struct B: public A { + template <typename U> + struct iterator { + }; + B() { } +}; +int main() +{ + B<int> a; +} diff --git a/gcc/testsuite/g++.dg/template/inherit3.C b/gcc/testsuite/g++.dg/template/inherit3.C new file mode 100644 index 000000000..97b9e5b3e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit3.C @@ -0,0 +1,12 @@ +template <typename T> +struct set { + void insert (const T&); + template <class X> + void insert (X, X); +}; + +struct C : public set<int> { + void f (const int i) { + insert (i); + } +}; diff --git a/gcc/testsuite/g++.dg/template/inherit4.C b/gcc/testsuite/g++.dg/template/inherit4.C new file mode 100644 index 000000000..511c9e605 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit4.C @@ -0,0 +1,14 @@ +// PR c++/21008, DR 515 + +struct A { + int foo_; +}; +template <typename T> struct B: public A { }; +template <typename T> struct C: B<T> { + int foo() { + return A::foo_; // #1 + } +}; +int f(C<int>* p) { + return p->foo(); +} diff --git a/gcc/testsuite/g++.dg/template/inherit5.C b/gcc/testsuite/g++.dg/template/inherit5.C new file mode 100644 index 000000000..cd22f5b10 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit5.C @@ -0,0 +1,11 @@ +struct A +{ + template<int> void foo(); +}; + +template<int N> struct B : A +{ + B() { foo<N>(); } +}; + +B<0> b; diff --git a/gcc/testsuite/g++.dg/template/inherit6.C b/gcc/testsuite/g++.dg/template/inherit6.C new file mode 100644 index 000000000..241a68e5e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit6.C @@ -0,0 +1,23 @@ +// Origin PR c++/47172 +// { dg-options "-std=c++0x" } +// { dg-do compile } + +struct A +{ + int f() const; +}; + +template <class T> +struct B : A { }; + +template <class T> +struct C : B<T> +{ + void g(); +}; + +template <class T> +void C<T>::g() +{ + A::f(); +} diff --git a/gcc/testsuite/g++.dg/template/inherit7.C b/gcc/testsuite/g++.dg/template/inherit7.C new file mode 100644 index 000000000..67afbca6b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit7.C @@ -0,0 +1,21 @@ +// Origin: PR c++/48656 +// { dg-options "-std=c++0x" } +// { dg-do compile } + +struct A { + int f(); + int f(int); +}; + +template <typename> struct B : A +{ +}; + +template <typename T> struct C : B<T> +{ + void + g() + { + A::f(); + } +}; diff --git a/gcc/testsuite/g++.dg/template/init-list.C b/gcc/testsuite/g++.dg/template/init-list.C new file mode 100644 index 000000000..6a868b25e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init-list.C @@ -0,0 +1,17 @@ +// Contributed by Gabriel Dos Reis <gdr@codesourcery.com> +// { dg-do compile } + +template<typename T> +struct Base { + Base(int) { } +}; + +template<typename T> +struct Derived : Base<T> { + Derived(); +}; + +template<typename T> +Derived<T>::Derived() : Base(4) { } // { dg-error "have any field" "" } + + diff --git a/gcc/testsuite/g++.dg/template/init1.C b/gcc/testsuite/g++.dg/template/init1.C new file mode 100644 index 000000000..fdbff8d3c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init1.C @@ -0,0 +1,10 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/9457: ICE tsubst'ing initializers in templates. + +template <typename> void foo (int count) { + int i = {count}; +} +template void foo<int> (int); diff --git a/gcc/testsuite/g++.dg/template/init2.C b/gcc/testsuite/g++.dg/template/init2.C new file mode 100644 index 000000000..b81e4be94 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init2.C @@ -0,0 +1,10 @@ +// PR c++/9820 + +template <typename T> struct X { + template<typename> static int test(...); + template<typename> static int test(int *); + + static const int i = sizeof(X<T>::template test<int>(0)); +}; + +template class X<int>; diff --git a/gcc/testsuite/g++.dg/template/init3.C b/gcc/testsuite/g++.dg/template/init3.C new file mode 100644 index 000000000..9799a206d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init3.C @@ -0,0 +1,11 @@ +// PR c++/11027 + +template <class T> +struct X { + typedef void (X::*pfun)(); + static pfun p[]; +}; + +template <class T> +typename X<T>::pfun X<T>::p[] = {}; + diff --git a/gcc/testsuite/g++.dg/template/init4.C b/gcc/testsuite/g++.dg/template/init4.C new file mode 100644 index 000000000..78c7c3088 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init4.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Dec 2004 <nathan@codesourcery.com> + +// PR 18905. bogus error +// Origin: Andrew Pinski <pinskia@gcc.gnu.org> + +int f1(char); +template <int t> +void f(void) +{ + const char* const suffixes = "plpv"; + f1(suffixes[t]); +} diff --git a/gcc/testsuite/g++.dg/template/init5.C b/gcc/testsuite/g++.dg/template/init5.C new file mode 100644 index 000000000..ab529beb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init5.C @@ -0,0 +1,11 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 May 2005 <nathan@codesourcery.com> + +// PR 21165. ICE on valid +// Origin:Volker Reichelt reichelt@gcc.gnu.org + +template<typename T> bool foo() +{ + const int i = T(); + return i > 0; +} diff --git a/gcc/testsuite/g++.dg/template/init6.C b/gcc/testsuite/g++.dg/template/init6.C new file mode 100644 index 000000000..143746642 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init6.C @@ -0,0 +1,31 @@ +// PR c++/25836 + +template <class T> +class Iter {}; + +template <class T> +class SubIter : public Iter<T> { + void insert(T); +}; + +class GraphBase { +public: + class Node; +}; + +template<class T> +class Graph : public GraphBase { + class Inner { + Iter<typename Graph<T>::Node*> *get(); + }; +}; + +template<class T> +Iter<typename Graph<T>::Node*> *Graph<T>::Inner::get() { + SubIter<typename Graph<T>::Node*> *iter; + iter->insert(0); +} + +int main() { + Iter<Graph<int>::Node*> *n2_iter = new SubIter<Graph<int>::Node*>(); +} diff --git a/gcc/testsuite/g++.dg/template/init7.C b/gcc/testsuite/g++.dg/template/init7.C new file mode 100644 index 000000000..bb26c8f92 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init7.C @@ -0,0 +1,9 @@ +/* PR c++/31517. This used to ICE. */ +/* { dg-do compile } */ + +template<typename> struct A +{ + static const int i=0; +}; + +template<typename T> const int A<T>::i = 0=0; /* { dg-error "duplicate initialization" } */ diff --git a/gcc/testsuite/g++.dg/template/init8.C b/gcc/testsuite/g++.dg/template/init8.C new file mode 100644 index 000000000..1bcda1253 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/init8.C @@ -0,0 +1,68 @@ +// PR c++/36089 +// { dg-do run } + +extern "C" void abort (); + +int f () +{ + const int c(2); + int d[c] = { 0, 0 }; + return d[0] + sizeof d; +} + +struct A +{ + static int f () + { + const int c(2); + int d[c] = { 0, 0 }; + return d[0] + sizeof d; + } +}; + +template <int> struct B +{ + static int f () + { + const int c = 2; + int d[c] = { 0, 0 }; + return d[0] + sizeof d; + } +}; + +template <int> struct C +{ + static int f () + { + const int c(2); + int d[c] = { 0, 0 }; + return d[0] + sizeof d; + } +}; + +template <int> struct D +{ + static int f () + { + const int e(2); + const int c(e); + int d[c] = { 0, 0 }; + return d[0] + sizeof d; + } +}; + +int +main (void) +{ + int v = f (); + if (v != 2 * sizeof (int)) + abort (); + if (v != A::f ()) + abort (); + if (v != B<6>::f ()) + abort (); + if (v != C<0>::f ()) + abort (); + if (v != D<1>::f ()) + abort (); +} diff --git a/gcc/testsuite/g++.dg/template/injected1.C b/gcc/testsuite/g++.dg/template/injected1.C new file mode 100644 index 000000000..81873b498 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/injected1.C @@ -0,0 +1,33 @@ +// PR c++/13950, DR 176 + +template <class T> struct Base { }; // { dg-error "" } candidate + +struct D1: Base<void> +{ + D1::Base* p1; + D1::Base<double>* p2; + Base *p3; + Base<double>* p4; +}; + +struct D2: Base<void>, Base<void*> +{ + D2::Base* p1; // { dg-error "" } + D2::Base<double>* p2; + Base *p3; // { dg-error "" } + Base<double>* p4; +}; + +template <class T> +struct D3: Base<T> { + typename D3::Base* p1; + typename D3::template Base<double>* p2; +}; +template struct D3<void>; + +template <class T> +struct D4: Base<T>, Base<T*> { + typename D4::Base* p1; // { dg-error "" } + typename D4::template Base<double>* p2; +}; +template struct D4<void>; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/injected2.C b/gcc/testsuite/g++.dg/template/injected2.C new file mode 100644 index 000000000..bd09ccc35 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/injected2.C @@ -0,0 +1,9 @@ +// DR 1004 + +template <class T, template<class>class U = T::template B> struct A { }; + +template <class T> struct B { + template <class U> friend struct B; +}; + +A<B<int> > a; diff --git a/gcc/testsuite/g++.dg/template/inline1.C b/gcc/testsuite/g++.dg/template/inline1.C new file mode 100644 index 000000000..c7ae1f5ca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inline1.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-options "-fno-default-inline -O0" } +// { dg-final { scan-assembler-not "\n_?_ZN1X3FooIiEEvT_\[: \t\n\]" } } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Mar 2003 <nathan@codesourcery.com> + +// PR 10047. bogus warning. + +struct X +{ + template <typename T> static void Foo (T) {} +}; + +extern template void X::Foo<int> (int); // extern, so don't emit it + +int main () { + X::Foo (1); // ok, we've seen the defn +} + diff --git a/gcc/testsuite/g++.dg/template/instantiate1.C b/gcc/testsuite/g++.dg/template/instantiate1.C new file mode 100644 index 000000000..828f2e9c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate1.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// Origin: + +// PR c++/6716 +// ICE in complex class structure when components are incomplete + +template <class T> struct X { + T t; // { dg-error "incomplete" } +}; + +template <class T> struct Y { + X<T> x; // { dg-message "instantiated" } +}; + +template <class T> struct Z { // { dg-error "declaration" } + Y<Z<T> > y; // { dg-message "instantiated" } +}; + +struct ZZ : Z<int> +{ +}; diff --git a/gcc/testsuite/g++.dg/template/instantiate10.C b/gcc/testsuite/g++.dg/template/instantiate10.C new file mode 100644 index 000000000..678e0194a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate10.C @@ -0,0 +1,37 @@ +/* PR c++/39242, xplicit instantiation declaration prohibits implicit + instantiation of non-inline functions. */ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +class Rep { +public: + void unref() const { } + static void unref (const Rep * obj_r) { obj_r->unref(); } +}; +template<typename _Tp, typename _Bt = _Tp> +class RepPtrStore { + _Tp * _obj; + void _assign( _Tp * new_r ); +public: + ~RepPtrStore() { _assign( 0 ); } +}; +template<typename _Tp,typename _Bt> +void RepPtrStore<_Tp,_Bt>::_assign( _Tp * new_r ) +{ + Rep::unref( _obj ); +} +class RepPtrBase { }; +template<typename _Bt> class PtrBase : public RepPtrBase { }; +template<typename _Tp, typename _Bt = _Tp> +class Ptr : public PtrBase<_Bt> { + RepPtrStore<_Tp,_Bt> _ptr; +}; +class YCode; +class YStatement; +typedef Ptr<YStatement,YCode> YStatementPtr; +extern template class RepPtrStore<YStatement,YCode>; +class ExecutionEnvironment { + YStatementPtr m_statement; + ~ExecutionEnvironment() { }; +}; + diff --git a/gcc/testsuite/g++.dg/template/instantiate11.C b/gcc/testsuite/g++.dg/template/instantiate11.C new file mode 100644 index 000000000..3598d5890 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate11.C @@ -0,0 +1,25 @@ +// PR c++/42608 +// { dg-do compile } + +template <class U, class V> +struct A; + +template <class V> +struct A<int, V> +{ + void f (); +}; + +template struct A<int, int>; + +int +main () +{ + A<int, int> a; + a.f (); + return 0; +} + +// Make sure we get undefined reference error if +// A<int, int>::f () isn't instantiated elsewhere. +// { dg-final { scan-assembler-not "weak\[\n\t\]*_ZN1AIiiE1fEv" } } diff --git a/gcc/testsuite/g++.dg/template/instantiate2.C b/gcc/testsuite/g++.dg/template/instantiate2.C new file mode 100644 index 000000000..a6faf17ae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate2.C @@ -0,0 +1,8 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <wolfgang.bangerth@iwr.uni-heidelberg.de> + +// PR c++/2862 +// Default function argument and template instantiation. + +template <int dim> void f (int=0) {} +template void f<1> (); // { dg-error "not match" } diff --git a/gcc/testsuite/g++.dg/template/instantiate3.C b/gcc/testsuite/g++.dg/template/instantiate3.C new file mode 100644 index 000000000..de3d3a084 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate3.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// Origin: Scott Snyder <snyder@fnal.gov> + +// PR c++/7639 +// ICE when accessing member with incomplete type. + +class ACE_Null_Mutex; // { dg-error "forward declaration" } + +template <class TYPE> +struct ACE_Cleanup_Adapter +{ + TYPE &object () + { return object_; } // { dg-error "invalid" } + TYPE object_; // { dg-error "incomplete type" } +}; + +template class ACE_Cleanup_Adapter<ACE_Null_Mutex>; // { dg-message "instantiated from here" } diff --git a/gcc/testsuite/g++.dg/template/instantiate4.C b/gcc/testsuite/g++.dg/template/instantiate4.C new file mode 100644 index 000000000..732b8529d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate4.C @@ -0,0 +1,13 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/10682: Typedef to enum template instantiation logic. + +template <typename T> +struct Foo { + enum E {a,b,c}; + typedef E EE; +}; + +void Baz(Foo<int>::EE x); diff --git a/gcc/testsuite/g++.dg/template/instantiate5.C b/gcc/testsuite/g++.dg/template/instantiate5.C new file mode 100644 index 000000000..e592c65d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate5.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/11616: Incorrect line number in diagnostics + +template <int> struct A +{ + static const int i=0; +}; + +int baz() { return A<0>::i; } + +struct B +{ + static void foo (int); // { dg-message "B::foo|candidate expects" } +}; + +template <typename T> struct C +{ + virtual void bar() const { T::foo(); } // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 21 } +}; + +C<B> c; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/instantiate6.C b/gcc/testsuite/g++.dg/template/instantiate6.C new file mode 100644 index 000000000..d5d712ee0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate6.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Origin: gianni@mariani.ws +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/13289: ICE recursively instantiate static member data. + +template <int N> struct S { + static const int C; +}; + +template <int N> +const int S<N>::C = S<(N+1)%2>::C; + +template struct S<1>; + diff --git a/gcc/testsuite/g++.dg/template/instantiate7.C b/gcc/testsuite/g++.dg/template/instantiate7.C new file mode 100644 index 000000000..2e54106ff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate7.C @@ -0,0 +1,10 @@ +// PR c++/19498 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// { dg-do compile } + +template<typename T> struct A +{ + template<T&> struct B; // { dg-error "reference to void" } +}; + +A<void> a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/instantiate8.C b/gcc/testsuite/g++.dg/template/instantiate8.C new file mode 100644 index 000000000..9004a86d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate8.C @@ -0,0 +1,17 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 18 Aug 2005 <nathan@codesourcery.com> + +// PR 22044: ICE +// Origin: Andrew Pinski <pinskia@gcc.gnu.org> + +struct no_context { + template< class Event > void no_function( const Event & ); +}; +template< class Event, class TransitionContext = no_context, +void ( TransitionContext::*pTransitionAction )( const Event & ) = &no_context::no_function< Event > > +struct transition +{ + struct EvFlipBit {}; + typedef transition<EvFlipBit> type; +}; + diff --git a/gcc/testsuite/g++.dg/template/instantiate9.C b/gcc/testsuite/g++.dg/template/instantiate9.C new file mode 100644 index 000000000..33f1d6018 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/instantiate9.C @@ -0,0 +1,15 @@ +/* PR c++/14622. The invalid explicit instantiation was not reported. */ +/* { dg-do compile } */ +template<class T> +class A +{ + static T a; +}; + +template<class T> +T A<T>::a; + +struct B {}; + +template B A<int>::a; /* { dg-error "does not match declared type" } */ +template float A<float>::a; diff --git a/gcc/testsuite/g++.dg/template/invalid1.C b/gcc/testsuite/g++.dg/template/invalid1.C new file mode 100644 index 000000000..d2fcca6d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/invalid1.C @@ -0,0 +1,8 @@ +// PR c++/14883 +// { dg-options "-std=gnu++98" } + +template < class T > struct DomainTraits {}; +template < int Dim > class Interval; +template < class DT > class Domain {}; +template <> class Interval < 1 >:public Domain < DomainTraits < Interval < 1 > +>> {}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/koenig1.C b/gcc/testsuite/g++.dg/template/koenig1.C new file mode 100644 index 000000000..850d38828 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig1.C @@ -0,0 +1,8 @@ +namespace NS { + struct C {}; + void foo(C); +} + +template <class T> void bar() { T t; foo (t); } + +template void bar<NS::C> (); diff --git a/gcc/testsuite/g++.dg/template/koenig2.C b/gcc/testsuite/g++.dg/template/koenig2.C new file mode 100644 index 000000000..be072a4a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig2.C @@ -0,0 +1,25 @@ +namespace nsp_foo { + + struct A {}; + + struct foo {}; + +} + +namespace nsp_bar { + + void foo(nsp_foo::A) {} + + template <class T> + void bar(T t) + { + nsp_bar::foo(t); // line 16 + } + +} + +int main() +{ + nsp_bar::bar(nsp_foo::A()); +} + diff --git a/gcc/testsuite/g++.dg/template/koenig3.C b/gcc/testsuite/g++.dg/template/koenig3.C new file mode 100644 index 000000000..f90059d65 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig3.C @@ -0,0 +1,28 @@ +// PR c++/13157 + +namespace aa +{ + double abs(double); + long double abs(long double); +} + +namespace fu +{ + template <class T> + struct X + {}; + + template <class T> + X<T> test(X<T> x) + { + using ::aa::abs; + return abs(x); + } + + template <class T> + X<T> abs(X<T>); + + X<int> x; + X<int> z = test(x); +} + diff --git a/gcc/testsuite/g++.dg/template/koenig4.C b/gcc/testsuite/g++.dg/template/koenig4.C new file mode 100644 index 000000000..31e41fcf9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig4.C @@ -0,0 +1,12 @@ +// PR c++/13978 + +namespace ns { + template <class TP> void func1(TP* t); + struct A {}; +} + +template < class TP > +void func2() { + func1( new ns::A() ); +} + diff --git a/gcc/testsuite/g++.dg/template/koenig5.C b/gcc/testsuite/g++.dg/template/koenig5.C new file mode 100644 index 000000000..d54bb7543 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig5.C @@ -0,0 +1,32 @@ +// { dg-do compile } +// Contributed by David Abrahams <dave at boost-consulting dot com> +// PR c++/14143: Koenig lookup should only look into template arguments only +// if the argument is a template-id. + +namespace fu +{ + template <class T> + struct bar + { + struct baz {}; + }; +} + +namespace axe +{ + struct handle {}; + + template <class T> + char* f(T&); +} + +namespace test +{ + template <class T> + int f(T const&); + + template <class T> + int g(T x) { return f(x); } + + int x = g(fu::bar<axe::handle>::baz()); +} diff --git a/gcc/testsuite/g++.dg/template/koenig6.C b/gcc/testsuite/g++.dg/template/koenig6.C new file mode 100644 index 000000000..8f93a653a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig6.C @@ -0,0 +1,29 @@ +// PR c++/38850 + +template <typename VType> +class Vector2 { + private: + VType c_[2]; + public: + typedef Vector2<VType> Self; + + Vector2(const VType x, const VType y) { + c_[0] = x; + c_[1] = y; + } + + friend inline Self Max(const Self &v1, const Self &v2) { + return Self(v1.c_[0], v1.c_[1]); + } +}; + +template <class T> +Vector2<float> foo(T x) { + Vector2<float> y(0,0); + return Max(y, y); +} + +int main() { + foo(3); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/koenig7.C b/gcc/testsuite/g++.dg/template/koenig7.C new file mode 100644 index 000000000..07f2fcad3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig7.C @@ -0,0 +1,11 @@ +// PR c++/13549 +// We need to do arg-dep lookup for g<T>(j) at instantiation time because +// g<T> is dependent, even though (j) is not; at that point we can find +// g(h). + +template <typename T> int g(int); +class h{}; +template <typename T> int l(){h j; return g<T>(j);} +template <typename T> int g(const h&); +class j{}; +int jj(){return l<j>();} diff --git a/gcc/testsuite/g++.dg/template/koenig8.C b/gcc/testsuite/g++.dg/template/koenig8.C new file mode 100644 index 000000000..5a49a7066 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig8.C @@ -0,0 +1,20 @@ +// PR c++/40740 + +template<class T> +T addsome(T v) { + return v+1; +} + +int addsome(int v) { + return v+2; +} + +int main() { + int i = 0; + if (addsome(i) != 2) + return 1; + if (addsome<>(i) != 1) + return 2; + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/local1.C b/gcc/testsuite/g++.dg/template/local1.C new file mode 100644 index 000000000..4293aca24 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local1.C @@ -0,0 +1,25 @@ +// PR c++/4286: We were crashing when trying to set up the class bindings in +// g(), because xref wanted the mangled name, which breaks inside a template. + +// Of course, the offending code is actually ill-formed anyway, so check +// for the error. Also check that it's formatted properly. + +struct A +{ + template<class T> void f(); +}; + +template<class T> void A::f() +{ + struct B + { + void g() {} + static int x; // { dg-error "static.*int A::f\\(\\)::B::x" "" } + }; +} + +int main () +{ + A a; + a.f<int> (); +} diff --git a/gcc/testsuite/g++.dg/template/local2.C b/gcc/testsuite/g++.dg/template/local2.C new file mode 100644 index 000000000..51c946a5a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local2.C @@ -0,0 +1,61 @@ +template<typename T> +struct X { + double & f (const unsigned int i, + const unsigned int j); + void g (X &M); +}; + +template <typename T> +void X<T>::g (X &x) { + double t14 = x.f(0,0)*x.f(1,1); + double t15 = x.f(2,2)*x.f(3,3); + double t17 = x.f(2,3)*x.f(3,2); + double t19 = x.f(0,0)*x.f(2,1); + double t20 = x.f(1,2)*x.f(3,3); + double t22 = x.f(1,3)*x.f(3,2); + double t24 = x.f(0,0)*x.f(3,1); + double t25 = x.f(1,2)*x.f(2,3); + double t27 = x.f(1,3)*x.f(2,2); + double t29 = x.f(1,0)*x.f(0,1); + double t32 = x.f(1,0)*x.f(2,1); + double t33 = x.f(0,2)*x.f(3,3); + double t35 = x.f(0,3)*x.f(3,2); + double t37 = x.f(1,0)*x.f(3,1); + double t38 = x.f(0,2)*x.f(2,3); + double t40 = x.f(0,3)*x.f(2,2); + double t42 = t14*t15-t14*t17-t19*t20+t19*t22+ + t24*t25-t24*t27-t29*t15+t29*t17+ + t32*t33-t32*t35-t37*t38+t37*t40; + double t43 = x.f(2,0)*x.f(0,1); + double t46 = x.f(2,0)*x.f(1,1); + double t49 = x.f(2,0)*x.f(3,1); + double t50 = x.f(0,2)*x.f(1,3); + double t52 = x.f(0,3)*x.f(1,2); + double t54 = x.f(3,0)*x.f(0,1); + double t57 = x.f(3,0)*x.f(1,1); + double t60 = x.f(3,0)*x.f(2,1); + double t63 = t43*t20-t43*t22-t46*t33+t46*t35+ + t49*t50-t49*t52-t54*t25+t54*t27+ + t57*t38-t57*t40-t60*t50+t60*t52; + double t65 = 1/(t42+t63); + double t71 = x.f(0,2)*x.f(2,1); + double t73 = x.f(0,3)*x.f(2,1); + double t75 = x.f(0,2)*x.f(3,1); + double t77 = x.f(0,3)*x.f(3,1); + double t81 = x.f(0,1)*x.f(1,2); + double t83 = x.f(0,1)*x.f(1,3); + double t85 = x.f(0,2)*x.f(1,1); + double t87 = x.f(0,3)*x.f(1,1); + double t101 = x.f(1,0)*x.f(2,2); + double t103 = x.f(1,0)*x.f(2,3); + double t105 = x.f(2,0)*x.f(1,2); + double t107 = x.f(2,0)*x.f(1,3); + double t109 = x.f(3,0)*x.f(1,2); + double t111 = x.f(3,0)*x.f(1,3); + double t115 = x.f(0,0)*x.f(2,2); + double t117 = x.f(0,0)*x.f(2,3); + double t119 = x.f(2,0)*x.f(0,2); + double t121 = x.f(2,0)*x.f(0,3); +} + +template void X<double>::g (X<double>&); diff --git a/gcc/testsuite/g++.dg/template/local3.C b/gcc/testsuite/g++.dg/template/local3.C new file mode 100644 index 000000000..5a01a4495 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local3.C @@ -0,0 +1,14 @@ + template<class T> + void f(const T&) + { + struct B { + + void g (T); + }; + B b; + } + void g() + { + f(42); + } + diff --git a/gcc/testsuite/g++.dg/template/local4.C b/gcc/testsuite/g++.dg/template/local4.C new file mode 100644 index 000000000..9a03c9a7b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local4.C @@ -0,0 +1,10 @@ +// PR c++/17413 +// { dg-options -std=c++98 } + +template <typename T> void foo() {} // { dg-message "note" } + +int main () { + struct S {}; + foo<S> (); // { dg-error "match" } + // { dg-message "candidate" "candidate note" { target *-*-* } 8 } +} diff --git a/gcc/testsuite/g++.dg/template/local5.C b/gcc/testsuite/g++.dg/template/local5.C new file mode 100644 index 000000000..705dca39e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local5.C @@ -0,0 +1,12 @@ +struct Attribute { }; + +template <class T> bool operator == (const Attribute &attr, const T &value); + +enum { + anon = 123 +}; + +void test(int foo) +{ + if (foo == anon) ; /* { dg-bogus "anonymous type" } */ +} diff --git a/gcc/testsuite/g++.dg/template/local6.C b/gcc/testsuite/g++.dg/template/local6.C new file mode 100644 index 000000000..4a87177c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local6.C @@ -0,0 +1,20 @@ +template <class T> struct PCVector2 // { dg-message "note" } +{ + template <class T2> PCVector2(const PCVector2<T> &cv) ; // { dg-message "note" } + + PCVector2<T> operator- (const PCVector2<T> &ov) const + { + return PCVector2<T>(ov.xFIELD, ov.yFIELD); // { dg-error "matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 7 } + } + + T xFIELD, yFIELD; +}; + +void findIntersection( PCVector2<double>& p0, PCVector2<double>& p1); + + +void findIntersection( PCVector2<double>& p0, PCVector2<double>& p1) +{ + PCVector2<double> e = p1 - p0; // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/lookup1.C b/gcc/testsuite/g++.dg/template/lookup1.C new file mode 100644 index 000000000..0df77bac1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup1.C @@ -0,0 +1,17 @@ +template <class T0> +class A { +public: + class B; +}; + +template <class T0> +class A<T0>::B { +public: + class C; +}; + +template <class T0> +class A<T0>::B::C { +public: + A<T0> &a; +}; diff --git a/gcc/testsuite/g++.dg/template/lookup2.C b/gcc/testsuite/g++.dg/template/lookup2.C new file mode 100644 index 000000000..15ab35268 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup2.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 27 Mar 2003 <nathan@codesourcery.com> + +// PR 11617: Failed to diagnose missing function. + +struct B {}; + +template <typename T> void Bar () +{ + T::foo (); // { dg-error "is not a member of" "" } +} + +void Foo () +{ + Bar<B> (); // { dg-message "instantiated" "" } +} diff --git a/gcc/testsuite/g++.dg/template/lookup3.C b/gcc/testsuite/g++.dg/template/lookup3.C new file mode 100644 index 000000000..c96a0b0b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup3.C @@ -0,0 +1,16 @@ +// PR c++/12397 + +struct foo { }; + +template <typename T> struct bar +{ + bar(){} + int i; + bar (const bar<T>& foo) : i (foo.i) {} +}; + +int main() +{ + bar<int> b1; + bar<int> b2(b1); +} diff --git a/gcc/testsuite/g++.dg/template/lookup4.C b/gcc/testsuite/g++.dg/template/lookup4.C new file mode 100644 index 000000000..3bd73a34e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup4.C @@ -0,0 +1,6 @@ +// PR c++/13950 + +template <class T> struct Base {}; +template <class T> struct Derived: public Base<T> { + typename Derived::template Base<double>* p1; +}; diff --git a/gcc/testsuite/g++.dg/template/lookup5.C b/gcc/testsuite/g++.dg/template/lookup5.C new file mode 100644 index 000000000..022202a71 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup5.C @@ -0,0 +1,17 @@ +// PR c++/13925 + +namespace N { + template <class T> void f(T); + + namespace M { + class A { + friend void f<int>(int); + }; + } + + template <class T> void f(T) {} + template <> void f<int>(int ) + { + f<long>(0); + } +} diff --git a/gcc/testsuite/g++.dg/template/lookup6.C b/gcc/testsuite/g++.dg/template/lookup6.C new file mode 100644 index 000000000..2ca6dcc75 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup6.C @@ -0,0 +1,11 @@ +struct S +{ + template<typename T> static void g(); +}; + +template<typename T> +void f() { return S::template g<T>(); } + +void g() { + f<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/lookup7.C b/gcc/testsuite/g++.dg/template/lookup7.C new file mode 100644 index 000000000..0e05c5f75 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup7.C @@ -0,0 +1,9 @@ +class S; + +template<class T> +int f(T, S); + +class S { + template<class T> + friend int f(T t, S) { t; return 0; } +}; diff --git a/gcc/testsuite/g++.dg/template/lookup8.C b/gcc/testsuite/g++.dg/template/lookup8.C new file mode 100644 index 000000000..981c283e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup8.C @@ -0,0 +1,19 @@ +// PR c++/38030 +// The call to f should be resolved at template definition time. +// { dg-do link } + +struct B { }; +struct D : public B { }; +D d; +void f (B &) { } +template < class T > +void g () +{ + return f (d); +} +void f (D &); +int main () +{ + g<int> (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/lvalue1.C b/gcc/testsuite/g++.dg/template/lvalue1.C new file mode 100644 index 000000000..9def2a18c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lvalue1.C @@ -0,0 +1,31 @@ +// PR c++/38877 + +template<class _T1, class _T2> +struct pair +{ + typedef _T1 first_type; + typedef _T2 second_type; + _T1 first; + _T2 second; + pair () : first(), second() { } + pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } +}; + +template<class _T1, class _T2> +inline pair<_T1, _T2> +make_pair(_T1 __x, _T2 __y) +{ + return pair<_T1, _T2>(__x, __y); +} + +template <int dim> class bar; + +template <int dim> +pair<bar<dim> *, unsigned int> +foo (unsigned int position) +{ + const pair<int,unsigned int> tmp; + return make_pair (new bar<dim>(tmp.first), + position); + } diff --git a/gcc/testsuite/g++.dg/template/mangle1.C b/gcc/testsuite/g++.dg/template/mangle1.C new file mode 100644 index 000000000..96d064723 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mangle1.C @@ -0,0 +1,16 @@ +// PR c++/17324 +// { dg-do assemble } + +template<int, typename T> struct A +{ + template<int I> void foo(const A<I,T>&) {} +}; + +template<typename> struct B +{ + template<int J> void bar(const A<J,B>&); + void baz() { A<0,B>().foo(A<0,B>()); } +}; + +template struct B<void>; +template struct B<int>; diff --git a/gcc/testsuite/g++.dg/template/mem-partial1.C b/gcc/testsuite/g++.dg/template/mem-partial1.C new file mode 100644 index 000000000..60cb36aea --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mem-partial1.C @@ -0,0 +1,15 @@ +// PR c++/14032 + +template <typename T> struct outer { + template <typename T2, typename U> + struct inner { + static int f() { return inner<T,int>::N; }; + }; + + template <typename U> + struct inner<T,U> { + static const int N = 1; + }; +}; + +int i = outer<int>::inner<double,int>::f(); diff --git a/gcc/testsuite/g++.dg/template/mem-partial2.C b/gcc/testsuite/g++.dg/template/mem-partial2.C new file mode 100644 index 000000000..fba325519 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mem-partial2.C @@ -0,0 +1,29 @@ +// PR c++/14032 +// { dg-do run } + +template <bool compare> +struct outer +{ + template <bool compare_with,bool second> + struct inner // unspecialized compare != compare_with + { + static inline bool test() + { + return false; + } + }; + template <bool second> // specialization compare == compare_with + struct inner<compare,second> + { + static inline bool test() + { + return true; + } + }; +}; +int main () +{ + bool b = outer<true>::inner<true,false>::test(); + + return b != true; +} diff --git a/gcc/testsuite/g++.dg/template/mem-partial3.C b/gcc/testsuite/g++.dg/template/mem-partial3.C new file mode 100644 index 000000000..bea6cd396 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mem-partial3.C @@ -0,0 +1,29 @@ +// PR c++/33342 + +template <bool B, class T = void> +struct enable_if_c { + typedef T type; +}; + +template <class T> +struct A +{ + template <class U, class V> + struct B; + + template <class U> + struct B<U, typename enable_if_c<U::sub::value==0>::type> + { }; +}; + +struct C +{ + struct sub + { + static const int value = 0; + }; +}; + + +A<int> a; +A<int>::B<C, void> b; diff --git a/gcc/testsuite/g++.dg/template/mem_func_ptr.C b/gcc/testsuite/g++.dg/template/mem_func_ptr.C new file mode 100644 index 000000000..7d912e2ad --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mem_func_ptr.C @@ -0,0 +1,57 @@ +// { dg-do compile } +template<typename T> struct takes_member_ptr; +template<typename T, typename Klasse> struct takes_member_ptr<T Klasse::*> {}; + +template<typename T, typename Klasse> +void fun_takes_member_ptr(T Klasse::*) {} + + +template<typename T> struct order_member_ptrs; +template<typename T, typename Klasse> struct order_member_ptrs<T Klasse::*> {}; +template<typename R, typename T1, typename Klasse> + struct order_member_ptrs<R (Klasse::*)(T1)> + { + typedef int type; + }; + +template<typename R, typename T1, typename Klasse> + struct order_member_ptrs<R (Klasse::*)(T1) const> + { + typedef int c_type; + }; + +template<typename R, typename T1, typename Klasse> + struct order_member_ptrs<R (Klasse::*)(T1) volatile> + { + typedef int v_type; + }; + +template<typename R, typename T1, typename Klasse> + struct order_member_ptrs<R (Klasse::*)(T1) const volatile> + { + typedef int cv_type; + }; + + +struct X { + void bar(float) {} + void bar_c(float) const {} + void bar_v(float) volatile {} + void bar_cv(float) const volatile {} +}; + +void foo() +{ + sizeof(takes_member_ptr<void (X::*)(float)>); + sizeof(takes_member_ptr<void (X::*)(float) const>); + sizeof(takes_member_ptr<void (X::*)(float) volatile>); + sizeof(takes_member_ptr<void (X::*)(float) const volatile>); + sizeof(order_member_ptrs<void (X::*)(float)>::type); + sizeof(order_member_ptrs<void (X::*)(float) const>::c_type); + sizeof(order_member_ptrs<void (X::*)(float) volatile>::v_type); + sizeof(order_member_ptrs<void (X::*)(float) const volatile>::cv_type); + fun_takes_member_ptr(&X::bar); + fun_takes_member_ptr(&X::bar_c); + fun_takes_member_ptr(&X::bar_v); + fun_takes_member_ptr(&X::bar_cv); +} diff --git a/gcc/testsuite/g++.dg/template/member.C b/gcc/testsuite/g++.dg/template/member.C new file mode 100644 index 000000000..69228334f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member.C @@ -0,0 +1,28 @@ +// { dg-do compile } + + +class BIXSet{ +int z[4]; +public: +void f(BIXSet &other){ +z[0]=other.z[0]; +} + +}; + +class TestCase2{ +public: +BIXSet a,b; + +public: +void run(void){ +BIXSet x,y; +process(0,x,y); +} + +protected: +template<class BS> void process(const int d,BS &en,BS &lb){ +a.f(en);b.f(lb); +} + +}; diff --git a/gcc/testsuite/g++.dg/template/member2.C b/gcc/testsuite/g++.dg/template/member2.C new file mode 100644 index 000000000..372c778a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member2.C @@ -0,0 +1,13 @@ +// PR c++/8660 +// Bug: we were treating the definition of the non-template as a definition +// of the template, which broke. + +struct BadgerBuf +{ + void ReadPod(); + template<class B> + void ReadPod(); +}; + +void BadgerBuf::ReadPod () + { ReadPod<int> (); } diff --git a/gcc/testsuite/g++.dg/template/member3.C b/gcc/testsuite/g++.dg/template/member3.C new file mode 100644 index 000000000..4f87e57bc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member3.C @@ -0,0 +1,19 @@ +template<typename T> +struct A { + template<typename L> struct SubA { }; + + template<typename T1,typename L> void f(T1 & t1, SubA<L> & t2) { } + template<typename U> void g(SubA<U> & suba) { } + template<typename U> void h(SubA<U> & suba) { } +}; + +int main(void) { + int i; + A<int> a; + A<int>::SubA<int> suba; + + a.f(i,suba); + a.g(suba); + a.h(suba); +} + diff --git a/gcc/testsuite/g++.dg/template/member4.C b/gcc/testsuite/g++.dg/template/member4.C new file mode 100644 index 000000000..290fbb566 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member4.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// Contributed by Matty T. <mattyt-bugzilla at tpg dot com dot au> +// PR c++/13813 [DR206]: Check semantic constraints of members of +// non-dependent type at instantiation time. + + +// DR206 explains that this is ill-formed, no diagnostic required. We emit +// a diagnostic instead. +class E; +template < class A > class Z { + A a; + E e; // { dg-error "incomplete type" } +}; + + +// Nested classes are always dependent names. +template < class A > class Y { + class F; + F e; // { dg-bogus "" "nested classes are always dependent, see DR108 and DR224" } +}; diff --git a/gcc/testsuite/g++.dg/template/member5.C b/gcc/testsuite/g++.dg/template/member5.C new file mode 100644 index 000000000..ba6a9705b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member5.C @@ -0,0 +1,33 @@ +// { dg-do compile } +// Contributed by: <fasbjx at free dot fr> +// PR c++/14389: Disambiguate overloaded member templates which differ only +// in the template argument list. + +namespace N1 { + +struct S { + template< typename B, typename A > void foo(); + template< typename A > void foo(); +}; + +template< typename A > void S::foo() {} +template< typename B, typename A > void S::foo() {} + +template void S::foo<void> (); +template void S::foo<void,void> (); + +} + +namespace N2 { + +struct S { + template< typename _A > void foo(); + template< int _i > void foo(); +}; + +template< typename _A > void S::foo() {} + +template void S::foo< 0 >(); // { dg-error "no definition available" "no def" } + // { dg-message "instantiated" "instantiated" { target *-*-* } 30 } + +} diff --git a/gcc/testsuite/g++.dg/template/member6.C b/gcc/testsuite/g++.dg/template/member6.C new file mode 100644 index 000000000..7d66e7bda --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member6.C @@ -0,0 +1,16 @@ +// PR c++/29105 + +struct Observer +{ + template < typename T > void observeComponent (); +}; + +template < typename T > +struct TagFilter : Observer +{ + TagFilter () + { + observeComponent < int > (); + } +}; + diff --git a/gcc/testsuite/g++.dg/template/member7.C b/gcc/testsuite/g++.dg/template/member7.C new file mode 100644 index 000000000..1c75e4956 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member7.C @@ -0,0 +1,15 @@ +// PR c++/29080 + +struct Base { + template<class C> void method() { } +}; + +struct Left : public Base { }; +struct Right : public Base { }; +struct Join : public Left, public Right { }; + +void function() +{ + Join join; + join.Left::method<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/member8.C b/gcc/testsuite/g++.dg/template/member8.C new file mode 100644 index 000000000..074c65543 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member8.C @@ -0,0 +1,25 @@ +// PR c++/35138 +// { dg-do compile } + +namespace N1 { struct A { }; } +namespace N2 { struct A { }; } +using namespace N1; +using namespace N2; + +template <typename T> int +foo (T const &t) +{ + return t.A; +} + +struct B +{ + int A; +}; + +int +main () +{ + B b; + foo (b); +} diff --git a/gcc/testsuite/g++.dg/template/member9.C b/gcc/testsuite/g++.dg/template/member9.C new file mode 100644 index 000000000..f15272db7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member9.C @@ -0,0 +1,21 @@ +// Origin PR c++/48838 +// { dg-do compile } + +class DUChainItemSystem +{ +public: + + template<class T> + void registerTypeClass(); + + static DUChainItemSystem& self(); +}; + +template<class T> +struct DUChainItemRegistrator +{ + DUChainItemRegistrator() + { + DUChainItemSystem::self().registerTypeClass<T>(); + } +}; diff --git a/gcc/testsuite/g++.dg/template/memclass1.C b/gcc/testsuite/g++.dg/template/memclass1.C new file mode 100644 index 000000000..c49ed724d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memclass1.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> + +// PR c++/10555: ICE for member class template when one of the +// template argument levels contains errors. + +template <typename> struct A +{ + template <typename> struct B; +}; + +template <typename T> struct C +{ + typedef typename A<T>::template B<U> X; // { dg-error "declared|invalid" } +}; + +C<void> c; diff --git a/gcc/testsuite/g++.dg/template/memclass2.C b/gcc/testsuite/g++.dg/template/memclass2.C new file mode 100644 index 000000000..da79d6afe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memclass2.C @@ -0,0 +1,20 @@ +namespace ns { + template<typename T> + struct Foo { + template<typename U> struct Bar; + }; + + template<typename T> + template<typename U> + struct Foo<T>::Bar { + template<typename V> struct Baz; + }; + + template<typename T> + template<typename U> + template<typename V> + struct Foo<T>::Bar<U>::Baz { + Foo<T> chokes; + ns::Foo<T> works; + }; +} diff --git a/gcc/testsuite/g++.dg/template/memclass3.C b/gcc/testsuite/g++.dg/template/memclass3.C new file mode 100644 index 000000000..8230b94e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memclass3.C @@ -0,0 +1,39 @@ +// PR c++/17132 + +template <typename T> +struct has_deref +{ + struct impl + { + template < + typename Type, + typename Type::reference (Type::*Func)(void) const> + struct func_tag; + + template <typename Type> + static char (& test( + Type *, + func_tag<Type, &Type::operator*> * = 0 + ))[2]; + static char test(void *); + }; + + static const bool value = (sizeof(impl::test((T *) 0)) == 2); +}; + +template <typename T> +struct container +{ + struct iterator + { + typedef T & reference; + reference operator*() const; + }; +}; + +int main() +{ + typedef container<int>::iterator iter; + int result = has_deref<iter>::value; + return result; +} diff --git a/gcc/testsuite/g++.dg/template/memclass4.C b/gcc/testsuite/g++.dg/template/memclass4.C new file mode 100644 index 000000000..65a42a4c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memclass4.C @@ -0,0 +1,70 @@ +// Origin: PR c++/42824 +// { dg-do compile } + +template<int T> +class int_ { +}; + +template<int T, int T2> +class Unit { +public: + Unit(const Unit<T, T2>& other) {} +}; + +template<int T> +class Quan { +public: + Quan(void) {} + + template<int T2> + Quan(double value, Unit<T, T2> unit) {} +}; +typedef Quan<0> Scalar; + +template<int T> +class hlp { +public: + typedef Quan<T> type; +}; + +class Mtrl { +public: + template<int T> + struct AssoType { + typedef typename hlp<T>::type type; + }; +}; + +template<class T> +class Eval { +public: + Eval(const T& object){} + + template<int V> + void eval() { + eval<V> (int_<0>()); + } +private: + template<typename U> struct Wrap {}; + + template<int V, int V2> + void value(Wrap<Quan<V2> >) {} + + template<int V> + void value(Wrap<Scalar>) {} + + template<int V> + void eval(int_<0>) { + typedef typename T::template AssoType<V>::type Type; + value<V>(Wrap<Type>()); + } +}; + +class Foo { +public: + static void eval(const Mtrl& mtrl) { + Eval<Mtrl> h(mtrl); + h.eval<0> (); + } +}; + diff --git a/gcc/testsuite/g++.dg/template/memfriend1.C b/gcc/testsuite/g++.dg/template/memfriend1.C new file mode 100644 index 000000000..f4541279c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend1.C @@ -0,0 +1,54 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member function of class template as friend + +template<class T> struct A +{ + void f(); +}; + +class C { + int i; + template<class T> friend void A<T>::f(); +}; + +template<class T> struct A<T*> +{ + void f(); +}; + +template<> struct A<char> +{ + void f(); +}; + +template<class T> void A<T>::f() +{ + C c; + c.i = 0; +} + +template<class T> void A<T*>::f() +{ + C c; + c.i = 0; +} + +void A<char>::f() +{ + C c; + c.i = 0; +} + +int main() +{ + A<int> a1; + a1.f(); + A<int *> a2; + a2.f(); + A<char> a3; + a3.f(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend10.C b/gcc/testsuite/g++.dg/template/memfriend10.C new file mode 100644 index 000000000..4fe760af2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend10.C @@ -0,0 +1,71 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class template of class template as friend + +template <class T> struct A +{ + template <class U> struct B + { + void f(); + }; +}; + +class C { + int i; + template <class T> template <class U> friend struct A<T>::B; +}; + +template <class T> struct A<T*> +{ + template <class U> struct B + { + void f(); + }; +}; + +template <> struct A<char> +{ + template <class U> struct B + { + void f(); + }; +}; + +template <class T> template <class U> void A<T>::B<U>::f() +{ + C c; + c.i = 0; +} + +template <class T> template <class U> void A<T*>::B<U>::f() +{ + C c; + c.i = 0; +} + +template <class U> void A<char>::B<U>::f() +{ + C c; + c.i = 0; +} + +template <> void A<char>::B<int>::f() +{ + C c; + c.i = 0; +} + +int main() +{ + A<int>::B<int> b1; + b1.f(); + A<int *>::B<int> b2; + b2.f(); + A<char>::B<char> b3; + b3.f(); + A<char>::B<int> b4; + b4.f(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend11.C b/gcc/testsuite/g++.dg/template/memfriend11.C new file mode 100644 index 000000000..e33e99bdc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend11.C @@ -0,0 +1,73 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class template of class template as friend + +template<class T> struct A +{ + template <T t> struct B + { + void f(); + }; +}; + +class C { + int i; + template<class T> template <T t> friend struct A<T>::B; +}; + +template<class T> struct A<T*> +{ + template <T* t> struct B + { + void f(); + }; +}; + +template<> struct A<char> +{ + template <char t> struct B + { + void f(); + }; +}; + +template<class T> template <T t> void A<T>::B<t>::f() +{ + C c; + c.i = 0; +} + +template<class T> template <T* t> void A<T*>::B<t>::f() +{ + C c; + c.i = 0; +} + +template <char t> void A<char>::B<t>::f() +{ + C c; + c.i = 0; +} + +template <> void A<char>::B<'b'>::f() +{ + C c; + c.i = 0; +} + +int d2 = 0; + +int main() +{ + A<int>::B<0> b1; + b1.f(); + A<int *>::B<&d2> b2; + b2.f(); + A<char>::B<'a'> b3; + b3.f(); + A<char>::B<'b'> b4; + b4.f(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend12.C b/gcc/testsuite/g++.dg/template/memfriend12.C new file mode 100644 index 000000000..77f821400 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend12.C @@ -0,0 +1,63 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class of class template as friend + +template<class T> struct A +{ + struct B + { + void f(); + }; +}; + +template <class U> class C { + int i; + template<class T> friend struct A<T>::B; +}; + +template<class T> struct A<T*> +{ + struct B + { + void f(); + }; +}; + +template<> struct A<char> +{ + struct B + { + void f(); + }; +}; + +template<class T> void A<T>::B::f() +{ + C<int> c; + c.i = 0; +} + +template<class T> void A<T*>::B::f() +{ + C<int> c; + c.i = 0; +} + +void A<char>::B::f() +{ + C<int> c; + c.i = 0; +} + +int main() +{ + A<int>::B b1; + b1.f(); + A<int *>::B b2; + b2.f(); + A<char>::B b3; + b3.f(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend13.C b/gcc/testsuite/g++.dg/template/memfriend13.C new file mode 100644 index 000000000..7faed22a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend13.C @@ -0,0 +1,71 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class template of class template as friend + +template <class T> struct A +{ + template <class U> struct B + { + void f(); + }; +}; + +template <class V> class C { + int i; + template <class T> template <class U> friend struct A<T>::B; +}; + +template <class T> struct A<T*> +{ + template <class U> struct B + { + void f(); + }; +}; + +template <> struct A<char> +{ + template <class U> struct B + { + void f(); + }; +}; + +template <class T> template <class U> void A<T>::B<U>::f() +{ + C<int> c; + c.i = 0; +} + +template <class T> template <class U> void A<T*>::B<U>::f() +{ + C<int> c; + c.i = 0; +} + +template <class U> void A<char>::B<U>::f() +{ + C<int> c; + c.i = 0; +} + +template <> void A<char>::B<int>::f() +{ + C<int> c; + c.i = 0; +} + +int main() +{ + A<int>::B<int> b1; + b1.f(); + A<int *>::B<int> b2; + b2.f(); + A<char>::B<char> b3; + b3.f(); + A<char>::B<int> b4; + b4.f(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend14.C b/gcc/testsuite/g++.dg/template/memfriend14.C new file mode 100644 index 000000000..298c55811 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend14.C @@ -0,0 +1,73 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class template of class template as friend + +template<class T> struct A +{ + template <T t> struct B + { + void f(); + }; +}; + +template <class U> class C { + int i; + template<class T> template <T t> friend struct A<T>::B; +}; + +template<class T> struct A<T*> +{ + template <T* t> struct B + { + void f(); + }; +}; + +template<> struct A<char> +{ + template <char t> struct B + { + void f(); + }; +}; + +template<class T> template <T t> void A<T>::B<t>::f() +{ + C<int> c; + c.i = 0; +} + +template<class T> template <T* t> void A<T*>::B<t>::f() +{ + C<int> c; + c.i = 0; +} + +template <char t> void A<char>::B<t>::f() +{ + C<int> c; + c.i = 0; +} + +template <> void A<char>::B<'b'>::f() +{ + C<int> c; + c.i = 0; +} + +int d2 = 0; + +int main() +{ + A<int>::B<0> b1; + b1.f(); + A<int *>::B<&d2> b2; + b2.f(); + A<char>::B<'a'> b3; + b3.f(); + A<char>::B<'b'> b4; + b4.f(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend15.C b/gcc/testsuite/g++.dg/template/memfriend15.C new file mode 100644 index 000000000..c12ec4b5a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend15.C @@ -0,0 +1,34 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class of class template as friend + +template<class T> struct A +{ + struct B1 + { + }; + struct B2 + { + void f(); + }; +}; + +class C { + int i; // { dg-error "private" } + template<class T> friend struct A<T>::B1; +}; + +template<class T> void A<T>::B2::f() +{ + C c; + c.i = 0; // { dg-error "context" } +} + +int main() +{ + A<int>::B2 b1; + b1.f(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/memfriend16.C b/gcc/testsuite/g++.dg/template/memfriend16.C new file mode 100644 index 000000000..2827ef3f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend16.C @@ -0,0 +1,34 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class of class template as friend + +template<class T> struct A +{ + template <class U> struct B1 + { + }; + template <class U> struct B2 + { + void f(); + }; +}; + +class C { + int i; // { dg-error "private" } + template<class T> template <class U> friend struct A<T>::B1; +}; + +template<class T> template <class U> void A<T>::B2<U>::f() +{ + C c; + c.i = 0; // { dg-error "context" } +} + +int main() +{ + A<int>::B2<int> b1; + b1.f(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/memfriend17.C b/gcc/testsuite/g++.dg/template/memfriend17.C new file mode 100644 index 000000000..5e163fa47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend17.C @@ -0,0 +1,46 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// PR c++/13495: Nested class as template friend. + +template<typename T> +class A{ +public: + class B + { + void func1(void); + void func2(void); + }; +}; + +template<typename Q> +class F1 +{ + friend class A<Q>::B; + enum { foo = 0 }; // { dg-error "private" } +}; + +template<typename Q> +class F2 +{ + template<typename T> + friend class A<T>::B; + enum { foo = 0 }; +}; + +template <typename T> +void A<T>::B::func1(void) +{ + (void)F1<T>::foo; + (void)F2<T>::foo; +} + +template <typename T> +void A<T>::B::func2(void) +{ + (void)F1<T*>::foo; // { dg-error "context" } + (void)F2<T*>::foo; +} + +template class A<int>; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/memfriend2.C b/gcc/testsuite/g++.dg/template/memfriend2.C new file mode 100644 index 000000000..364ad7d78 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend2.C @@ -0,0 +1,61 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member function template of class template as friend + +template <class T> struct A +{ + template <class U> void f(); +}; + +class C { + int i; + template <class T> template <class U> friend void A<T>::f(); +}; + +template <class T> struct A<T*> +{ + template <class U> void f(); +}; + +template <> struct A<char> +{ + template <class U> void f(); +}; + +template <class T> template <class U> void A<T>::f() +{ + C c; + c.i = 0; +} + +template <class T> template <class U> void A<T*>::f() +{ + C c; + c.i = 0; +} + +template <class U> void A<char>::f() +{ + C c; + c.i = 0; +} + +template <> void A<char>::f<int>() +{ + C c; + c.i = 0; +} + +int main() +{ + A<int> a1; + a1.f<char>(); + A<int *> a2; + a2.f<char>(); + A<char> a3; + a3.f<char>(); + a3.f<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend3.C b/gcc/testsuite/g++.dg/template/memfriend3.C new file mode 100644 index 000000000..3ea8c84cf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend3.C @@ -0,0 +1,55 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member function of class template as friend + +template<class T> struct A +{ + void f(T); +}; + +class C { + int i; + template<class T> friend void A<T>::f(T); +}; + +template<class T> struct A<T*> +{ + void f(T*); +}; + +template<> struct A<char> +{ + void f(char); +}; + +template<class T> void A<T>::f(T) +{ + C c; + c.i = 0; +} + +template<class T> void A<T*>::f(T*) +{ + C c; + c.i = 0; +} + +void A<char>::f(char) +{ + C c; + c.i = 0; +} + +int main() +{ + A<int> a1; + a1.f(0); + A<int *> a2; + int *p = 0; + a2.f(p); + A<char> a3; + a3.f('a'); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend4.C b/gcc/testsuite/g++.dg/template/memfriend4.C new file mode 100644 index 000000000..5c006fe84 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend4.C @@ -0,0 +1,63 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member function of class template as friend + +template<class T> struct A +{ + template <T t> void f(); +}; + +class C { + int i; + template<class T> template <T t> friend void A<T>::f(); +}; + +template<class T> struct A<T*> +{ + template <T* t> void f(); +}; + +template<> struct A<char> +{ + template <char t> void f(); +}; + +template<class T> template <T t> void A<T>::f() +{ + C c; + c.i = 0; +} + +template<class T> template <T* t> void A<T*>::f() +{ + C c; + c.i = 0; +} + +template <char t> void A<char>::f() +{ + C c; + c.i = 0; +} + +template <> void A<char>::f<'b'>() +{ + C c; + c.i = 0; +} + +int d2 = 0; + +int main() +{ + A<int> a1; + a1.f<0>(); + A<int *> a2; + a2.f<&d2>(); + A<char> a3; + a3.f<'a'>(); + a3.f<'b'>(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend5.C b/gcc/testsuite/g++.dg/template/memfriend5.C new file mode 100644 index 000000000..38c2fb93f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend5.C @@ -0,0 +1,31 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member template function of member class template as friend + +template <class T> struct A { + template <class U> struct B { + template <class V> void f(V); + }; +}; + +class X { + int i; + template <class T> template <class U> template <class V> + friend void A<T>::B<U>::f(V); +}; + +template <class T> template <class U> template <class V> + void A<T>::B<U>::f(V) +{ + X x; + x.i = 0; +} + +int main() +{ + A<char>::B<char> a1; + a1.f(0); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend6.C b/gcc/testsuite/g++.dg/template/memfriend6.C new file mode 100644 index 000000000..5f82339af --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend6.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member function of class template as friend +// Erroneous case: mismatch during declaration + +template <class T> struct A { + template <class U> void f(U); // { dg-error "candidate" } + void g(); // { dg-error "candidate|with" } + void h(); // { dg-error "candidate|with" } + void i(int); // { dg-error "candidate" } +}; + +class C { + int ii; + template <class U> friend void A<U>::f(U); // { dg-error "not match" } + template <class U> template <class V> + friend void A<U>::g(); // { dg-error "not match|cannot be overloaded" } + template <class U> friend int A<U>::h(); // { dg-error "not match|cannot be overloaded" } + template <class U> friend void A<U>::i(char); // { dg-error "not match" } +}; diff --git a/gcc/testsuite/g++.dg/template/memfriend7.C b/gcc/testsuite/g++.dg/template/memfriend7.C new file mode 100644 index 000000000..1583646c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend7.C @@ -0,0 +1,133 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Member function of class template as friend +// Erroneous case: mismatch during specialization + +template <class T> struct A { + template <class U> void f(U); + void g(); + void h(); + void i(int); + template <T t> void j(); +}; + +class C { + int ii; // { dg-error "private" } + template <class U> template <class V> + friend void A<U>::f(V); + template <class U> friend void A<U>::g(); + template <class U> friend void A<U>::h(); + template <class U> friend void A<U>::i(int); + template <class U> template <U t> + friend void A<U>::j(); +}; + +template <class T> struct A<T*> { + void f(int); + template <class U> void g(); + int h(); + void i(char); + template <int> void j(); +}; + +template <class T> void A<T*>::f(int) +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <class T> template <class U> void A<T*>::g() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <class T> int A<T*>::h() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <class T> void A<T*>::i(char) +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <class T> template <int> void A<T*>::j() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <> struct A<char> { + void f(int); + template <class U> void g(); + int h(); + void i(char); + template <int> void j(); +}; + +void A<char>::f(int) +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <class U> void A<char>::g() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <> void A<char>::g<int>() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +int A<char>::h() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +void A<char>::i(char) +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <int> void A<char>::j() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +template <> void A<char>::j<0>() +{ + C c; + c.ii = 0; // { dg-error "context" } +} + +int main() +{ + A<int *> a1; + a1.f(0); // { dg-message "instantiated" } + a1.g<char>(); // { dg-message "instantiated" } + a1.g<int>(); // { dg-message "instantiated" } + a1.h(); // { dg-message "instantiated" } + a1.i('a'); // { dg-message "instantiated" } + a1.j<1>(); // { dg-message "instantiated" } + A<char> a2; + a2.f(0); + a2.g<char>(); // { dg-message "instantiated" } + a2.g<int>(); + a2.h(); + a2.i('a'); + a2.j<1>(); // { dg-message "instantiated" } + a2.j<0>(); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend8.C b/gcc/testsuite/g++.dg/template/memfriend8.C new file mode 100644 index 000000000..886096b9d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend8.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Origin: Martin Sebor <sebor@roguewave.com> + +// PR c++/5369: Member function of class template as friend + +template <class T> +struct S +{ + int foo () { + return S<int>::bar (); + } + +private: + + template <class U> + friend int S<U>::foo (); + + static int bar () { return 0; } +}; + +int main () +{ + S<char>().foo (); +} diff --git a/gcc/testsuite/g++.dg/template/memfriend9.C b/gcc/testsuite/g++.dg/template/memfriend9.C new file mode 100644 index 000000000..9c926013b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memfriend9.C @@ -0,0 +1,63 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +// Nested class of class template as friend + +template<class T> struct A +{ + struct B + { + void f(); + }; +}; + +class C { + int i; + template<class T> friend struct A<T>::B; +}; + +template<class T> struct A<T*> +{ + struct B + { + void f(); + }; +}; + +template<> struct A<char> +{ + struct B + { + void f(); + }; +}; + +template<class T> void A<T>::B::f() +{ + C c; + c.i = 0; +} + +template<class T> void A<T*>::B::f() +{ + C c; + c.i = 0; +} + +void A<char>::B::f() +{ + C c; + c.i = 0; +} + +int main() +{ + A<int>::B b1; + b1.f(); + A<int *>::B b2; + b2.f(); + A<char>::B b3; + b3.f(); +} diff --git a/gcc/testsuite/g++.dg/template/meminit1.C b/gcc/testsuite/g++.dg/template/meminit1.C new file mode 100644 index 000000000..6fd024a26 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/meminit1.C @@ -0,0 +1,8 @@ +// { dg-options "-std=gnu++98" } +template <class T > +struct S +{ + S() : S() {} // { dg-error "base" } +}; + +S<int> s; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/meminit2.C b/gcc/testsuite/g++.dg/template/meminit2.C new file mode 100644 index 000000000..f6afa0151 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/meminit2.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// Origin: Mark Anders <mark dot a dot anders at intel dot com> +// PR c++/15503: disambiguators in base classes and mem-initializers + +template <typename K1> struct O { + template <typename K2> struct I {}; +}; + +template <typename T> +struct A : typename O<T>::template I<int> { // { dg-error "keyword 'typename' not allowed" } + A() : typename O<T>::template I<int>() // { dg-error "keyword 'typename' not allowed" } + {} +}; + +template <typename T> +struct B : O<T>::template I<int> { + B() : O<T>::I<int>() // { dg-error "used as template|it is a template" "" } + {} +}; + +// { dg-bogus "end of input" "bogus token skipping in the parser" { xfail *-*-* } 17 } diff --git a/gcc/testsuite/g++.dg/template/memtmpl1.C b/gcc/testsuite/g++.dg/template/memtmpl1.C new file mode 100644 index 000000000..260dbf8dc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memtmpl1.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 30 Jul 2003 <nathan@codesourcery.com> + +// PR 11347. ICE in tsubst + +template <class T> struct T1 { + enum {N}; +}; + +template<class T> struct T2 { + template <class S, bool Z = T1<S>::N + 1> struct B {}; + struct C {}; +}; + +T2<int> t; + +T2<int>::B<int> s; + diff --git a/gcc/testsuite/g++.dg/template/memtmpl2.C b/gcc/testsuite/g++.dg/template/memtmpl2.C new file mode 100644 index 000000000..0c9dad647 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memtmpl2.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 18 Sep 2003 <nathan@codesourcery.com> + +// PR c++/12332. ICE + +template <unsigned D> class TPL; + +template <typename T> struct X { + template <template <typename> class V> + V<TPL<V<int>::d> > operator () (); +}; + +void Foo (X<int> x) {} diff --git a/gcc/testsuite/g++.dg/template/memtmpl3.C b/gcc/testsuite/g++.dg/template/memtmpl3.C new file mode 100644 index 000000000..583155ea7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memtmpl3.C @@ -0,0 +1,24 @@ +// PR c++/33239 + +struct null_type; + +template<typename T1, typename T2> +struct tuple_impl +{ + template<typename U> + struct append + { + typedef tuple_impl<U, null_type> type; + }; + + int data; +}; + +template<typename T1> +class tuple +: public tuple_impl<T1, null_type>::template append<T1>::type +{ + using tuple_impl<T1, null_type>::template append<T1>::type::data; +}; + +tuple<int> my_tuple; diff --git a/gcc/testsuite/g++.dg/template/nested1.C b/gcc/testsuite/g++.dg/template/nested1.C new file mode 100644 index 000000000..ed2028b3c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nested1.C @@ -0,0 +1,15 @@ +/* PR c++/4633 */ +/* { dg-do compile } */ + +// The 'class X' inside the template used to escape (somehow), +// so that the typedef claimed that it was redefining X. + +template <typename T> struct S ; + +template <> struct S<float> +{ + template <class, class> struct R; + template <class X> struct R<X, X> { }; + + typedef int X; +}; diff --git a/gcc/testsuite/g++.dg/template/nested2.C b/gcc/testsuite/g++.dg/template/nested2.C new file mode 100644 index 000000000..be4f95f71 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nested2.C @@ -0,0 +1,9 @@ +template <class T> class CO { + class CI1 { + class CI2; + }; +}; + +template <class T> +class CO<T>::CI1::CI2 {}; + diff --git a/gcc/testsuite/g++.dg/template/nested3.C b/gcc/testsuite/g++.dg/template/nested3.C new file mode 100644 index 000000000..5652e178a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nested3.C @@ -0,0 +1,30 @@ +template <class T1, class T2> +class A { + template <class S> + class SubA { + int _k; + }; + T1 _t1; + T2 _t2; +}; + +template <class U> +class B { + class SubB1 { + B _i; + }; + + class SubB2 { + int _j; + }; + A<U,SubB1>::SubA<SubB2> _a; // { dg-error "not a base type" "not base" } + // { dg-message "note" "note" { target *-*-* } 20 } + // { dg-error "non-template" "non-template" { target *-*-* } 20 } +}; + + +int main() { + B<char> objB; // { dg-message "instantiated" } + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/nested4.C b/gcc/testsuite/g++.dg/template/nested4.C new file mode 100644 index 000000000..6e5b99b46 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nested4.C @@ -0,0 +1,10 @@ +template <typename T> struct A { + template<typename S> struct B { typedef A<S> X; }; + +}; + +template<typename> void f() { + typedef A<int>::B<double>::X X; +} + +template void f<int> (); diff --git a/gcc/testsuite/g++.dg/template/nested5.C b/gcc/testsuite/g++.dg/template/nested5.C new file mode 100644 index 000000000..3850fdace --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nested5.C @@ -0,0 +1,19 @@ +// PR c++/33959 + +template <typename T> struct A +{ + struct C + { + template <typename U> struct D {}; + }; + template <typename S> static C::D<S> bar (S const &); +}; + +struct E {}; + +int +main () +{ + E e; + A<E>::bar (e); +} diff --git a/gcc/testsuite/g++.dg/template/new1.C b/gcc/testsuite/g++.dg/template/new1.C new file mode 100644 index 000000000..63ee2f924 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new1.C @@ -0,0 +1,45 @@ +// { dg-do run } +// { dg-options "-O2" } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Dec 2004 <nathan@codesourcery.com> + +// PR 18318. ICE with template new[] +// Origin:Elliot Hughes <enh@jessies.org> +// Andrew Pinski <pinskia@gcc.gnu.org> + +struct Aint +{ + ~Aint (); + Aint (); +}; + +Aint::Aint () {} +Aint::~Aint () {} + +static int count; + +template <class T> +struct A +{ + unsigned Blksize() const; + + void f() + { + new T[Blksize()]; + } +}; + +template <class T> unsigned A<T>::Blksize () const +{ + count++; + return 1; +} + +int main () +{ + A<Aint> a; + a.f(); + + return count != 1; +} diff --git a/gcc/testsuite/g++.dg/template/new10.C b/gcc/testsuite/g++.dg/template/new10.C new file mode 100644 index 000000000..98293ba5b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new10.C @@ -0,0 +1,23 @@ +// PR c++/46658 + +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +template<class T> class scoped_array { + void reset(T * p = 0) { } +}; +typedef uint16_t SequenceIndex; +typedef uint32_t SequenceMapIndex; +class Analyzer { + template <typename READER> + bool ReadDictionary( READER& reader ); + scoped_array<SequenceIndex> map_from_2_hints_to_composite_sequence; + SequenceMapIndex number_of_composite_sequences; +}; +template <typename READER> +bool Analyzer::ReadDictionary( READER &reader ) +{ + const SequenceMapIndex ntt + = ( number_of_composite_sequences + SequenceMapIndex( 1 ) ) + * ( number_of_composite_sequences + 1 ); + map_from_2_hints_to_composite_sequence.reset(new SequenceIndex[ntt]()); +} diff --git a/gcc/testsuite/g++.dg/template/new2.C b/gcc/testsuite/g++.dg/template/new2.C new file mode 100644 index 000000000..682ca6e18 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new2.C @@ -0,0 +1,14 @@ +// PR c++/21336 + +typedef __SIZE_TYPE__ size_t; +template<class _T> void* operator new( size_t Size, _T&); +struct B { + int a; + int* m() { + return new(a) int; + } +}; +B* n() { + return new B(); +} + diff --git a/gcc/testsuite/g++.dg/template/new3.C b/gcc/testsuite/g++.dg/template/new3.C new file mode 100644 index 000000000..230330ec6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new3.C @@ -0,0 +1,18 @@ +extern void *operator new(__SIZE_TYPE__); // { dg-message "note" } + +template <class T > +struct C +{ + void f() { + int* node; + new (&node) int(0); // { dg-error "new" } + // { dg-message "candidate" "candidate note" { target *-*-* } 8 } + } +}; + +void* operator new(__SIZE_TYPE__, void* __p); + +void g() { + C<int> c; + c.f(); +} diff --git a/gcc/testsuite/g++.dg/template/new4.C b/gcc/testsuite/g++.dg/template/new4.C new file mode 100644 index 000000000..bf6f06100 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new4.C @@ -0,0 +1,8 @@ +// PR c++/27559 +// { dg-do compile } + +struct A +{ + template<typename T> + static void* operator new(T) {} // { dg-error "first parameter|invalid template" } +}; diff --git a/gcc/testsuite/g++.dg/template/new5.C b/gcc/testsuite/g++.dg/template/new5.C new file mode 100644 index 000000000..a2c560181 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new5.C @@ -0,0 +1,9 @@ +// PR c++/27210 + +template <class foo> class junk { + void bar(int a) + { + unsigned char *c = new unsigned char[a*sizeof(foo)]; + } +}; + diff --git a/gcc/testsuite/g++.dg/template/new6.C b/gcc/testsuite/g++.dg/template/new6.C new file mode 100644 index 000000000..4db068512 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new6.C @@ -0,0 +1,7 @@ +// PR c++/27713 +// { dg-do compile } + +struct A +{ + template<int> friend void* operator new(__SIZE_TYPE__); // { dg-error "invalid template" } +}; diff --git a/gcc/testsuite/g++.dg/template/new7.C b/gcc/testsuite/g++.dg/template/new7.C new file mode 100644 index 000000000..dcf8a8e59 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new7.C @@ -0,0 +1,9 @@ +// PR c++/27714 + +template<typename> struct A +{ + static void* operator new(__SIZE_TYPE__); + template<typename T> friend void* A<T>::operator new(__SIZE_TYPE__); +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/new8.C b/gcc/testsuite/g++.dg/template/new8.C new file mode 100644 index 000000000..b8f3f97e6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new8.C @@ -0,0 +1,29 @@ +// PR c++/34336 +// { dg-do compile } + +struct A; + +template <class T> +struct S +{ + T *m; + T &operator* () { return *m; } +}; + +struct B +{ + B (const A &); +}; + +template <class T> +struct C +{ + C (); + S<A> c; +}; + +template <class T> +C<T>::C () +{ + B *b = new B (*c); +} diff --git a/gcc/testsuite/g++.dg/template/new9.C b/gcc/testsuite/g++.dg/template/new9.C new file mode 100644 index 000000000..24e40ee23 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/new9.C @@ -0,0 +1,16 @@ +// PR c++/46277 + +class ggRGBE { +public: + ggRGBE(); +}; +template <class T> class ggIO +{ + void readbody(int); + ggRGBE *scanline; +}; +template <class T> void +ggIO<T>::readbody(int width) +{ + scanline = new ggRGBE[width]; +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent1.C b/gcc/testsuite/g++.dg/template/non-dependent1.C new file mode 100644 index 000000000..3fe5c33d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent1.C @@ -0,0 +1,21 @@ +//PR c++/8222 +// Origin: giovannibajo@libero.it and setzersn@gmx.de + +// { dg-do run } + +struct Foo +{ + template <class> + void func() {} +}; +template <class> +void Bar(Foo* p) +{ + p->func<int>(); +} + +int main() +{ + Foo c; + Bar<int>(&c); +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent10.C b/gcc/testsuite/g++.dg/template/non-dependent10.C new file mode 100644 index 000000000..1891cad30 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent10.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// Two-phase name lookup for address of member: +// Detecting overloading function error during parsing + +struct S +{ + int f(char); + int f(int); +}; + +template<int (S::*p)()> +struct X +{}; + +template <class T> +struct Foo +{ + X<&S::f> x; // { dg-error "convert|no matches" } +}; diff --git a/gcc/testsuite/g++.dg/template/non-dependent11.C b/gcc/testsuite/g++.dg/template/non-dependent11.C new file mode 100644 index 000000000..dff5b909d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent11.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Origin: Jakub Jelinek <jakub@gcc.gnu.org> +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/19311: Non-dependent address to member as function argument. + +template <class R, class T> void foo (R (T::*x) ()); +template <class R, class T, class C> void foo (R (T::*x) (C)); + +template<int> struct I { + int o (); + int o () const; +}; + +template <int> void bar (void) { + foo <int, I<1> > (&I<1>::o); +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent12.C b/gcc/testsuite/g++.dg/template/non-dependent12.C new file mode 100644 index 000000000..73d7e9497 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent12.C @@ -0,0 +1,10 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 8 Mar 2005 <nathan@codesourcery.com> + +// PR 20186: ICE +// Origin: Jan Dvorak <jan.dvorak@kraxnet.cz> + +template<typename T> void foo(T &t) +{ + int i = static_cast<int>(t); +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent13.C b/gcc/testsuite/g++.dg/template/non-dependent13.C new file mode 100644 index 000000000..9e69948ac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent13.C @@ -0,0 +1,11 @@ +// PR c++/26266 + +template <int I> +struct S; + +template <int I> +void f() { + if (const int i = 3) { + S<i>::j; // { dg-error "incomplete" } + } +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent2.C b/gcc/testsuite/g++.dg/template/non-dependent2.C new file mode 100644 index 000000000..3b073b47a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent2.C @@ -0,0 +1,16 @@ +//PR c++/11070 +// Used to ICE +// Origin: bangerth@dealii.org and rwgk@yahoo.com + +template <bool b> struct X { + template <typename T> + static int* execute(int* x) { return x; } +}; + +template <typename T> void foo() { + static bool const same = true; + X<same>::execute<int> (0); +} + +template void foo<int> (); + diff --git a/gcc/testsuite/g++.dg/template/non-dependent3.C b/gcc/testsuite/g++.dg/template/non-dependent3.C new file mode 100644 index 000000000..ce18bf243 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent3.C @@ -0,0 +1,15 @@ +//PR c++/11071 +// Used to ICE +// Origin: bangerth@dealii.org and rwgk@yahoo.com + +template <bool b> struct X { + template <typename T> + static int* execute(T* x) { return x; } +}; + +template <typename T> void foo() { + static bool const same = true; + X<same>::execute ((int*)0); +} + +template void foo<int> (); diff --git a/gcc/testsuite/g++.dg/template/non-dependent4.C b/gcc/testsuite/g++.dg/template/non-dependent4.C new file mode 100644 index 000000000..ff3a6eb2c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent4.C @@ -0,0 +1,4 @@ +int temp(const char *temp); + +template <int> int g() { return temp("Hi"); } +int g1() { return temp("Hi"); } diff --git a/gcc/testsuite/g++.dg/template/non-dependent5.C b/gcc/testsuite/g++.dg/template/non-dependent5.C new file mode 100644 index 000000000..bd6ce6b47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent5.C @@ -0,0 +1,8 @@ +// PR c++/15299 + +template <class T> void fun_ptr(T (*)()); +template <class T> T bar(); + +template <class> void foo () { + fun_ptr(bar<int>); +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent6.C b/gcc/testsuite/g++.dg/template/non-dependent6.C new file mode 100644 index 000000000..0959a3de9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent6.C @@ -0,0 +1,13 @@ +// PR c++/15285 + +void foo(void (*func)()) {} + +template<typename T> +void bar() +{} + +template<typename T> +void baz() +{ + foo(&bar<long>); +} diff --git a/gcc/testsuite/g++.dg/template/non-dependent7.C b/gcc/testsuite/g++.dg/template/non-dependent7.C new file mode 100644 index 000000000..ee34327ad --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent7.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// PR c++/13092: ICE taking address of member which is non-dependent + +struct S +{ + int i; +}; + +template<int S::*p> +struct X +{}; + +template <class T> +struct Foo +{ + X<&S::i> x; +}; + +template struct Foo<void>; diff --git a/gcc/testsuite/g++.dg/template/non-dependent8.C b/gcc/testsuite/g++.dg/template/non-dependent8.C new file mode 100644 index 000000000..369e13731 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent8.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// Two-phase name lookup for address of member: +// Detecting error during parsing + +struct S +{ + char i; +}; + +template<int S::*p> +struct X +{}; + +template <class T> +struct Foo +{ + X<&S::i> x; // { dg-error "convert|no type" } +}; diff --git a/gcc/testsuite/g++.dg/template/non-dependent9.C b/gcc/testsuite/g++.dg/template/non-dependent9.C new file mode 100644 index 000000000..c046312d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent9.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: Giovanni Bajo <giovannibajo@libero.it> + +// Two-phase name lookup for address of member: +// Overloading function + +struct S +{ + int f(); + int f(int); +}; + +template<int (S::*p)()> +struct X +{}; + +template <class T> +struct Foo +{ + X<&S::f> x; +}; diff --git a/gcc/testsuite/g++.dg/template/non-type-template-argument-1.C b/gcc/testsuite/g++.dg/template/non-type-template-argument-1.C new file mode 100644 index 000000000..41243649a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-type-template-argument-1.C @@ -0,0 +1,12 @@ +struct A { static const bool b=false; }; + +struct B { typedef A X; }; + +template <bool> struct C {}; + +template <typename T> struct D +{ + C<T::X> c; // { dg-error "parsed as a non-type|if a type is meant" } +}; + +D<B> d; // { dg-message "instantiated from here" } diff --git a/gcc/testsuite/g++.dg/template/non-type1.C b/gcc/testsuite/g++.dg/template/non-type1.C new file mode 100644 index 000000000..70e81d362 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-type1.C @@ -0,0 +1,49 @@ +// PR c++/4377 + +template < int I1, int I2 > +class unit +{ +public: + typedef unit<I1,I2> my_type; + + unit() {} + unit( const unit<I1,I2>& ) {} + + template< int Q1, int Q2 > + unit< I1 + Q1, I2 + Q2 > operator * ( const unit< Q1, Q2 >& rhs ) const { + return unit< I1 + Q1, I2 + Q2 >(); + } + + template< int Q1, int Q2 > + unit< I1 - Q1, I2 - Q2 > operator / ( const unit< Q1, Q2 >& rhs ) const { + return unit< I1 - Q1, I2 - Q2 >(); + } +}; + +// specialization added to first test +// +template <> +class unit<0,0> { +public: + typedef unit<0,0> my_type; + + unit() {} + + friend unit<0,0> operator*( const unit<0,0>& lhs, const unit<0,0>& rhs ) { + return unit<0,0>(); + } + friend unit<0,0> operator/( const unit<0,0>& lhs, const unit<0,0>& rhs ) { + return unit<0,0>(); + } + +}; + + +int main() +{ + const unit<1,0> u1; + const unit<2,0> u2; + + unit<-1,0> u3( u1 / u2 ); + unit< 3,0> u4( u1 * u2 ); +} diff --git a/gcc/testsuite/g++.dg/template/nontype1.C b/gcc/testsuite/g++.dg/template/nontype1.C new file mode 100644 index 000000000..834a36a26 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype1.C @@ -0,0 +1,5 @@ +// PR c++/4934 +// dump_expr didn't know how to deal with a CONVERT_EXPR with no type. + +template<unsigned> struct A {}; +template<typename T> struct B { A<sizeof(+int())> a; }; diff --git a/gcc/testsuite/g++.dg/template/nontype10.C b/gcc/testsuite/g++.dg/template/nontype10.C new file mode 100644 index 000000000..83ac8e302 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype10.C @@ -0,0 +1,10 @@ +// { dg-do compile } +// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +#include <cstddef> + +template <int T> struct A {}; +template <void* T> struct B {}; + +A<NULL> a; // { dg-warning "NULL" } +B<NULL> b; // { dg-error "" } + diff --git a/gcc/testsuite/g++.dg/template/nontype11.C b/gcc/testsuite/g++.dg/template/nontype11.C new file mode 100644 index 000000000..d52eb9a38 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype11.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// Origin: <fsm at robots dot ox dot ac dot uk> +// PR c++/18354: Unary plus should not be wrapped in NON_LVALUE_EXPR + +template <int N> +struct X { }; + +const int n = 1; + +void f() +{ + X< 1> a; + X<-1> b; + X<+1> c; +} + +void g() +{ + X< n> a; + X<-n> b; + X<+n> c; +} diff --git a/gcc/testsuite/g++.dg/template/nontype12.C b/gcc/testsuite/g++.dg/template/nontype12.C new file mode 100644 index 000000000..a290ec337 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype12.C @@ -0,0 +1,35 @@ +// PR c++/20172 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> + +template<typename T> struct A +{ + template<T> int foo(); // { dg-error "double" } + template<template<T> class> int bar(); // { dg-error "double" } + template<T> struct X; // { dg-error "double" } +}; + +A<char> a1; +A<double> a2; // { dg-message "instantiated" } + +template<typename T> struct B +{ + template<double> int foo(); // { dg-error "double" } + template<template<double> class> int bar(); // { dg-error "double" } + template<double> struct X; // { dg-error "double" } +}; + +template<void> int foo(); // { dg-error "void" } +template<template<void> class> int bar(); // { dg-error "void" } +template<void> struct X; // { dg-error "void" } + +template<typename T> struct C +{ + template<T> int foo(); // { dg-error "double" } +}; + +template<typename T> int baz(T) { C<T> c; } // { dg-message "instantiated" } + +void foobar() +{ + baz(1.2); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/nontype13.C b/gcc/testsuite/g++.dg/template/nontype13.C new file mode 100644 index 000000000..6fffb8d8e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype13.C @@ -0,0 +1,29 @@ +// PR c++/19004 + +template<typename T> +struct Dummy +{ + void evil() + { + this->template tester<true>(); + } + + template<bool B> + void tester() + { + bar<evil>()(); // { dg-error "constant" } + } + template<bool B> + struct bar + { + void operator()() + { } + }; +}; + +int main() +{ + Dummy<int> d; + d.tester<true> (); // { dg-message "instantiated" } +} + diff --git a/gcc/testsuite/g++.dg/template/nontype14.C b/gcc/testsuite/g++.dg/template/nontype14.C new file mode 100644 index 000000000..93338512b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype14.C @@ -0,0 +1,13 @@ +// PR c++/23789 + +template <int W> struct X { + template <int W2> + X< (W+(W&&W) > 1 ? W+(W&&W) : 1)+1> + operator + (const X<W2>&) const; +}; + +template <int dummy> void foo() +{ + X<6> A,B; + A + B; +} diff --git a/gcc/testsuite/g++.dg/template/nontype15.C b/gcc/testsuite/g++.dg/template/nontype15.C new file mode 100644 index 000000000..dd5f4e78a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype15.C @@ -0,0 +1,20 @@ +struct foo { + typedef int (*fun)(int); + + static int f(int); // overload between static & non-static + int f(); + + static int g(int); // non-overloaded static +}; + +template<foo::fun> +struct f_obj { + // something .. +}; + +int foo::f() { + f_obj<f> f1; + f_obj<g> f2; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/nontype16.C b/gcc/testsuite/g++.dg/template/nontype16.C new file mode 100644 index 000000000..36d1e9564 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype16.C @@ -0,0 +1,9 @@ +//PR c++/27962 + +template<int> struct A +{ + template<typename> void foo(); +}; + +template<> template<struct T> void A<0>::foo() {} // { dg-error "not a valid type" } + diff --git a/gcc/testsuite/g++.dg/template/nontype17.C b/gcc/testsuite/g++.dg/template/nontype17.C new file mode 100644 index 000000000..f3a4480c9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype17.C @@ -0,0 +1,8 @@ +// PR c++/35282 + +template<int> struct A +{ + template<int> void foo(); +}; + +template<> template<int> void A<0>::foo() {} diff --git a/gcc/testsuite/g++.dg/template/nontype18.C b/gcc/testsuite/g++.dg/template/nontype18.C new file mode 100644 index 000000000..cbe0a1b5a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype18.C @@ -0,0 +1,8 @@ +// PR c++/28743 + +template<int I> struct A +{ + template<typename T> void foo(); +}; + +template<int I> template<typename T> void A<0>::foo() {} // { dg-error "template parameter" } diff --git a/gcc/testsuite/g++.dg/template/nontype19.C b/gcc/testsuite/g++.dg/template/nontype19.C new file mode 100644 index 000000000..1df78b3b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype19.C @@ -0,0 +1,19 @@ +// PR c++/42466 + +template<class IntT, IntT X> +struct A +{ + A(); + + template<IntT X2> + A(const A<IntT, X2>& other); +}; + +int main(int argc, char** argv) +{ + A<int, 42> a; + A<int, 100> b = a; + + A<unsigned, 42u> c; + A<unsigned, 100u> d = c; +} diff --git a/gcc/testsuite/g++.dg/template/nontype2.C b/gcc/testsuite/g++.dg/template/nontype2.C new file mode 100644 index 000000000..fe7e71537 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype2.C @@ -0,0 +1,11 @@ +template <bool> struct A {}; + +template <bool> struct B +{ + void foo() + { + const int i=0; + typedef A< i<=1 > C; + typedef A< i<=2 > C; + } +}; diff --git a/gcc/testsuite/g++.dg/template/nontype20.C b/gcc/testsuite/g++.dg/template/nontype20.C new file mode 100644 index 000000000..e4aba3227 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype20.C @@ -0,0 +1,11 @@ +// PR c++/48003 +// { dg-options "-fpermissive -w" } +// Test that we allow integer overflow in constant exprs with -fpermissive + +template<int N> +struct test +{ + typedef test<N - 1> prior; +}; + +test<-2147483647-1> f; diff --git a/gcc/testsuite/g++.dg/template/nontype21.C b/gcc/testsuite/g++.dg/template/nontype21.C new file mode 100644 index 000000000..69cab54f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype21.C @@ -0,0 +1,7 @@ +// PR c++/47705 + +template<char const * const x> class Something { }; + +extern char const xyz; + +class SomethingElse:public Something<xyz> { }; // { dg-error "xyz. is a variable" } diff --git a/gcc/testsuite/g++.dg/template/nontype22.C b/gcc/testsuite/g++.dg/template/nontype22.C new file mode 100644 index 000000000..f2c8c46e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype22.C @@ -0,0 +1,11 @@ +// PR c++/44629 +// The proper mangling is unclear. + +template<typename T> int cmp1(T a, T b); +template<typename T, int (*cmp)(T, T) = cmp1> struct A { }; +template <typename T> void f (A<T> &); // { dg-bogus "" "" { xfail *-*-* } } +void g() +{ + A<char> a; + f(a); +} diff --git a/gcc/testsuite/g++.dg/template/nontype3.C b/gcc/testsuite/g++.dg/template/nontype3.C new file mode 100644 index 000000000..d0c6b72a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype3.C @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options -std=c++98 } +// Origin: <drow at gcc dot gnu dot org>, +// <giovannibajo at gcc dot gnu dot org> +// c++/13243: Template parameters of non integral or enumeration type can't be +// used for integral constant expressions. ADDR_EXPR and INDIRECT_REF are +// invalid too. + +template <int T> class foo {}; +template <int *T> class bar {}; + +template <int *PI> +void dep5(bar<PI> *); + +template <int *PI> +void dep6(bar<PI+1> *); // { dg-error "" "integral or enumeration" } + +template <int I> +void dep7(bar<I+1> *); + +template <int *PI> +void dep8(foo< *PI > *); // { dg-error "" "integral or enumeration" } + +template <int PI[1]> +void dep9(foo< *PI > *); // { dg-error "" "integral or enumeration" } + +template <int PI[1]> +void dep9a(foo< sizeof(*PI) > *); + +template <int PI[1]> +void dep10(foo< PI[0] > *); // { dg-error "" "integral or enumeration" } + +template <int I> +void dep11(foo< *&I > *); // { dg-error "" "constant-expression" } + +template <int I> +void dep12(foo< (&I)[4] > *); // { dg-error "" "constant-expression" } + diff --git a/gcc/testsuite/g++.dg/template/nontype4.C b/gcc/testsuite/g++.dg/template/nontype4.C new file mode 100644 index 000000000..ab39ed443 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype4.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> +// Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/13797: ICE invalid nontype template parameter + +template <int> struct A +{ + typedef A<0> B; // { dg-error "previous declaration" } + template <B> struct B {}; // { dg-error "not a valid type|typedef" } +}; + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/nontype5.C b/gcc/testsuite/g++.dg/template/nontype5.C new file mode 100644 index 000000000..f7b76259b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype5.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> +// Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/13797: ICE invalid nontype template parameter + +template <int> struct A +{ + typedef A<0> B; + template <B> struct C {}; // { dg-error "not a valid type" } +}; + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/nontype6.C b/gcc/testsuite/g++.dg/template/nontype6.C new file mode 100644 index 000000000..97b093ae5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype6.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// Origin: <v dot haisman at sh dot cvut dot cz> +// PR c++/13957: Improved error message for type in template (when non-type +// is expected). + +template <class T> +struct A +{ + typedef int type; +}; + +template <class T> +void func(void) +{ + (void)A<T>::type(); // { dg-error "non-type" "non-type" } +// { dg-message "if a type" "note" { target *-*-* } 15 } +} + +template void func<float>(void); // { dg-message "instantiated from here" } diff --git a/gcc/testsuite/g++.dg/template/nontype7.C b/gcc/testsuite/g++.dg/template/nontype7.C new file mode 100644 index 000000000..5eac558e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype7.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// Origin: C++ standard, [temp.arg.nontype]/2 + +template<class T, char* p> struct X { + X(); + X(const char* q) { /* ... */ } +}; + +char p[] = "Vivisectionist"; + +X<int,"Studebaker"> x1; // { dg-error "string literal" } +X<int, p> x2; + +// { dg-bogus "" "additional errors" { xfail *-*-* } 11 } + diff --git a/gcc/testsuite/g++.dg/template/nontype8.C b/gcc/testsuite/g++.dg/template/nontype8.C new file mode 100644 index 000000000..d2976dfc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype8.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// Origin: C++ standard, [temp.arg.nontype]/3 + +template<int* p> class X { }; + +int a[10]; +struct S { int m; static int s; } s; + +X<&a[2]> x3; // { dg-error "" } address of array element +X<&s.m> x4; // { dg-error "" } address of non-static member +X<&s.s> x5; // { dg-error "" } &S::s must be used +X<&S::s> x6; // OK: address of static member + diff --git a/gcc/testsuite/g++.dg/template/nontype9.C b/gcc/testsuite/g++.dg/template/nontype9.C new file mode 100644 index 000000000..e16eef601 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype9.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-prune-output "mangled name" } +// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +int i; + +template <void (&FN)()> +struct g { + void foo(void) { + FN (); + } +}; + +void h () +{ + i = 7; +} + +template struct g<h>; + diff --git a/gcc/testsuite/g++.dg/template/ntp1.C b/gcc/testsuite/g++.dg/template/ntp1.C new file mode 100644 index 000000000..98698e932 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ntp1.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Dec 2001 <nathan@codesourcery.com> + +// PR 35. We were default promoting template PARM_DECLs + +template <short B> class R {}; + +template <class T> class A +{ + public: + template <short B> + void operator() (R<B> const &); +}; + +int main() { + A<int> a; + R<1> r; + + a (r); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/ntp2.C b/gcc/testsuite/g++.dg/template/ntp2.C new file mode 100644 index 000000000..42219e0fc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ntp2.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Dec 2002 <nathan@codesourcery.com> + +// PR 3784: We were confusing non-type template parms. + +template <unsigned N> class X { }; + +template <short N> void foo1(X<N>); +template <unsigned N> void foo2(X<N>); + +int main() { + X<2> x; + foo2(x); +} diff --git a/gcc/testsuite/g++.dg/template/offsetof1.C b/gcc/testsuite/g++.dg/template/offsetof1.C new file mode 100644 index 000000000..1ee9be1e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/offsetof1.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// PR c++/17221 + +#include <cstddef> + +template <int N> struct Bar; +template <> struct Bar<3> {}; + +template <class T> +struct Foo { + Bar<offsetof(T, a) + 3> k; +}; + +struct A { int a; }; + +template struct Foo<A>; diff --git a/gcc/testsuite/g++.dg/template/op1.C b/gcc/testsuite/g++.dg/template/op1.C new file mode 100644 index 000000000..7cc9c9e91 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/op1.C @@ -0,0 +1,12 @@ +template <class T> struct X { + typedef int type; +}; + +template <class T> struct O { + struct I { + operator typename X<T>::type (); + }; +}; + +template <class T> +O<T>::I::operator typename X<T>::type () {} diff --git a/gcc/testsuite/g++.dg/template/operator1.C b/gcc/testsuite/g++.dg/template/operator1.C new file mode 100644 index 000000000..402e607d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator1.C @@ -0,0 +1,49 @@ +class test +{ +public: + float operator[]( int index ) + { + return testFloat[index]; + } +private: + float testFloat[3]; +}; + +template < class typeA > float +operator*( + typeA a, + float b +) +{ + return a[0] * b; +} + +template < class typeB > float +operator*( + float a, + typeB b +) +{ + return a * b[0]; +} + +template < class typeA, class typeB > float +operator*( + typeA a, + typeB b +) +{ + return a[0] * b[0]; +} + +int main( void ) +{ + test aTest; + float bTest; + float result; + + result = aTest * bTest; + result = bTest * aTest; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/operator10.C b/gcc/testsuite/g++.dg/template/operator10.C new file mode 100644 index 000000000..448b02290 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator10.C @@ -0,0 +1,8 @@ +// PR c++/30535 +// { dg-prune-output "note" } + +struct A {}; + +template<A, typename T> int operator-(A, T); // { dg-error "not a valid type" } + +int i = A() - 0; // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/template/operator11.C b/gcc/testsuite/g++.dg/template/operator11.C new file mode 100644 index 000000000..8d6b77ab4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator11.C @@ -0,0 +1,25 @@ +// PR c++/48594 +// Test for uses of (X->*Y)() that don't actually involve a +// pointer to member function. + +struct A { } a; +struct B { } b; +struct C * cp; + +struct Func { void operator()(); }; +Func operator->* (A, int); + +typedef void (*pfn)(); +pfn operator->* (B, int); + +pfn C::*cpfn; +Func C::*cfunc; + +template <class T> +void f() +{ + (a->*1)(); + (b->*1)(); + (cp->*cpfn)(); + (cp->*cfunc)(); +} diff --git a/gcc/testsuite/g++.dg/template/operator2.C b/gcc/testsuite/g++.dg/template/operator2.C new file mode 100644 index 000000000..89f428d5f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator2.C @@ -0,0 +1,8 @@ +template <typename T> struct A {}; + +struct B { + operator A<B>(); +}; + +template <typename T> +void f() { B::operator A<T>; } diff --git a/gcc/testsuite/g++.dg/template/operator3.C b/gcc/testsuite/g++.dg/template/operator3.C new file mode 100644 index 000000000..45292cd95 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator3.C @@ -0,0 +1,10 @@ +// PR c++/15640 + +struct A { + void foo(void); +}; + +template <int> void bar() { + A a; + a + a.foo; // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/template/operator4.C b/gcc/testsuite/g++.dg/template/operator4.C new file mode 100644 index 000000000..972d52fc1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator4.C @@ -0,0 +1,11 @@ +// PR c++/17068 + +struct A +{ + template<int> void operator()() {} +}; + +template<typename> void foo() +{ + A().template operator()<0>(); +} diff --git a/gcc/testsuite/g++.dg/template/operator5.C b/gcc/testsuite/g++.dg/template/operator5.C new file mode 100644 index 000000000..1c0c29231 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator5.C @@ -0,0 +1,14 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Dec 2004 <nathan@codesourcery.com> + +// PR 18803: reject legal +// Origin: Wolfgang Bangerth <bangerth@dealii.org> + +struct A { + int operator() (); +}; + +template <int> void foo () { + A &a = *new A(); + const int i = a(); +} diff --git a/gcc/testsuite/g++.dg/template/operator6.C b/gcc/testsuite/g++.dg/template/operator6.C new file mode 100644 index 000000000..94a869bcc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator6.C @@ -0,0 +1,4 @@ +// PR c++/27315 +// { dg-do compile } + +template void operator+; // { dg-error "non-function" } diff --git a/gcc/testsuite/g++.dg/template/operator7.C b/gcc/testsuite/g++.dg/template/operator7.C new file mode 100644 index 000000000..59c8b356c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator7.C @@ -0,0 +1,7 @@ +//PR c++/27493 +// { dg-options "-std=gnu++98" } + +template<operator T> void foo() // { dg-error "before|template" } +{ + struct A {}; +} diff --git a/gcc/testsuite/g++.dg/template/operator8.C b/gcc/testsuite/g++.dg/template/operator8.C new file mode 100644 index 000000000..29d17b84b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator8.C @@ -0,0 +1,6 @@ +//PR c++/27494 + +struct A +{ + template<operator+> void foo() {} // { dg-error "identifier|non-function|template arguments" } +}; diff --git a/gcc/testsuite/g++.dg/template/operator9.C b/gcc/testsuite/g++.dg/template/operator9.C new file mode 100644 index 000000000..35be77876 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator9.C @@ -0,0 +1,10 @@ +//PR c++/27670 + +template<operator+> void foo(); // { dg-error "before|non-function|template" } + +void bar() +{ + foo(); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 7 } +} + diff --git a/gcc/testsuite/g++.dg/template/overload1.C b/gcc/testsuite/g++.dg/template/overload1.C new file mode 100644 index 000000000..2225fecf7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload1.C @@ -0,0 +1,24 @@ +// { dg-options "-w" } +// PR c++/9420 +// Bug: We were instantiating B<int> during overload resolution for E<0. +// This is wrong; the contents of B<int> are not relevant, since we can't +// use its constructors (because we'd already be using a constructor for +// C). + +enum { E }; + +template <typename T> struct A { + static const int a = (E < 0); +}; + +template <typename T> class B { + A<int> b; +}; + +struct C { + C(B<int>); +}; + +int operator<(C, C); + +A<int> c; diff --git a/gcc/testsuite/g++.dg/template/overload10.C b/gcc/testsuite/g++.dg/template/overload10.C new file mode 100644 index 000000000..088b9d291 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload10.C @@ -0,0 +1,6 @@ +// PR c++40342 + +template <typename T1, typename T2> int f(T1 *, const T2 *); // { dg-error "" } +template <typename T1, typename T2> int f(const T1 *, T2 *); // { dg-error "" } + +int (*p)(const int *, const int *) = f; // { dg-error "ambiguous" } diff --git a/gcc/testsuite/g++.dg/template/overload11.C b/gcc/testsuite/g++.dg/template/overload11.C new file mode 100644 index 000000000..d7b0a7c9f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload11.C @@ -0,0 +1,27 @@ +// PR c++/39413 +// We don't need to instantiate Wrapper<int> to check the +// foo(const Thingy&) overload. + +template <class T> struct Incomplete; + +template <typename T> class Wrapper +{ + Incomplete<T> i; +}; + +template <typename T> struct Thingy +{ + Thingy(); + Thingy(const Wrapper<T>& v); + + template <typename X> void foo(const Thingy<X>&); + void foo(const Thingy&); +}; + +int main() +{ + Thingy<int> ap1; + Thingy<float> bp1; + + ap1.foo(bp1); +} diff --git a/gcc/testsuite/g++.dg/template/overload2.C b/gcc/testsuite/g++.dg/template/overload2.C new file mode 100644 index 000000000..253d055cd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload2.C @@ -0,0 +1,15 @@ +template <class T, int (T::*)> struct foo; + +template <class T> +int f(foo<T,&T::ob_type>*); + +template <class T> +char* f(...); + +struct X { int ob_type; }; +struct Y { char* ob_type; }; + int x = f<X>(0); +char* y = f<Y>(0); +char* z = f<int>(0); + +int main() { return 0; } diff --git a/gcc/testsuite/g++.dg/template/overload3.C b/gcc/testsuite/g++.dg/template/overload3.C new file mode 100644 index 000000000..ec48fbb90 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload3.C @@ -0,0 +1,14 @@ +// PR c++/16870 + +struct A +{ + int operator[](int) const; +}; + +template<int> A foo(); + +A bar(A(*)()); + +template<int> int baz() { return (bar(&foo<0>))[0]; } + +template int baz<0>(); diff --git a/gcc/testsuite/g++.dg/template/overload4.C b/gcc/testsuite/g++.dg/template/overload4.C new file mode 100644 index 000000000..1a294eb3c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload4.C @@ -0,0 +1,20 @@ +// PR c++/20679 + +template <class T> +struct foo +{ + struct bar + { + int m; + }; + + void m() const {} + void m() {} + + bool n() const { return b->m < 42; } + + bar *b; +}; + + + diff --git a/gcc/testsuite/g++.dg/template/overload5.C b/gcc/testsuite/g++.dg/template/overload5.C new file mode 100644 index 000000000..8e520e929 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload5.C @@ -0,0 +1,28 @@ +// PR c++/22621 + +struct foo { + typedef int (*fun)(int); + + static int f(int); // overload between static & non-static + int f(); + + static int g(int); // non-overloaded static +}; + +template<foo::fun> +struct f_obj { + // something .. +}; + +f_obj<&foo::f> a; // OK +f_obj<foo::f> b; // OK (note: a and b are of the same type) + +int foo::f() +{ + f_obj<&foo::f> a; // OK + f_obj<foo::f> b; // ERROR: foo::f cannot be a constant expression + + f_obj<&foo::g> c; // OK + f_obj<foo::g> d; // OK +} + diff --git a/gcc/testsuite/g++.dg/template/overload6.C b/gcc/testsuite/g++.dg/template/overload6.C new file mode 100644 index 000000000..5e26c448b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload6.C @@ -0,0 +1,18 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 12 Oct 2005 <nathan@codesourcery.com> + +// PR 21592:ICE +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> + +template<typename T> void unique(T,T); // { dg-message "note" } + +struct A +{ + int begin(); +}; + +template<int> void foo() +{ + unique(A().begin); // { dg-error "no matching function" "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 16 } +} diff --git a/gcc/testsuite/g++.dg/template/overload7.C b/gcc/testsuite/g++.dg/template/overload7.C new file mode 100644 index 000000000..28bd16c4e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload7.C @@ -0,0 +1,31 @@ +// { dg-do run } + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 17 Oct 2005 <nathan@codesourcery.com> + +// PR 24386:Wrong virtual function called +// Origin: Scott Snyder snyder@fnal.gov + +struct A +{ + virtual int Foo () { return 1; } +}; +struct B : public A +{ + virtual int Foo () { return 2; } +}; + +template <class T> +int Bar (T *a) +{ + if (static_cast<A*>(a)->A::Foo () != 1) + return 1; + if (static_cast<A*>(a)->Foo () != 2) + return 2; + return 0; +} + +int main () +{ + return Bar (new B); +} diff --git a/gcc/testsuite/g++.dg/template/overload8.C b/gcc/testsuite/g++.dg/template/overload8.C new file mode 100644 index 000000000..cc6a05b70 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload8.C @@ -0,0 +1,7 @@ +// PR c++/24915 + +struct A +{ + template<int> void foo() {} + template<int> int foo() {} +}; diff --git a/gcc/testsuite/g++.dg/template/overload9.C b/gcc/testsuite/g++.dg/template/overload9.C new file mode 100644 index 000000000..8aeab9eaa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload9.C @@ -0,0 +1,18 @@ +// PR c++/32232 + +template <typename T> struct A; +template <typename T> struct B {}; +template <typename T> A<T>& operator<<(A<T>&, const B<T>&); + +template <typename T> +struct A +{ + A<T>& operator<<(A<T>& (*)(A<T>&)); +}; + +template <typename T> A<T>& foo(A<T>&); +extern A<char> c; + +int main () { + c << (1, foo); // { dg-error "no context" } +} diff --git a/gcc/testsuite/g++.dg/template/param1.C b/gcc/testsuite/g++.dg/template/param1.C new file mode 100644 index 000000000..a8c379125 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/param1.C @@ -0,0 +1,12 @@ +// PR c++/22233 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// { dg-do compile } + +template<int> struct A // { dg-error "declaration" } +{ + A(); +}; + +template<int N, char> A<N>::A() {} // { dg-error "invalid use of incomplete type" } + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/param2.C b/gcc/testsuite/g++.dg/template/param2.C new file mode 100644 index 000000000..d25b85565 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/param2.C @@ -0,0 +1,8 @@ +// Origin PR c++/47311 +// { dg-do compile } + +template < typename > class A0; +template <class Key, class T, template < typename TF = T> class TC = A0> class B0; + +template <int> class A1; +template <class Key, class T, template <T p> class TC = A1> class B1; diff --git a/gcc/testsuite/g++.dg/template/param3.C b/gcc/testsuite/g++.dg/template/param3.C new file mode 100644 index 000000000..0c1e70326 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/param3.C @@ -0,0 +1,12 @@ +// PR c++/49418 + +template <class T> +void f (const T t) +{ + t = 1; // { dg-error "" } +} + +int main() +{ + f(1); +} diff --git a/gcc/testsuite/g++.dg/template/partial-specialization.C b/gcc/testsuite/g++.dg/template/partial-specialization.C new file mode 100644 index 000000000..feaeb2fbf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization.C @@ -0,0 +1,22 @@ +// Contributed by Gabriel Dos Reis <gdr@codesourcery.com> +// Origin: philippeb@videotron.ca +// { dg-do compile } + +struct B +{ + int i; +}; + +template <class _T, class _M, _M _T::* _V> + struct A; + +template <class _T, int _T::* _V> + struct A<_T, int, _V> + { + }; + +int main() +{ + A<B, int, & B::i> a; +} + diff --git a/gcc/testsuite/g++.dg/template/partial1.C b/gcc/testsuite/g++.dg/template/partial1.C new file mode 100644 index 000000000..41ea53039 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial1.C @@ -0,0 +1,36 @@ +// { dg-do run } +// Origin: Jo Totland <jototland@hotmail.com> + +// PR c++/6620 +// Partial specialization involving expression of non-type template +// parameter causes ICE. + +extern "C" void abort(); + +template <int N> struct HoldInt +{ +}; + +template <class A, class B> struct Add +{ +}; + +template <int N> struct Add<HoldInt<N>, HoldInt<-N> > +{ + typedef int type; + int f() { return 0; } +}; + +template <int N, int M> +struct Add<HoldInt<N>, HoldInt<M> > +{ + typedef HoldInt<N+M> type; + int f() { return 1; } +}; + +int main() { + Add<HoldInt<1>, HoldInt<-1> > a; + Add<HoldInt<1>, HoldInt<-2> > b; + if (a.f() != 0 || b.f() != 1) + abort(); +} diff --git a/gcc/testsuite/g++.dg/template/partial12.C b/gcc/testsuite/g++.dg/template/partial12.C new file mode 100644 index 000000000..05a3eca97 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial12.C @@ -0,0 +1,27 @@ +// PR c++/46105 + +template< typename T > +struct empty { // support class is like stripped-down enable_if + typedef void type; +}; + +template< class T, typename v = void > // v is always void! +struct element { + typedef typename T::value_type type; +}; + +template< class T > // T in deduced context, T::element_type is SFINAE: +struct element< T, typename empty< typename T::element_type >::type > { + typedef typename T::element_type type; +}; + +template< class T > +struct element< T const, typename empty< typename T::element_type >::type > { + typedef typename T::element_type const type; +}; + +struct has_et { + typedef int element_type; +}; + +element<has_et const>::type ip = 0; diff --git a/gcc/testsuite/g++.dg/template/partial2.C b/gcc/testsuite/g++.dg/template/partial2.C new file mode 100644 index 000000000..ebfdce278 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial2.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Origin: lorgon1@yahoo.com + +// PR c++/11154: Multi-level template argument in partial ordering of +// class template + +template <class A> struct Outer { + template <class T, class U = void, class V = void> struct Foo {}; + template <class T, class U> struct Foo<T,U,void> {}; + template <class T> struct Foo<T,void,void> {}; +}; + +Outer<int>::Foo<int,void,void> f; diff --git a/gcc/testsuite/g++.dg/template/partial3.C b/gcc/testsuite/g++.dg/template/partial3.C new file mode 100644 index 000000000..986267514 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial3.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// Origin: John Maddock <john at johnmaddock dot co dot uk> +// PR c++/13997: Error while matching partial specialization of array type + +template <typename T> +struct is_array; + +template <typename T, unsigned int N> +struct is_array<T[N]>; + +template <typename T, unsigned int N> +struct is_array<const T[N]> {}; + +template struct is_array<int const[2]>; diff --git a/gcc/testsuite/g++.dg/template/partial4.C b/gcc/testsuite/g++.dg/template/partial4.C new file mode 100644 index 000000000..8ea202cdf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial4.C @@ -0,0 +1,16 @@ +// PR c++/25342 + +template < typename eval > +struct tpl_seq_search { + typedef typename eval::enum_type Enum; + template < Enum first, Enum last > + struct range { + }; + template < Enum val > + struct range<val,val> { + }; +}; +struct xxx { + typedef int enum_type; + tpl_seq_search<xxx>::range<0, 1> a; +}; diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C new file mode 100644 index 000000000..aa32e3b8a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial5.C @@ -0,0 +1,24 @@ +// PR c++/33964 + +template<typename T> +struct X { }; + +template<typename T> +struct X<typename T::foo> { }; // { dg-error "not used|T" } + +template<int N> +struct X<int[N]> {}; // okay + + +template<typename T, typename T::foo V> +struct Y { }; + +template<typename T, typename U, U v> +struct Y<T, v> { }; // { dg-error "not used|U" } + + +template<typename T, T V> +struct Z { }; + +template<typename T> +struct Z<T, (T)0> { }; // { dg-error "involves template parameter" } diff --git a/gcc/testsuite/g++.dg/template/partial6.C b/gcc/testsuite/g++.dg/template/partial6.C new file mode 100644 index 000000000..80bbfe3c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial6.C @@ -0,0 +1,31 @@ +// PR c++/41703 +// The second GetAllSize template is more specialized because even though +// deduction on each parameter type succeeds, we never get a template +// argument for its X to make it match the first template. + +template <typename T, int (T::*)() const> +struct TSizeEnabler +{ + typedef T TClass; +}; + +template <typename X> +int +GetAllSize(const X &Var) +{ return sizeof(Var); } + +template <typename X> +int +GetAllSize(const typename TSizeEnabler<X, &X::func>::TClass &Var) +{ return Var.func(); } + +struct H +{ + int func() const; +}; + +int main() +{ + H b; + return GetAllSize< H >(b); +} diff --git a/gcc/testsuite/g++.dg/template/partial7.C b/gcc/testsuite/g++.dg/template/partial7.C new file mode 100644 index 000000000..0fd157fdc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial7.C @@ -0,0 +1,10 @@ +// PR c++/43559 + +template<typename T, typename U> void f(U&) { } +template<typename T, typename U> void f(T const&) { } + +int main() +{ + int a; + f<int, int const>(a); +} diff --git a/gcc/testsuite/g++.dg/template/partial8.C b/gcc/testsuite/g++.dg/template/partial8.C new file mode 100644 index 000000000..4db7e1868 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial8.C @@ -0,0 +1,4 @@ +// PR c++/32505 +template <class T> struct A { }; +A<int*> a; +template <class T> struct A<T*> { }; // { dg-error "A<int\\*>" } diff --git a/gcc/testsuite/g++.dg/template/pr23510.C b/gcc/testsuite/g++.dg/template/pr23510.C new file mode 100644 index 000000000..1c3180f83 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr23510.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-ftemplate-depth-15" } +template<unsigned int nFactor> +struct Factorial +{ + enum { nValue = nFactor * Factorial<nFactor - 1>::nValue }; // { dg-error "depth exceeds maximum" } + // { dg-message "recursively instantiated" "" { target *-*-* } 6 } + // { dg-error "incomplete type" "" { target *-*-* } 6 } +} // { dg-error "expected ';' after" } + + template<> + struct Factorial<0> + { + enum { nValue = 1 }; + }; + + static const unsigned int FACTOR = 20; + +int main() +{ + Factorial<FACTOR>::nValue; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/pr28284.C b/gcc/testsuite/g++.dg/template/pr28284.C new file mode 100644 index 000000000..7ef9aa12b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr28284.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +template<int> struct A +{ + static const int i=x; /* { dg-error "was not declared in this scope" } */ + static const int j, k; +}; + +template<int N> const int A<N>::j = i; +template<int N> const int A<N>::k = j; + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/pr28301.C b/gcc/testsuite/g++.dg/template/pr28301.C new file mode 100644 index 000000000..a7a008478 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr28301.C @@ -0,0 +1,18 @@ +// PR c++/28301 +// { dg-do compile } + +template<typename> struct A +{ + template<int> void foo() +}; // { dg-error "initializer" } + +template<> struct A<void> +{ + template<int> void foo(); +}; + +void bar() +{ + A<void> a; + a.foo<0>(); +} diff --git a/gcc/testsuite/g++.dg/template/pr32519.C b/gcc/testsuite/g++.dg/template/pr32519.C new file mode 100644 index 000000000..e93c7b476 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr32519.C @@ -0,0 +1,16 @@ +// PR 32519 +// { dg-do compile } + +struct B +{ +protected: + template <class T> void f (); // { dg-error "protected" } +}; + +struct D : public B +{ + void g (B* b) + { + b->f<int> (); // { dg-error "context" } + } +}; diff --git a/gcc/testsuite/g++.dg/template/pr35240.C b/gcc/testsuite/g++.dg/template/pr35240.C new file mode 100644 index 000000000..47455b658 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr35240.C @@ -0,0 +1,12 @@ +// PR c++/35240 +// { dg-do compile } + + +template<int> struct A {}; + +template<int N> A<sizeof(new int[N][N])> foo(); // { dg-message "unimplemented" } + +void bar() +{ + foo<1>(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/pr39425.C b/gcc/testsuite/g++.dg/template/pr39425.C new file mode 100644 index 000000000..d55f547e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr39425.C @@ -0,0 +1,18 @@ +// PR c++/39425 +// { dg-do compile } + +class a { + + template<unsigned int s> + struct _rec { + static const char size = _rec< (s >> 1) >::size; + }; + + template<> // { dg-error "explicit" } + struct _rec <0> { + static const char size = 0; + }; + + static const unsigned int value = _rec < 1 >::size; + +} // { dg-error "after class definition" } diff --git a/gcc/testsuite/g++.dg/template/pr4926-1.C b/gcc/testsuite/g++.dg/template/pr4926-1.C new file mode 100644 index 000000000..ec2b226fe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr4926-1.C @@ -0,0 +1,18 @@ +// PR c++/4926 +// { dg-do compile } + +template <unsigned> struct X { typedef int Type; }; +template <typename T> struct Y { char array[1]; }; + +template<typename T> Y<T> P(T); // acts as "Y<typeof(T)>" + +struct F { int operator()() const; }; + +template <typename T> +typename X<sizeof(P( T()() ).array)>::Type foo(); + +void +bar () +{ + foo<F>(); +} diff --git a/gcc/testsuite/g++.dg/template/pr54858.C b/gcc/testsuite/g++.dg/template/pr54858.C new file mode 100644 index 000000000..51610ad68 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr54858.C @@ -0,0 +1,21 @@ +// PR c++/54858 +// { dg-do compile } + +template <int> struct A {}; +template <typename T, T *> struct B {}; +template <typename D> struct C +{ + A<0> c0; B<A<0>, &C::c0> d0; // { dg-error "could not convert template argument" } + A<0> c1; B<A<0>, &C::c1> d1; // { dg-error "could not convert template argument" } + A<0> c2; B<A<0>, &C::c2> d2; // { dg-error "could not convert template argument" } + A<0> c3; B<A<0>, &C::c3> d3; // { dg-error "could not convert template argument" } + A<0> c4; B<A<0>, &C::c4> d4; // { dg-error "could not convert template argument" } + A<0> c5; B<A<0>, &C::c5> d5; // { dg-error "could not convert template argument" } + A<0> c6; B<A<0>, &C::c6> d6; // { dg-error "could not convert template argument" } + A<0> c7; B<A<0>, &C::c7> d7; // { dg-error "could not convert template argument" } + A<0> c8; B<A<0>, &C::c8> d8; // { dg-error "could not convert template argument" } + A<0> c9; B<A<0>, &C::c9> d9; // { dg-error "could not convert template argument" } + A<0> ca; B<A<0>, &C::ca> da; // { dg-error "could not convert template argument" } + A<0> cb; B<A<0>, &C::cb> db; // { dg-error "could not convert template argument" } +}; +C<int> e; diff --git a/gcc/testsuite/g++.dg/template/pretty1.C b/gcc/testsuite/g++.dg/template/pretty1.C new file mode 100644 index 000000000..99cbcd64a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pretty1.C @@ -0,0 +1,43 @@ +// { dg-do run } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Sep 2002 <nathan@codesourcery.com> + +// PR 7768 template dtor pretty function wrong + +#include <string.h> + +static size_t current = 0; +static bool error = false; + +static char const *names[] = +{ + "X<T>::X() [with T = void]", + "X<T>::~X() [with T = void]", + 0 +}; + +void Verify (char const *ptr) +{ + error = strcmp (ptr, names[current++]); +} + +template <typename T> +struct X +{ + X() { Verify (__PRETTY_FUNCTION__); } + ~X() { Verify (__PRETTY_FUNCTION__); } +}; + +int main() +{ + { + X<void> x; + + if (error) + return current; + } + if (error) + return current; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/pseudodtor1.C b/gcc/testsuite/g++.dg/template/pseudodtor1.C new file mode 100644 index 000000000..cf7c254d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor1.C @@ -0,0 +1,44 @@ +// PR c++/32384 +// { dg-do compile } + +struct A +{ + typedef int T; + T foo (); + + A () { foo ().~T (); } +}; + +template<typename> struct B +{ + typedef int T; + T foo (); + + B () { foo ().~T (); } +}; + +template<typename T> struct C +{ + T t; + C () { t.~T (); } +}; + +template<typename S> struct D +{ + typedef int T; + S foo (); + + D () { foo ().~T(); } +}; + +struct Z +{ + Z () {} + ~Z () {} +}; + +A a; +B<int> b; +C<int> c1; +C<Z> c2; +D<int> d; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor2.C b/gcc/testsuite/g++.dg/template/pseudodtor2.C new file mode 100644 index 000000000..796aff078 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor2.C @@ -0,0 +1,18 @@ +// PR c++/32384 +// { dg-do compile } + +template<typename S> struct D +{ + typedef int T; + S foo (); + + D () { foo ().~T(); } // { dg-error "is not of type" } +}; + +struct Z +{ + Z () {} + ~Z () {} +}; + +D<Z> d; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor3.C b/gcc/testsuite/g++.dg/template/pseudodtor3.C new file mode 100644 index 000000000..5f392f4e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor3.C @@ -0,0 +1,43 @@ +// PR c++/32241 +// { dg-do compile } + +struct A +{ + typedef int T; + T &foo (); + A () { foo.~T (); } // { dg-error "does not have class type|expected" } +}; + +template <typename T> struct B +{ + T &foo (); + B () { foo.~T (); } // { dg-error "invalid use of member" } +}; + +B<int> b; + +template <typename T, typename S> struct C +{ + T t; + C () { t.~S (); } // { dg-error "is not of type" } +}; + +C<int, long int> c; + +template <typename T> struct D +{ + T t; + typedef long int U; + D () { t.~U (); } // { dg-error "is not of type" } +}; + +D<int> d; + +template <typename T> struct E +{ + T &foo (); + typedef long int U; + E () { foo.~U (); } // { dg-error "is not of type" } +}; + +E<int> e; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor4.C b/gcc/testsuite/g++.dg/template/pseudodtor4.C new file mode 100644 index 000000000..40178bf48 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor4.C @@ -0,0 +1,10 @@ +// PR c++/34068 +// { dg-do compile } + +template <typename> struct A +{ + typedef int X; + A () { T (). ~X (); } // { dg-error "there are no arguments to|fpermissive|was not declared in this scope" } +}; + +A <int> a; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor5.C b/gcc/testsuite/g++.dg/template/pseudodtor5.C new file mode 100644 index 000000000..751e662ad --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor5.C @@ -0,0 +1,23 @@ +// PR c++/37563 + +struct A {}; + +template<int> struct Traits +{ + typedef void X; +}; + +template<> struct Traits<0> +{ + typedef A X; +}; + +template<int N> struct B +{ + typedef typename Traits<N>::X Y; + + void foo(Y y) + { + y.Y::A::~A(); + } +}; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor6.C b/gcc/testsuite/g++.dg/template/pseudodtor6.C new file mode 100644 index 000000000..4438b6ffb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pseudodtor6.C @@ -0,0 +1,9 @@ +// PR c++/47971 + +template <typename> struct S +{ + typedef double T; + S () { T ().~T (); } +}; + +S<double> s; diff --git a/gcc/testsuite/g++.dg/template/ptrmem1.C b/gcc/testsuite/g++.dg/template/ptrmem1.C new file mode 100644 index 000000000..ebd6a201a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem1.C @@ -0,0 +1,33 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com> + +// PR 3716 tsubsting a pointer to member function did not create a +// pointer to member function. + +template <class C, class T, T C::*M> +struct Closure +{ + T operator() (C & c) const { return (c.*M); } +}; + +template <class C, class T, T (C::* M)()> +struct Closure<C, T (), M> +{ + T operator()(C & c) const { return (c.*M)(); } +}; + +struct A +{ + int get(); +}; + +static Closure<A, int (), & A::get> get_closure; + + +void Foo () +{ + A a; + get_closure (a); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem10.C b/gcc/testsuite/g++.dg/template/ptrmem10.C new file mode 100644 index 000000000..b76d5e80a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem10.C @@ -0,0 +1,21 @@ +// PR c++/15096 + +template <typename T_> +class C1 +{ +public: + C1 (); + ~C1 (); + const int C1<T_>::* getPtr () const; + +private: + int x; + T_ y; +}; + + +template <typename T_> +const int C1<T_>::* C1<T_>::getPtr () const +{ return &C1<T_>::x; } + + diff --git a/gcc/testsuite/g++.dg/template/ptrmem11.C b/gcc/testsuite/g++.dg/template/ptrmem11.C new file mode 100644 index 000000000..a88b70660 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem11.C @@ -0,0 +1,19 @@ +// PR c++/18407 + +template <typename Klasse> +struct the_base{ + template <void (Klasse::*Fn)()> void foo() { } +}; + +template <typename T> +struct derivedT: the_base<derivedT<T> > { + typedef the_base<derivedT<T> > parent; + void ice(){ + this->parent::template foo< &derivedT<T>::ice>(); + } +}; + +int main() { + derivedT<int> dT; + dT.ice(); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem12.C b/gcc/testsuite/g++.dg/template/ptrmem12.C new file mode 100644 index 000000000..717b86988 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem12.C @@ -0,0 +1,29 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 17 Mar 2005 <nathan@codesourcery.com> + +// PR 20465 +// Origin: Matthias Klose <doko@debian.org> +// Andrew Pinski <pinskia@gcc.gnu.org> + +template <class _Ret, class _Tp> +void mem_fun_ref(_Ret (_Tp::*__f)()); + +struct A { + double f(); +}; + +void h () +{ + mem_fun_ref(&A::f); +} + +template <class T> +void f() +{ + mem_fun_ref(&A::f); +} + +void g() +{ + f<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem13.C b/gcc/testsuite/g++.dg/template/ptrmem13.C new file mode 100644 index 000000000..84374ea05 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem13.C @@ -0,0 +1,11 @@ +// PR c++/20734 + +struct A; +void blah(int A::*); +struct A{ + int a; +}; +template<typename T> +void hoho(){ + blah(&A::a); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem14.C b/gcc/testsuite/g++.dg/template/ptrmem14.C new file mode 100644 index 000000000..30eb1ebcc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem14.C @@ -0,0 +1,12 @@ +// PR c++/15875 + +struct A +{ + void foo(); +}; + +template<int> void bar() +{ + typedef void (A::*fptr)(); + fptr ptr = &A::foo; +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem15.C b/gcc/testsuite/g++.dg/template/ptrmem15.C new file mode 100644 index 000000000..b52ff8917 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem15.C @@ -0,0 +1,9 @@ +// PR c++/19894 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> + +template<typename T> struct A +{ + T A::* p; // { dg-error "void" } +}; + +A<void> a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/ptrmem16.C b/gcc/testsuite/g++.dg/template/ptrmem16.C new file mode 100644 index 000000000..770581db8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem16.C @@ -0,0 +1,20 @@ +// PR c++/25369 +// { dg-do link } + +template <typename> struct A +{ + void foo() {} +}; + +void bar(void (A<int>::*)()) {} + +template <int> void baz() +{ + bar(&A<int>::foo); +} + +int main() +{ + baz<0>(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem17.C b/gcc/testsuite/g++.dg/template/ptrmem17.C new file mode 100644 index 000000000..5c5ee3fc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem17.C @@ -0,0 +1,10 @@ +// PR c++/28346 + +template<int> struct A +{ + int& i; + A(); + ~A() { &A::i; } // { dg-error "reference" } +}; + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/ptrmem18.C b/gcc/testsuite/g++.dg/template/ptrmem18.C new file mode 100644 index 000000000..c3124cd81 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem18.C @@ -0,0 +1,49 @@ +// PR c++/33616 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); + +struct S { + int c; + S () : c (0) {} + virtual void f1 () { c += 1; } + virtual void f2 () { c += 16; } +}; + +struct T { + S s; +}; + +typedef void (S::*Q) (); + +template <Q P> +void test1 (T *t) +{ + (t->s.*P)(); +} + +template <Q P> +void test2 (T *t) +{ + S &s = t->s; + (s.*P)(); +} + +int +main () +{ + T t; + test1 <&S::f1> (&t); + if (t.s.c != 1) + abort (); + test1 <&S::f2> (&t); + if (t.s.c != 17) + abort (); + test2 <&S::f1> (&t); + if (t.s.c != 18) + abort (); + test2 <&S::f2> (&t); + if (t.s.c != 34) + abort (); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem19.C b/gcc/testsuite/g++.dg/template/ptrmem19.C new file mode 100644 index 000000000..52711c6cb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem19.C @@ -0,0 +1,19 @@ +// PR c++/40780 +// { dg-do compile } + +template <class T1, typename T2, typename T3> +struct A +{ + typedef T2 (T1::*m) (T3); + A (m) {} +}; +struct B; +struct C +{ + void foo (B *); +}; +typedef A <C, void, B *> D; +typedef void (C::*E) (B *); +struct F; +typedef void (C::*G) (F); +D d ((E) (G) & C::foo); diff --git a/gcc/testsuite/g++.dg/template/ptrmem2.C b/gcc/testsuite/g++.dg/template/ptrmem2.C new file mode 100644 index 000000000..191904736 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem2.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com> + +// We'd tsubst a pointer to member reference + +struct A {}; + +template <typename T> T A::* Foo (); // { dg-message "note" } + +void Baz () +{ + Foo <int &> (); // { dg-error "no matching function" "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 14 } +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem20.C b/gcc/testsuite/g++.dg/template/ptrmem20.C new file mode 100644 index 000000000..dee3c629a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem20.C @@ -0,0 +1,17 @@ +// PR c++/43079 + +struct A {}; + +struct B +{ + void foo() const; + void foo(); +}; + +template<void (A::*)()> void bar(); // { dg-message "note" } + +void baz() +{ + bar<&B::foo>(); // { dg-error "not a valid template argument|no match" } + // { dg-message "candidate" "candidate note" { target *-*-* } 15 } +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem21.C b/gcc/testsuite/g++.dg/template/ptrmem21.C new file mode 100644 index 000000000..c30fa38fc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem21.C @@ -0,0 +1,37 @@ +// PR c++/43868 +// { dg-options "-g" } + +struct Foo +{ + virtual void do_something() = 0; +}; + +template <typename T> +struct Foo_impl; + +template <typename R, typename O> +struct Foo_impl<R (O::*)() const> : public Foo +{ + struct Helper + { + typedef int Some_type; + operator Some_type () const { return 0; } + Helper( R (O::*)() const) {} + }; + + void do_something() { Helper( 0); }; +}; + +void register_foo_internal( Foo*) {}; + +template <typename TT> +void register_foo( TT) { register_foo_internal( new Foo_impl<TT>()); } + +struct Bar +{ +}; + +void setup() +{ + register_foo( (int (Bar::*) () const) 0); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem22.C b/gcc/testsuite/g++.dg/template/ptrmem22.C new file mode 100644 index 000000000..762f377f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem22.C @@ -0,0 +1,29 @@ +// PR c++/44778 + +enum Healpix_Ordering_Scheme { RING, NEST }; + +class Healpix_Base + { + protected: + Healpix_Ordering_Scheme scheme_; + int nest2ring (int pix) const; + int ring2nest (int pix) const; + + typedef int (Healpix_Base::*swapfunc)(int pix) const; + }; + +template<typename T> class Healpix_Map: public Healpix_Base + { + public: + void Import_nograde (const Healpix_Map<T> &orig) + { + swapfunc swapper = (scheme_ == NEST) ? + &Healpix_Map::ring2nest : &Healpix_Map::nest2ring; + } + }; + +int main() + { + Healpix_Map<double> a,b; + a.Import_nograde(b); + } diff --git a/gcc/testsuite/g++.dg/template/ptrmem23.C b/gcc/testsuite/g++.dg/template/ptrmem23.C new file mode 100644 index 000000000..28c0a63e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem23.C @@ -0,0 +1,22 @@ +// PR c++/56247 + +struct Base { + void method() {} +}; + +typedef void (Base::*MemPtr)(); + +// Template with a member function pointer "non-type parameter". +template<MemPtr func> +struct Wrapper {}; + +template<class C> +struct Child : public Base { + // Templated derived class instantiates the Wrapper with the same parameter + // in two different virtual methods. + void foo() { typedef Wrapper<&Base::method> W; } + void bar() { typedef Wrapper<&Base::method> W; } +}; + +// Instantiate Child with some type. +template class Child<int>; diff --git a/gcc/testsuite/g++.dg/template/ptrmem3.C b/gcc/testsuite/g++.dg/template/ptrmem3.C new file mode 100644 index 000000000..fda7bf10a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem3.C @@ -0,0 +1,22 @@ +// Origin: Theo Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr> + +template <typename T,double (T::*fun)() const> +struct I { +}; + +struct R { + R() { } +}; + +class H: public R { +public: + H(): R() { } + double& f() { return a; } + double f() const { return 1.0; } + double a; +}; + +struct A { + typedef I<H,&H::f> F; + A() { } +}; diff --git a/gcc/testsuite/g++.dg/template/ptrmem4.C b/gcc/testsuite/g++.dg/template/ptrmem4.C new file mode 100644 index 000000000..62262c4b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem4.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Scott Snyder <snyder@fnal.gov> + +// PR c++/8849 +// Pointer to member function template argument deduction ICE. + + +template <class CONT> void queryAliases(CONT& fill_me); // { dg-message "queryAliases|no known conversion" } + +struct SpyExample +{ + void ready(); + void inputs(); +}; + +void SpyExample::ready() +{ + queryAliases(inputs); // { dg-error "matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 19 } +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem5.C b/gcc/testsuite/g++.dg/template/ptrmem5.C new file mode 100644 index 000000000..50a7e77f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem5.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 24 Mar 2003 <nathan@codesourcery.com> + +// PR 10119 (part). We failed to tsubst the args of a template-id-expr + +template <class T, void (T::* const U)()> struct Good +{ + static int const value = 0; +}; + +struct A +{ + template <typename U> void good () + { + int s_id = Good<A, &A::good<U> >::value; + } +}; + + +int main() +{ + A().good<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem6.C b/gcc/testsuite/g++.dg/template/ptrmem6.C new file mode 100644 index 000000000..a355cfe89 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem6.C @@ -0,0 +1,10 @@ +struct S {}; + +void g(int S::**); + +template <typename T> +void f (int T::* volatile *p) { + g(p); // { dg-error "conversion" } +} + +template void f(int S::* volatile *); // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/ptrmem7.C b/gcc/testsuite/g++.dg/template/ptrmem7.C new file mode 100644 index 000000000..cd907f212 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem7.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// Origin: <togawa at acm dot arg> +// c++/2094: unsupported 'ptrmem_cst' in type unification + +struct R +{ + int i; +}; + +struct S +{ + int i; + int j; +}; + +struct S2 : S +{}; + +template<int S::*p, typename> +struct X +{ + X (); + template<typename U> X(const X<p,U> &); +}; + +X<&S::i,S> x = X<&S::i,S>(); +X<&S::i,S> x2 = X<&S2::i,S>(); +X<&S::i,S> y = X<&S::j,S>(); // { dg-error "" } +X<&S::i,S> z = X<&R::i,S>(); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/ptrmem8.C b/gcc/testsuite/g++.dg/template/ptrmem8.C new file mode 100644 index 000000000..d0473f5cc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem8.C @@ -0,0 +1,24 @@ +// { dg-do compile } +// Origin: <marco dot franzen at bigfoot dot com> +// PR c++/10126: Handle ptmf default conversions while matching a template +// argument + +struct B +{ + int I () const; + int I (); +}; + +struct D : B {}; + +template <int (D::*fun)() const> int Get(); // { dg-message "note" } + +int main () +{ + Get<&B::I>(); // { dg-error "not a valid template argument" "not valid" } + // { dg-error "no match" "no match" { target *-*-* } 18 } + // { dg-message "note" "note" { target *-*-* } 18 } + Get<&D::I>(); // { dg-error "not a valid template argument" "not valid" } + // { dg-error "no match" "no match" { target *-*-* } 21 } + // { dg-message "note" "note" { target *-*-* } 21 } +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem9.C b/gcc/testsuite/g++.dg/template/ptrmem9.C new file mode 100644 index 000000000..55e881599 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem9.C @@ -0,0 +1,9 @@ +// PR c++/15329 + +struct S {}; + +template <typename> struct X { + S s; + void foo (void (S::*p)()) + { (s.*p)(); } +}; diff --git a/gcc/testsuite/g++.dg/template/pure1.C b/gcc/testsuite/g++.dg/template/pure1.C new file mode 100644 index 000000000..68dbe6bf0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pure1.C @@ -0,0 +1,6 @@ +// PR c++/26122 + +struct A +{ + template<int> void foo() = 1; // { dg-error "pure|non-virtual" } +}; diff --git a/gcc/testsuite/g++.dg/template/qual1.C b/gcc/testsuite/g++.dg/template/qual1.C new file mode 100644 index 000000000..8fa79b3d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qual1.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +template<class T> +class Link_array +{ +public: + void sort (int (*compare) (T *const&,T *const&)); +}; + +int shift_compare (int *const &, int *const &) {} + +template<class T> void +Link_array<T>::sort (int (*compare) (T *const&,T *const&)) +{ +} + +void f () +{ + Link_array<int> clashes; + clashes.sort (shift_compare); +} diff --git a/gcc/testsuite/g++.dg/template/qual2.C b/gcc/testsuite/g++.dg/template/qual2.C new file mode 100644 index 000000000..aa6b10ea4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qual2.C @@ -0,0 +1,29 @@ +// { dg-do run } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 23 Jan 2003 <nathan@codesourcery.com> + +// PR9415. Forgot a lookup was scoped + +int here; +int there; + +struct B +{ + virtual int activate() {return !here++;} +}; + +template <class K> +struct TPL : public B +{ + int activate() + { + return !there++ && B::activate(); + } +}; + +int main () +{ + TPL<int> i; + return !i.activate (); +} diff --git a/gcc/testsuite/g++.dg/template/qualified-id1.C b/gcc/testsuite/g++.dg/template/qualified-id1.C new file mode 100644 index 000000000..602be5bf1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualified-id1.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 4 Sep 2003 <nathan@codesourcery.com> +// Origin Volker Reichelt reichelt@igpm.rwth-aachen.de + +// PR 11922 + +struct A +{ + template <bool> struct B; + struct C; +}; + +template <> struct A::B<false> {}; + +template <typename T> void foo() +{ + T::C (); // { dg-error "parsed as a non-type|if a type is meant" } + T::template B<false>(); // { dg-error "parsed as a non-type" "non-type" } + // { dg-message "if a type" "if a type" { target *-*-* } 20 } +} + +void bar() +{ + foo<A>(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/qualified-id2.C b/gcc/testsuite/g++.dg/template/qualified-id2.C new file mode 100644 index 000000000..e88e85474 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualified-id2.C @@ -0,0 +1,27 @@ +// PR c++/44587 +// { dg-do run } + +template <const char *N> struct A { static const char *p; }; +template <const char *N> const char *A<N>::p = N; +template <class T> struct B { static const char c[1]; typedef A<B<T>::c> C; }; +template <class T> const char B<T>::c[1] = ""; +template <class T> struct D { static const char c[1]; typedef A<c> C; }; +template <class T> const char D<T>::c[1] = ""; + +template <int& I> struct E { static int *ip; }; +template <int& I> int* E<I>::ip = &I; +template <class T> struct F { static int i; typedef E<F<T>::i> C; }; +template <class T> int F<T>::i; +template <class T> struct G { static int i; typedef E<i> C; }; +template <class T> int G<T>::i; + +#define AS(X) if (!(X)) return 1; +int main() +{ + AS(B<int>::C::p == B<int>::c); + AS(B<float>::C::p == B<float>::c); + AS(B<float>::C::p != B<int>::c); + AS(D<int>::C::p == D<int>::c); + AS(D<float>::C::p == D<float>::c); + AS(D<float>::C::p != D<int>::c); +} diff --git a/gcc/testsuite/g++.dg/template/qualified-id3.C b/gcc/testsuite/g++.dg/template/qualified-id3.C new file mode 100644 index 000000000..c769a529c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualified-id3.C @@ -0,0 +1,14 @@ +// PR c++/44587 + +template <const int N> struct A { }; +template <class T> struct B { + static const int c; // { dg-message "not initialized with a constant expression" } + typedef A<B<T>::c> C; // { dg-error "constant expression|template argument" } +}; +template <class T> const int B<T>::c = sizeof (T); + +template <const int N> struct D { }; +template <class T> struct E { + static const int c = sizeof (T); + typedef D<E<T>::c> F; // OK +}; diff --git a/gcc/testsuite/g++.dg/template/qualttp1.C b/gcc/testsuite/g++.dg/template/qualttp1.C new file mode 100644 index 000000000..b97ef4275 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp1.C @@ -0,0 +1,22 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +struct A +{ + template <class T> class B {}; +}; + +template <class T> struct X +{ +}; + +template <class T> struct C +{ + X<T::template B> x; // { dg-error "type" } +}; + +int main() +{ + C<A> c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp10.C b/gcc/testsuite/g++.dg/template/qualttp10.C new file mode 100644 index 000000000..8734ddc67 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp10.C @@ -0,0 +1,13 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <template <class> class TT> class C { +}; + +template <class T> struct D { + template <class U> class B {}; + C<D<T>::template B> c; +}; + +D<int> d; diff --git a/gcc/testsuite/g++.dg/template/qualttp11.C b/gcc/testsuite/g++.dg/template/qualttp11.C new file mode 100644 index 000000000..fa5c860c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp11.C @@ -0,0 +1,23 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do link } + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT> struct X +{ + TT<int> y; +}; + +template <class T> struct C +{ + X<T::template B> x; +}; + +int main() +{ + C<A> c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp12.C b/gcc/testsuite/g++.dg/template/qualttp12.C new file mode 100644 index 000000000..ebd4b645c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp12.C @@ -0,0 +1,24 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do link } + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT> void f() +{ + TT<int> y; +} + +template <class T> struct C +{ + void g() { f<T::template B>(); } +}; + +int main() +{ + C<A> c; + c.g(); +} diff --git a/gcc/testsuite/g++.dg/template/qualttp13.C b/gcc/testsuite/g++.dg/template/qualttp13.C new file mode 100644 index 000000000..eefc60493 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp13.C @@ -0,0 +1,27 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + +template <class U> struct A +{ + template <class V> struct AA { + template <class T> struct B { + int i; + B() : i(1) {} + }; + }; +}; + +template <template <class> class TT> struct X +{ + TT<int> y; +}; + +template <class T, class U> struct C +{ + X<T::template AA<U>::template B> x; +}; + +int main() +{ + C<A<char>, int> c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp14.C b/gcc/testsuite/g++.dg/template/qualttp14.C new file mode 100644 index 000000000..055855759 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp14.C @@ -0,0 +1,30 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do link } + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT, class T> struct X +{ + TT<int> y; + T z; +}; + +template <class T> struct X<T::template B, T> +{ + typename T::template B<int> y; + T z; +}; + +template <class T> struct C +{ + X<T::template B, A> x; +}; + +int main() +{ + C<A> c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp15.C b/gcc/testsuite/g++.dg/template/qualttp15.C new file mode 100644 index 000000000..b1c61195d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp15.C @@ -0,0 +1,33 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT> struct X +{ + TT<int> y; +}; + +template <class T> struct X<T::template B> // { dg-error "previous" } +{ + T z; +}; + +template <class T> struct X<T::template B> // { dg-error "redefinition" } +{ + T z; +}; + +template <class T> struct C +{ + X<T::template B> x; +}; + +int main() +{ + C<A> c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp16.C b/gcc/testsuite/g++.dg/template/qualttp16.C new file mode 100644 index 000000000..1fd0e1f35 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp16.C @@ -0,0 +1,40 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do run } + +extern "C" void abort(); + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT, class T> struct X +{ + TT<int> y; + T z; + int f() { return 0; } +}; + +template <class T> struct X<T::template B, T> +{ + typename T::template B<int> y; + T z; + int f() { return 1; } +}; + +template <class T> struct C +{ + X<T::template B, A> x; +}; + +int main() +{ + C<A> c; + X<A::B, A> x1; + X<A::B, int> x2; + if (x1.f() != 1) + abort(); + if (x2.f() != 0) + abort(); +} diff --git a/gcc/testsuite/g++.dg/template/qualttp17.C b/gcc/testsuite/g++.dg/template/qualttp17.C new file mode 100644 index 000000000..f492ced8c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp17.C @@ -0,0 +1,25 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } +// { dg-options "-fno-inline -fabi-version=1 -Wno-abi" } + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT> struct X +{ +}; + +template <class T> void f(X<T::template B>) +{ +} + +int main() +{ + X<A::B> x; + f<A>(x); +} + +// { dg-final { scan-assembler "\n_?_Z1fI1AEv1XIN1T1BEE\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/template/qualttp18.C b/gcc/testsuite/g++.dg/template/qualttp18.C new file mode 100644 index 000000000..31dfa6a83 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp18.C @@ -0,0 +1,23 @@ +// Copyright (C) 2001, 2002 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +struct A +{ + template <class T> class B {}; +}; + +template <template <class> class TT> struct X +{ + TT<int> y; +}; + +struct C +{ + X<A::template B> x; // { dg-error "" } +}; + +int main() +{ + C c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp19.C b/gcc/testsuite/g++.dg/template/qualttp19.C new file mode 100644 index 000000000..be6676cc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp19.C @@ -0,0 +1,41 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Dec 2001 <nathan@codesourcery.com> + +// PR 2645 + +template <typename T> +struct call_traits +{ + public: + typedef T type_less_spec; +}; + +template <typename T> +struct call_traits<T&> +{ + typedef T type_more_spec; +}; + + +int main() +{ + int num; + + // Two typedefs lead to the instant. of the less spec. ("wrong") template + typedef int& r_type; + typedef const r_type cr_type; + call_traits<cr_type>::type_less_spec var = num; // { dg-error "" "" } + + // The explicit type leads to the instantiation of the "correct" one + call_traits<const int&>::type_more_spec var2 = num; + + // As happen with a single typedef! + typedef const int& std_cr_type; + call_traits<std_cr_type>::type_more_spec var3 = num; + + + // As happen, indeed, without the cv-qualifier + call_traits<r_type>::type_more_spec var4; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp2.C b/gcc/testsuite/g++.dg/template/qualttp2.C new file mode 100644 index 000000000..b25e15f5c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp2.C @@ -0,0 +1,22 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +struct A +{ + template <class T> class B {}; +}; + +template <int i> struct X +{ +}; + +template <class T> struct C +{ + X<T::template B> x; // { dg-error "type" } +}; + +int main() +{ + C<A> c; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp20.C b/gcc/testsuite/g++.dg/template/qualttp20.C new file mode 100644 index 000000000..f42981b52 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp20.C @@ -0,0 +1,36 @@ +// { dg-do compile } +// { dg-options "-pedantic -pedantic-errors" } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Dec 2001 <nathan@codesourcery.com> + +// PR 2645 + +struct AS +{ + typedef void (myT) (); + struct L {}; + +}; + + +template <typename T> struct B1 : T +{ + typedef typename T::L __restrict__ r;// { dg-error "'__restrict__' qualifiers cannot" "" } + typedef typename T::myT __restrict__ p; + + // The following are DR 295 dependent + typedef typename T::myT volatile *myvolatile; + typename T::myT volatile *a; + myvolatile b; +}; +template <typename T> struct B2 : T +{ + // The following are DR 295 dependent + typedef typename T::myT const *myconst; + typename T::myT const *a; + myconst b; +}; + +B1<AS> b1; // { dg-message "instantiated" "" } +B2<AS> b2; diff --git a/gcc/testsuite/g++.dg/template/qualttp21.C b/gcc/testsuite/g++.dg/template/qualttp21.C new file mode 100644 index 000000000..00fcf40c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp21.C @@ -0,0 +1,17 @@ +// Copyright (C) 2002 Free Software Foundation +// Contributed by Roger Sayle <roger@eyesopen.com> +// { dg-do compile } + +template <class A> +class foo { + int _foo; +public: + foo() {} +protected: + ~foo() {} // { dg-error "~foo" } +}; + +int main() +{ + foo<int> a; // { dg-error "context" } +} diff --git a/gcc/testsuite/g++.dg/template/qualttp22.C b/gcc/testsuite/g++.dg/template/qualttp22.C new file mode 100644 index 000000000..21aa7568d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp22.C @@ -0,0 +1,28 @@ +// { dg-do compile } + +// Origin: Philippe Van Deyck <hetadres@email.com> + +// PR c++/13520: Default template template argument that is a qualified id +// with dependent scope. + +template<typename regular_type> class Policy {}; + +template <typename regular_type, template<typename> class OriginalPolicy> +class ChangedPolicy_impl {}; + +template <template<typename> class OriginalPolicy > class ChangedPolicy { +public: + template<typename regular_type> class Type : public + ChangedPolicy_impl<regular_type,OriginalPolicy> { }; +}; + +template <typename regular_type, template<typename> class Policy1, + template<typename> class Policy2 + = ChangedPolicy<Policy1>::template Type> +class Host : public Policy1<regular_type>, public Policy2<regular_type> { }; + +int main() +{ + Host<void, Policy> h; + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/qualttp3.C b/gcc/testsuite/g++.dg/template/qualttp3.C new file mode 100644 index 000000000..4b9ffe34e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp3.C @@ -0,0 +1,23 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +struct A +{ + template <class T, class U> class B {}; +}; + +template <template <class> class TT> struct X +{ + TT<int> y; +}; + +template <class T> struct C +{ + X<T::template B> x; // { dg-error "type" } +}; + +int main() +{ + C<A> c; // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/qualttp4.C b/gcc/testsuite/g++.dg/template/qualttp4.C new file mode 100644 index 000000000..c55ce2d37 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp4.C @@ -0,0 +1,24 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +struct A +{ + template <class T> struct B {}; +}; + +template <template <class, class> class TT> // { dg-error "provided" } +struct X +{ + TT<int> y; // { dg-error "number" } +}; + +template <class T> struct C +{ + X<T::template B> x; // { dg-error "type" } +}; + +int main() +{ + C<A> c; // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/qualttp5.C b/gcc/testsuite/g++.dg/template/qualttp5.C new file mode 100644 index 000000000..8bca7f696 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp5.C @@ -0,0 +1,26 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <class U> struct A +{ + template <class T> class B {}; // { dg-message "operator=|no known conversion" } +}; + +template <template <class> class TT> void f() +{ + TT<int> y; + y = 0; // { dg-error "no match" } + // { dg-message "candidate" "candidate note" { target *-*-* } 13 } +} + +template <class T> struct C +{ + void g() { f<A<T>::template B>(); } // { dg-message "instantiated" } +}; + +int main() +{ + C<int> c; + c.g(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/qualttp6.C b/gcc/testsuite/g++.dg/template/qualttp6.C new file mode 100644 index 000000000..aa1a46700 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp6.C @@ -0,0 +1,15 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <template <class> class TT> class C { +}; + +template <class T> struct D { + C<T::template B> c; // { dg-error "no class template" } +}; + +struct E { +}; + +D<E> d; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/qualttp7.C b/gcc/testsuite/g++.dg/template/qualttp7.C new file mode 100644 index 000000000..f37123e77 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp7.C @@ -0,0 +1,12 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <template <class> class TT> class C { +}; + +template <class T> struct D { + C<T::template B> c; // { dg-error "no class template" } +}; + +D<int> d; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/qualttp8.C b/gcc/testsuite/g++.dg/template/qualttp8.C new file mode 100644 index 000000000..5f55e60b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp8.C @@ -0,0 +1,17 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <template <class> class TT> class C { +}; + +template <class T> struct D { + C<T::template B> c; // { dg-error "context" } +}; + +struct E { + private: + template <class T> class B {}; // { dg-error "private" } +}; + +D<E> d; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/qualttp9.C b/gcc/testsuite/g++.dg/template/qualttp9.C new file mode 100644 index 000000000..8d90dabde --- /dev/null +++ b/gcc/testsuite/g++.dg/template/qualttp9.C @@ -0,0 +1,17 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <template <class> class TT> class C { +}; + +template <class T> struct D : T { + C<T::template B> c; +}; + +struct E { + protected: + template <class T> class B {}; +}; + +D<E> d; diff --git a/gcc/testsuite/g++.dg/template/recurse.C b/gcc/testsuite/g++.dg/template/recurse.C new file mode 100644 index 000000000..448c34721 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse.C @@ -0,0 +1,27 @@ +// Test for handling of excessive template recursion. +// { dg-options "-ftemplate-depth-50 -O" } + +template <int I> struct F +{ + int operator()() + { + F<I+1> f; // { dg-error "incomplete type" "incomplete" } + // { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 } + // { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 } + return f()*I; // { dg-message "recursively instantiated" "recurse" } + } +}; + +template <> struct F<52> +{ + int operator()() { return 0; } +}; + +int main () +{ + F<1> f; + return f(); // { dg-message "instantiated from here" "excessive recursion" } +} + +// Ignore excess messages from recursion. +// { dg-prune-output "instantiated from 'int" } diff --git a/gcc/testsuite/g++.dg/template/recurse1.C b/gcc/testsuite/g++.dg/template/recurse1.C new file mode 100644 index 000000000..4789983af --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse1.C @@ -0,0 +1,16 @@ +// PR c++/5050 +// Origin: georg.wild@gmx.de +// Reduced by: tbagot@bluearc.com and Nathanael C. Nerode <neroden@twcny.rr.com> +// Test for that excessive template recursion does not occur +// because of optimization. +// { dg-options "-ftemplate-depth-1 -O" } + + struct ostream { + template<class T> ostream& foo( const T & ) + { return *this; } + }; + + void foo() { + ostream os; + (os.foo(1)).foo(2); + } diff --git a/gcc/testsuite/g++.dg/template/recurse2.C b/gcc/testsuite/g++.dg/template/recurse2.C new file mode 100644 index 000000000..b9767dfb6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse2.C @@ -0,0 +1,8 @@ +// PR c++/9335 +// We should not see an error about non-constant initialization. + +template <int N> struct X { + static const int value = X<N-1>::value; // { dg-error "instantiation|incomplete" } + // { dg-message "recursively instantiated" "" { target *-*-* } 5 } +}; +template struct X<1000>; diff --git a/gcc/testsuite/g++.dg/template/redecl1.C b/gcc/testsuite/g++.dg/template/redecl1.C new file mode 100644 index 000000000..1bbf20ec7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/redecl1.C @@ -0,0 +1,4 @@ +// PR c++/15025 + +template <int> struct X; +struct X {}; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/redecl2.C b/gcc/testsuite/g++.dg/template/redecl2.C new file mode 100644 index 000000000..4dd432e6f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/redecl2.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +// Origin: heinlein@informatik.uni-ulm.de + +// PR c++/14428: Redeclaration of class template with wrong +// non-type template parameter. + +template <int i> struct X; // { dg-error "template parameter" } +template <int* p> struct X; // { dg-error "redeclared here" } diff --git a/gcc/testsuite/g++.dg/template/redecl3.C b/gcc/testsuite/g++.dg/template/redecl3.C new file mode 100644 index 000000000..029f9e69a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/redecl3.C @@ -0,0 +1,7 @@ +// PR c++/19980 +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> + +// { dg-do compile } + +int foo; // { dg-error "previous declaration" } +template<int> void foo() {} // { dg-error "redeclared" } diff --git a/gcc/testsuite/g++.dg/template/redecl4.C b/gcc/testsuite/g++.dg/template/redecl4.C new file mode 100644 index 000000000..9a4a9f366 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/redecl4.C @@ -0,0 +1,5 @@ +// PR c++/28710 +// { dg-do compile } + +template<int> union A; // { dg-error "previous" } +struct A; // { dg-error "non-template" } diff --git a/gcc/testsuite/g++.dg/template/ref1.C b/gcc/testsuite/g++.dg/template/ref1.C new file mode 100644 index 000000000..5ac4329d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref1.C @@ -0,0 +1,4 @@ +// { dg-prune-output "mangled name" } +class a {} a1; +template <a & p> class b { public: b() { static_cast <a &> (p); } }; +int main() { b <a1> b1; } diff --git a/gcc/testsuite/g++.dg/template/ref2.C b/gcc/testsuite/g++.dg/template/ref2.C new file mode 100644 index 000000000..9feb19d2f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref2.C @@ -0,0 +1,27 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Jan 2005 <nathan@codesourcery.com> + +// PR 19298: Rejects legal +// Origin: Andrew Pinski <pinskia@gcc.gnu.org> + +struct t +{ + void f() const; +}; + +template <typename _Tp> +struct A +{ + static t const& c; +}; + +template <typename _Tp> +void g(void) +{ + A<_Tp>::c.f(); +} + +void h(void) +{ + g<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/ref3.C b/gcc/testsuite/g++.dg/template/ref3.C new file mode 100644 index 000000000..976c093a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref3.C @@ -0,0 +1,11 @@ +// PR c++/28341 + +template<const int&> struct A {}; + +template<typename T> struct B +{ + A<(T)0> b; // { dg-error "constant|not a valid" } + A<T(0)> a; // { dg-error "constant|not a valid" } +}; + +B<const int&> b; diff --git a/gcc/testsuite/g++.dg/template/ref4.C b/gcc/testsuite/g++.dg/template/ref4.C new file mode 100644 index 000000000..6d89fa80a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref4.C @@ -0,0 +1,12 @@ +// PR c++/41972 + +struct X { + static const double x; +}; +template <const double& _test_> + class Foo { }; +template <typename _ignore_> +struct Y { + typedef Foo<X::x> type; +}; + diff --git a/gcc/testsuite/g++.dg/template/ref5.C b/gcc/testsuite/g++.dg/template/ref5.C new file mode 100644 index 000000000..efefbef9c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref5.C @@ -0,0 +1,11 @@ +// PR c++/35075 + +template<int&> struct A {}; + +template<typename T> struct B +{ + static const T t; + A<t> a; // { dg-error "reference variable" } +}; + +B<int&> b; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/repo1.C b/gcc/testsuite/g++.dg/template/repo1.C new file mode 100644 index 000000000..342993eca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo1.C @@ -0,0 +1,20 @@ +// { dg-options "-frepo" } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +struct A { + A(); +}; + +A::A() {} + +template <typename T> +struct B : public A { + B() {} // { dg-bogus "" } +}; + +B<int> b; + +int main () {} + +// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo2.C b/gcc/testsuite/g++.dg/template/repo2.C new file mode 100644 index 000000000..e3224155e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo2.C @@ -0,0 +1,18 @@ +// PR c++/17163 +// { dg-options "-frepo" } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +template <int __inst> +struct __Atomicity_lock +{ + static unsigned char _S_atomicity_lock; +}; +template <int __inst> +unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0; +template unsigned char __Atomicity_lock<0>::_S_atomicity_lock; + +int main () { +} + +// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo3.C b/gcc/testsuite/g++.dg/template/repo3.C new file mode 100644 index 000000000..cfa38a9e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo3.C @@ -0,0 +1,11 @@ +// { dg-options "-frepo -DF='a'" } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +template <typename A, typename B> void f () {} +template <typename A, typename B> void g () { f<int,int>(); } +int main () { g<int,int>(); } + +char c = F; + +// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo4.C b/gcc/testsuite/g++.dg/template/repo4.C new file mode 100644 index 000000000..64882a8c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo4.C @@ -0,0 +1,18 @@ +// PR c++/17775 +// { dg-options "-frepo" } +// { dg-final { cleanup-repo-files } } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +namespace { + struct Foo {}; +} + +template <typename Tp> +void foo(Tp) {} + +int +main() +{ + foo(Foo()); +} diff --git a/gcc/testsuite/g++.dg/template/repo5.C b/gcc/testsuite/g++.dg/template/repo5.C new file mode 100644 index 000000000..e45ade7df --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo5.C @@ -0,0 +1,14 @@ +// PR c++/25625 +// { dg-options "-frepo" } +// { dg-final { cleanup-repo-files } } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +template< typename T, T N > struct integral_c { + static const T value = N; + typedef integral_c< T, value + 1 > next; +}; +template< typename T, T N > T const integral_c< T, N >::value; +integral_c<int,0> a; + +int main () {} diff --git a/gcc/testsuite/g++.dg/template/repo6.C b/gcc/testsuite/g++.dg/template/repo6.C new file mode 100644 index 000000000..4b7178e2a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo6.C @@ -0,0 +1,26 @@ +// PR c++/34178 +// { dg-options "-frepo" } +// { dg-final { cleanup-repo-files } } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +template<typename T> +class A +{ +private: + static const int x; + static int y; + +public: + int getX () { return x + y; } +}; + +template<typename T> const int A<T>::x = 0; +template<typename T> int A<T>::y = 0; + +int +main () +{ + A<int> a; + return a.getX(); +} diff --git a/gcc/testsuite/g++.dg/template/repo7.C b/gcc/testsuite/g++.dg/template/repo7.C new file mode 100644 index 000000000..dafb3f559 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo7.C @@ -0,0 +1,25 @@ +// PR c++/34340 +// { dg-options "-frepo" } +// { dg-final { cleanup-repo-files } } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +struct A +{ + int a; +}; + +template <typename T> struct D +{ + static const A b; +}; + +template<typename T> const A D<T>::b = { 2 }; +template class D<A>; + +const A *x = &D<A>::b; + +int +main () +{ +} diff --git a/gcc/testsuite/g++.dg/template/repo8.C b/gcc/testsuite/g++.dg/template/repo8.C new file mode 100644 index 000000000..c51592c93 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo8.C @@ -0,0 +1,24 @@ +// PR c++/34340 +// { dg-options "-frepo" } +// { dg-final { cleanup-repo-files } } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +struct A +{ + int a; +}; + +template <typename T> struct D +{ + static const A b; +}; + +template<typename T> const A D<T>::b = { 2 }; + +const A *x = &D<A>::b; + +int +main () +{ +} diff --git a/gcc/testsuite/g++.dg/template/repo9.C b/gcc/testsuite/g++.dg/template/repo9.C new file mode 100644 index 000000000..7ddc6bf56 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/repo9.C @@ -0,0 +1,49 @@ +// PR c++/36364 +// { dg-options "-frepo" } +// { dg-final { cleanup-repo-files } } +// { dg-require-host-local "" } +// { dg-skip-if "dkms are not final links" { vxworks_kernel } } + +template <typename C> struct A +{ + static void assign (C &c1, const C &c2) { c1 = c2; } +}; + +template <typename C, typename T> struct B +{ + struct D + { + static const C terminal; + static unsigned long stor[]; + static D &empty_rep () + { + void *p = reinterpret_cast <void *>(&stor); + return *reinterpret_cast <D *>(p); + } + void test (unsigned long n) + { + T::assign (this->refdata ()[n], terminal); + } + C *refdata () throw () + { + return reinterpret_cast <C *>(this + 1); + } + }; + C *dataplus; + C *data () const { return dataplus; } + D *rep () const { return &((reinterpret_cast < D * >(data ()))[-1]); } + static D & empty_rep () { return D::empty_rep (); } + B () : dataplus (empty_rep ().refdata ()) { } + ~B () { } + void push_back (C c) { rep ()->test (10); } +}; + +template <typename C, typename T> const C B <C, T>::D::terminal = C (); +template <typename C, typename T> unsigned long B <C, T>::D::stor[64]; + +int +main () +{ + B <char, A <char> > s; + s.push_back ('a'); +} diff --git a/gcc/testsuite/g++.dg/template/restrict1.C b/gcc/testsuite/g++.dg/template/restrict1.C new file mode 100644 index 000000000..4452298eb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/restrict1.C @@ -0,0 +1,8 @@ +// PR c++/6392 +// Bug: We tried to make the array restricted, which doesn't make sense. + +template <class T> +class bob +{ + T * __restrict a[50]; +}; diff --git a/gcc/testsuite/g++.dg/template/scope1.C b/gcc/testsuite/g++.dg/template/scope1.C new file mode 100644 index 000000000..b017b0bdb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/scope1.C @@ -0,0 +1,12 @@ +// PR 8327 + +template <class T> +class X +{ + static const int a = 5; + + static T b[a]; +}; + +template <class T> T X<T>::b[X::a]; + diff --git a/gcc/testsuite/g++.dg/template/scope2.C b/gcc/testsuite/g++.dg/template/scope2.C new file mode 100644 index 000000000..79b520cbe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/scope2.C @@ -0,0 +1,34 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Aug 2003 <nathan@codesourcery.com> + +// checked instantiated bases in wrong scope. + +class Helper {}; + +template<class T> struct X { }; + +template<class T> class Base +{ + protected: + typedef Helper H; +}; + +template<class T > +struct Derived : Base<T> +{ + typedef Base<T> Parent; + typedef typename Parent::H H; + + class Nested : public X<H> {}; + + Nested m; + + void Foo (); +}; + +void Foo (Derived<char> &x) +{ + x.Foo (); +} diff --git a/gcc/testsuite/g++.dg/template/scope3.C b/gcc/testsuite/g++.dg/template/scope3.C new file mode 100644 index 000000000..c191c79c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/scope3.C @@ -0,0 +1,15 @@ +// PR c++/41038 + +struct S +{ + int size() const; +}; + +template<typename T> +struct Packer +{ + int foo() { + return Packer::var.size(); + } + const S& var; +}; diff --git a/gcc/testsuite/g++.dg/template/scope4.C b/gcc/testsuite/g++.dg/template/scope4.C new file mode 100644 index 000000000..a4ae074c0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/scope4.C @@ -0,0 +1,15 @@ +// PR c++/46058 + +class StringLiterals { +public: + static const char dec[]; +}; + +template<class St, class Base, const char* name> +class NoValueCommand : public Base { +public: +}; + +template<class St, class Base> +class DecBasic : public NoValueCommand<St,Base,StringLiterals::dec> { +}; diff --git a/gcc/testsuite/g++.dg/template/sfinae1.C b/gcc/testsuite/g++.dg/template/sfinae1.C new file mode 100644 index 000000000..47db41154 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae1.C @@ -0,0 +1,21 @@ +// PR c++/14337 + +template <bool> struct Constraint; +template <> struct Constraint<true> { typedef int Result; }; + +template <typename T> +struct IsInt { static const bool value = false; }; + +template <> +struct IsInt<int> { static const bool value = true; }; + +template <typename T> +typename Constraint<IsInt<T>::value>::Result foo(T); + +template <typename T> +typename Constraint<!IsInt<T>::value>::Result foo(T); + +template <typename> +void bar() { + foo(1); +} diff --git a/gcc/testsuite/g++.dg/template/sfinae10.C b/gcc/testsuite/g++.dg/template/sfinae10.C new file mode 100644 index 000000000..f44c4458f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae10.C @@ -0,0 +1,181 @@ +// DR 339 +// +// Test of the use of various unary operators with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#define DEFINE_PREFIX_UNARY_TRAIT(Name,Op) \ +template<typename T> \ + typename enable_if<(sizeof(Op create_a<T>(), 1) > 0), \ + yes_type>::type \ + JOIN(check_,Name)(int); \ + \ +template<typename T> \ + no_type JOIN(check_,Name)(...); \ + \ +template<typename T> \ +struct Name \ +{ \ + static const bool value = \ + (sizeof(JOIN(check_,Name)<T&>(0)) == sizeof(yes_type)); \ +} + +#define DEFINE_POSTFIX_UNARY_TRAIT(Name,Op) \ +template<typename T> \ + typename enable_if<(sizeof(create_a<T>() Op, 1) > 0), \ + yes_type>::type \ + JOIN(check_,Name)(int); \ + \ +template<typename T> \ + no_type JOIN(check_,Name)(...); \ + \ +template<typename T> \ +struct Name \ +{ \ + static const bool value = \ + (sizeof(JOIN(check_,Name)<T&>(0)) == sizeof(yes_type)); \ +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct W { + W operator+(); + W operator-(); + int operator*(); + W operator~(); + bool operator!(); + W& operator++(); + W& operator--(); + W& operator++(int); + W& operator--(int); +}; + +struct X { }; +X operator+(X); +X operator-(X); +int operator*(X); +X operator~(X); +bool operator!(X); +X& operator++(X&); +X& operator--(X&); +X& operator++(X&, int); +X& operator--(X&, int); + +struct Y { }; + +struct Z { +private: + Z operator+(); // { dg-error "is private" } + Z operator-(); // { dg-error "is private" } + int operator*(); // { dg-error "is private" } + Z operator~(); // { dg-error "is private" } + bool operator!(); // { dg-error "is private" } + Z& operator++(); // { dg-error "is private" } + Z& operator--(); // { dg-error "is private" } + Z& operator++(int); // { dg-error "is private" } + Z& operator--(int); // { dg-error "is private" } +}; + +// has_unary_plus +DEFINE_PREFIX_UNARY_TRAIT(has_unary_plus, +); // { dg-error "within this context" } +STATIC_ASSERT((has_unary_plus<int>::value)); +STATIC_ASSERT((!has_unary_plus<int X::*>::value)); +STATIC_ASSERT((has_unary_plus<W>::value)); +STATIC_ASSERT((has_unary_plus<X>::value)); +STATIC_ASSERT((!has_unary_plus<Y>::value)); + +// is_negatable +DEFINE_PREFIX_UNARY_TRAIT(is_negatable, -); // { dg-error "within this context" } +STATIC_ASSERT((is_negatable<int>::value)); +STATIC_ASSERT((!is_negatable<int X::*>::value)); +STATIC_ASSERT((is_negatable<W>::value)); +STATIC_ASSERT((is_negatable<X>::value)); +STATIC_ASSERT((!is_negatable<Y>::value)); + +// is_dereferenceable +DEFINE_PREFIX_UNARY_TRAIT(is_dereferenceable, *); // { dg-error "within this context" } +STATIC_ASSERT((!is_dereferenceable<int>::value)); +STATIC_ASSERT((is_dereferenceable<int*>::value)); +STATIC_ASSERT((is_dereferenceable<W>::value)); +STATIC_ASSERT((is_dereferenceable<X>::value)); +STATIC_ASSERT((!is_dereferenceable<Y>::value)); + +// has_bitwise_not +DEFINE_PREFIX_UNARY_TRAIT(has_bitwise_not, ~); // { dg-error "within this context" } +STATIC_ASSERT((has_bitwise_not<int>::value)); +STATIC_ASSERT((!has_bitwise_not<int*>::value)); +STATIC_ASSERT((has_bitwise_not<W>::value)); +STATIC_ASSERT((has_bitwise_not<X>::value)); +STATIC_ASSERT((!has_bitwise_not<Y>::value)); + +// has_truth_not +DEFINE_PREFIX_UNARY_TRAIT(has_truth_not, !); // { dg-error "within this context" } +STATIC_ASSERT((has_truth_not<int>::value)); +STATIC_ASSERT((has_truth_not<int*>::value)); +STATIC_ASSERT((has_truth_not<W>::value)); +STATIC_ASSERT((has_truth_not<X>::value)); +STATIC_ASSERT((!has_truth_not<Y>::value)); + +// has_preincrement +DEFINE_PREFIX_UNARY_TRAIT(has_preincrement, ++); // { dg-error "within this context" } +STATIC_ASSERT((has_preincrement<int>::value)); +STATIC_ASSERT((has_preincrement<int*>::value)); +STATIC_ASSERT((!has_preincrement<int X::*>::value)); +STATIC_ASSERT((has_preincrement<W>::value)); +STATIC_ASSERT((has_preincrement<X>::value)); +STATIC_ASSERT((!has_preincrement<Y>::value)); + +// has_predecrement +DEFINE_PREFIX_UNARY_TRAIT(has_predecrement, --); // { dg-error "within this context" } +STATIC_ASSERT((has_predecrement<int>::value)); +STATIC_ASSERT((has_predecrement<int*>::value)); +STATIC_ASSERT((!has_predecrement<int X::*>::value)); +STATIC_ASSERT((has_predecrement<W>::value)); +STATIC_ASSERT((has_predecrement<X>::value)); +STATIC_ASSERT((!has_predecrement<Y>::value)); + +// has_postincrement +DEFINE_POSTFIX_UNARY_TRAIT(has_postincrement, ++); // { dg-error "within this context" } +STATIC_ASSERT((has_postincrement<int>::value)); +STATIC_ASSERT((has_postincrement<int*>::value)); +STATIC_ASSERT((!has_postincrement<int X::*>::value)); +STATIC_ASSERT((has_postincrement<W>::value)); +STATIC_ASSERT((has_postincrement<X>::value)); +STATIC_ASSERT((!has_postincrement<Y>::value)); + +// has_postdecrement +DEFINE_POSTFIX_UNARY_TRAIT(has_postdecrement, --); // { dg-error "within this context" } +STATIC_ASSERT((has_postdecrement<int>::value)); +STATIC_ASSERT((has_postdecrement<int*>::value)); +STATIC_ASSERT((!has_postdecrement<int X::*>::value)); +STATIC_ASSERT((has_postdecrement<W>::value)); +STATIC_ASSERT((has_postdecrement<X>::value)); +STATIC_ASSERT((!has_postdecrement<Y>::value)); + +// Check for private members +STATIC_ASSERT((has_unary_plus<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((is_negatable<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((is_dereferenceable<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((has_bitwise_not<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((has_truth_not<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((has_preincrement<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((has_predecrement<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((has_postincrement<Z>::value)); // { dg-message "instantiated from here" } +STATIC_ASSERT((has_postdecrement<Z>::value)); // { dg-message "instantiated from here" } + diff --git a/gcc/testsuite/g++.dg/template/sfinae11.C b/gcc/testsuite/g++.dg/template/sfinae11.C new file mode 100644 index 000000000..a813055ea --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae11.C @@ -0,0 +1,53 @@ +// DR 339 +// +// Test of the use of the comma operator with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +template<typename T, typename U> + typename enable_if<(sizeof(create_a<T>(), create_a<U>()) > 0), + yes_type>::type + check_comma(int); + +template<typename T, typename U> no_type check_comma(...); + +template<typename T, typename U> +struct has_comma +{ + static const bool value = + (sizeof(check_comma<T, U>(0)) == sizeof(yes_type)); +}; + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct X { }; +struct Y { }; +struct Z { }; + +bool operator,(X&, Y); +bool operator,(X, Z); +void operator,(const Y&, const Z&); + +STATIC_ASSERT((has_comma<int, float>::value)); +STATIC_ASSERT((has_comma<int, X>::value)); +STATIC_ASSERT((has_comma<X, X>::value)); +STATIC_ASSERT((has_comma<X, Y>::value)); +STATIC_ASSERT((has_comma<X&, Y>::value)); +STATIC_ASSERT((has_comma<X, Z>::value)); +STATIC_ASSERT((!has_comma<Y, Z>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae12.C b/gcc/testsuite/g++.dg/template/sfinae12.C new file mode 100644 index 000000000..c51211be2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae12.C @@ -0,0 +1,47 @@ +// DR 339 +// +// Test of the use of the ternary operator with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +template<typename T, typename U, typename V> +typename enable_if< + (sizeof((create_a<T>()? create_a<U>() : create_a<V>()), 0) > 0), + yes_type>::type + check_ternary(int); + +template<typename T, typename U, typename V> no_type check_ternary(...); + +template<typename T, typename U, typename V> +struct has_ternary +{ + static const bool value = + (sizeof(check_ternary<T, U, V>(0)) == sizeof(yes_type)); +}; + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct X { }; +struct Y { operator bool(); }; + +STATIC_ASSERT((has_ternary<int, float, double>::value)); +STATIC_ASSERT((has_ternary<bool, double, double>::value)); +STATIC_ASSERT((!has_ternary<int, float*, double>::value)); +STATIC_ASSERT((!has_ternary<X, double, double>::value)); +STATIC_ASSERT((has_ternary<Y, double, double>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae13.C b/gcc/testsuite/g++.dg/template/sfinae13.C new file mode 100644 index 000000000..b659685d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae13.C @@ -0,0 +1,86 @@ +// DR 339 +// +// Test of the use of casts with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#define CHECK_CAST(CastKind) \ +template<typename T, typename U> \ + typename enable_if<(sizeof((JOIN(CastKind,_cast)<U>(create_a<T>())), 0) > 0), \ + yes_type>::type \ + JOIN(check_,JOIN(CastKind,_cast))(int); \ + \ +template<typename T, typename U> \ + no_type JOIN(check_,JOIN(CastKind,_cast))(...); \ + \ +template<typename T, typename U> \ +struct JOIN(has_,JOIN(CastKind,_cast)) \ +{ \ + static const bool value = \ + (sizeof(JOIN(check_,JOIN(CastKind,_cast))<T, U>(0)) == sizeof(yes_type)); \ +} + +template<typename T, typename U> +typename enable_if<(sizeof(((U)create_a<T>()), 0) > 0), yes_type>::type + check_c_cast(int); + +template<typename T, typename U> no_type check_c_cast(...); + +template<typename T, typename U> +struct has_c_cast +{ + static const bool value = + (sizeof(check_c_cast<T, U>(0)) == sizeof(yes_type)); +}; + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +CHECK_CAST(static); +CHECK_CAST(dynamic); +CHECK_CAST(const); +CHECK_CAST(reinterpret); + +struct X { virtual void f(); }; +struct Y { operator bool(); }; +struct Z : public X { }; + +STATIC_ASSERT((has_static_cast<int, float>::value)); +STATIC_ASSERT((!has_static_cast<X, Y>::value)); +STATIC_ASSERT((has_static_cast<Z, X>::value)); + +STATIC_ASSERT(!(has_dynamic_cast<int, float>::value)); +STATIC_ASSERT(!(has_dynamic_cast<X, Y>::value)); +STATIC_ASSERT(!(has_dynamic_cast<X, Z>::value)); +STATIC_ASSERT(!(has_dynamic_cast<Y, Z>::value)); +STATIC_ASSERT((has_dynamic_cast<X*, Z*>::value)); +STATIC_ASSERT((has_dynamic_cast<X*, Y*>::value)); +STATIC_ASSERT(!(has_dynamic_cast<Y*, Z*>::value)); + +STATIC_ASSERT(!(has_const_cast<int, float>::value)); +STATIC_ASSERT((has_const_cast<const int*, int*>::value)); +STATIC_ASSERT((has_const_cast<int*, const int*>::value)); +STATIC_ASSERT(!(has_const_cast<const int*, float*>::value)); + +STATIC_ASSERT((has_reinterpret_cast<int*, float*>::value)); +STATIC_ASSERT(!(has_reinterpret_cast<void*, char>::value)); +STATIC_ASSERT(!(has_reinterpret_cast<const X, X>::value)); + +STATIC_ASSERT((has_c_cast<int, float>::value)); +STATIC_ASSERT(!(has_c_cast<X, Y>::value)); +STATIC_ASSERT(!(has_c_cast<void*, char>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae14.C b/gcc/testsuite/g++.dg/template/sfinae14.C new file mode 100644 index 000000000..93eba43a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae14.C @@ -0,0 +1,79 @@ +// DR 339 +// +// Test of the use of the new and new[] operators with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +template<typename T> +typename enable_if<(sizeof(new T, 0) > 0), yes_type>::type + check_new(int); + +template<typename T> no_type check_new(...); + +template<typename T> +struct has_new +{ + static const bool value = + (sizeof(check_new<T>(0)) == sizeof(yes_type)); +}; + +template<typename T, typename U> +typename enable_if<(sizeof((new T(create_a<U>())), 0) > 0), + yes_type>::type + check_new_one_arg(int); + +template<typename T, typename U> no_type check_new_one_arg(...); + +template<typename T, typename U> +struct has_new_one_arg +{ + static const bool value = + (sizeof(check_new_one_arg<T, U>(0)) == sizeof(yes_type)); +}; + +template<typename T, typename U, U N> +typename enable_if<(sizeof(new T[N], 0) > 0), yes_type>::type + check_array_new(int); + +template<typename T, typename U, U N> no_type check_array_new(...); + +template<typename T, typename U, U N> +struct has_array_new +{ + static const bool value = + (sizeof(check_array_new<T, U, N>(0)) == sizeof(yes_type)); +}; + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct X { + X(int); +}; + +struct Y { int foo; }; + +STATIC_ASSERT((has_new<Y>::value)); +STATIC_ASSERT(!(has_new<X>::value)); +STATIC_ASSERT((has_new_one_arg<Y, Y>::value)); +STATIC_ASSERT((has_new_one_arg<X, float>::value)); +STATIC_ASSERT(!(has_new_one_arg<X, int X::*>::value)); + +STATIC_ASSERT((has_array_new<Y, int, 5>::value)); +STATIC_ASSERT(!(has_array_new<X, int Y::*, &Y::foo>::value)); +STATIC_ASSERT((has_array_new<X, int, 5>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae15.C b/gcc/testsuite/g++.dg/template/sfinae15.C new file mode 100644 index 000000000..27bce255d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae15.C @@ -0,0 +1,23 @@ +// PR c++/40944 +// { dg-options -std=c++0x } +// { dg-do run } + +template<typename T> +struct make { static T&& it(); }; + +void (*pf)(int&) = 0; + +template< typename T > +int bar(T const& x, + decltype( pf(make<T const&>::it()) )* = 0 // SFINAE! + ) { + return 1; +} + +int bar(...) { + return 0; +} + +int main() { + return bar(42); +} diff --git a/gcc/testsuite/g++.dg/template/sfinae16.C b/gcc/testsuite/g++.dg/template/sfinae16.C new file mode 100644 index 000000000..28a06d280 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae16.C @@ -0,0 +1,34 @@ +// PR c++/41927 +// { dg-options "-std=c++0x -Wall" } + +// We were getting a spurious ||/&& warning about the enable_if with the +// source position of d1. + +template<typename Tp> + struct is_int + { static const bool value = true; }; + +template<bool, typename Tp = void> + struct enable_if + { }; + +template<typename Tp> + struct enable_if<true, Tp> + { typedef Tp type; }; + +template<typename Rep> + struct duration + { + duration() { } + + template<typename Rep2, typename = typename + enable_if<false || (true && is_int<Rep2>::value)>::type> + duration(const duration<Rep2>&) { } + }; + +int main() +{ + duration<int> d0; + duration<int> d1 = d0; // { dg-warning "set but not used" } +} + diff --git a/gcc/testsuite/g++.dg/template/sfinae17.C b/gcc/testsuite/g++.dg/template/sfinae17.C new file mode 100644 index 000000000..eb043cbdd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae17.C @@ -0,0 +1,28 @@ +// The conversion from D* to B* is ambiguous, but that should not produce +// an error, it should remove the first f overload by SFINAE. + +#define static_assert(TEST,STR) \ + do { int ar[(TEST)?1:-1]; } while (0); + +struct B {}; + +struct B1 : B {}; +struct B2 : B {}; + +struct D : B1, B2 {}; + +template <class T> T create(); + +typedef char one[1]; +typedef char two[2]; + +template <class T> + one &f(char (*)[sizeof static_cast<T>(create<D *>())]); +template <class T> + two &f(...); + +int main() +{ + static_assert(sizeof f<int>(0) == sizeof(two), ""); + static_assert(sizeof f<B *>(0) == sizeof(two), ""); +} diff --git a/gcc/testsuite/g++.dg/template/sfinae18.C b/gcc/testsuite/g++.dg/template/sfinae18.C new file mode 100644 index 000000000..bbc39cb3a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae18.C @@ -0,0 +1,10 @@ +// PR c++/41468 + +typedef int Ft(int); +struct A { operator Ft*(); }; +struct B { operator Ft*(); }; +struct C : A, B { }; + +template<typename C> void f(int (*a)[sizeof(C()(0))]); +template<typename C> void f(...); +int main() { f<C>(0); } diff --git a/gcc/testsuite/g++.dg/template/sfinae19.C b/gcc/testsuite/g++.dg/template/sfinae19.C new file mode 100644 index 000000000..59be183fe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae19.C @@ -0,0 +1,44 @@ +// PR c++/44907 + +struct A { }; + +struct B +: public A { }; + +struct C +: public A { }; + +struct D +: public B, public C { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename From, typename To> + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename To1> + static void test_aux(To1); + + template<typename To1, typename From1> + static typename + enable_if<(sizeof(test_aux<To1>(From1()), 1) > 0), one>::type + test(int); + + template<typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<To, From>(0)) == 1; + }; + +template<typename From, typename To> + const bool mini_is_convertible<From, To>::value; + +int Test1[mini_is_convertible<D*, A*>::value ? -1 : 1]; +int Test2[mini_is_convertible<A*, D*>::value ? -1 : 1]; +int Test3[mini_is_convertible<D, A>::value ? -1 : 1]; +int Test4[mini_is_convertible<A, D>::value ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae2.C b/gcc/testsuite/g++.dg/template/sfinae2.C new file mode 100644 index 000000000..e39ca6b76 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae2.C @@ -0,0 +1,18 @@ +// PR c++/19989 +// Don't instantiate a function template if it would generate an +// array of size zero. + +// { dg-do compile } + +template<int T> struct cl { + const static int value = T; +}; + +template<int I> void fn (char (*) [cl<I>::value] = 0 ); // { dg-message "note" } + +void foo (void) +{ + fn<0> (); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 15 } +} + diff --git a/gcc/testsuite/g++.dg/template/sfinae20.C b/gcc/testsuite/g++.dg/template/sfinae20.C new file mode 100644 index 000000000..9767bc029 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae20.C @@ -0,0 +1,45 @@ +// PR c++/44907 +// { dg-options "-std=c++0x" } + +#include <utility> + +struct A { }; + +struct B +: public A { }; + +struct C +: public A { }; + +struct D +: public B, public C { }; + +template<typename From, typename To> + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename To1> + static void test_aux(To1); + + template<typename To1, typename From1> + static decltype(test_aux<To1>(std::declval<From1>()), one()) + test(int); + + template<typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<To, From>(0)) == 1; + }; + +template<typename From, typename To> + const bool mini_is_convertible<From, To>::value; + +static_assert (!mini_is_convertible<D*, A*>::value, ""); +static_assert (!mini_is_convertible<A*, D*>::value, ""); +static_assert (!mini_is_convertible<D&, A&>::value, ""); +static_assert (!mini_is_convertible<A&, D&>::value, ""); +static_assert (!mini_is_convertible<D, A>::value, ""); +static_assert (!mini_is_convertible<A, D>::value, ""); diff --git a/gcc/testsuite/g++.dg/template/sfinae21.C b/gcc/testsuite/g++.dg/template/sfinae21.C new file mode 100644 index 000000000..6086f2f9e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae21.C @@ -0,0 +1,40 @@ +// PR c++/44908 + +struct A { }; + +struct B +: public virtual A { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename From, typename To> + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename To1> + static void test_aux(To1); + + template<typename To1, typename From1> + static typename + enable_if<(sizeof(test_aux<To1>(From1()), 1) > 0), one>::type + test(int); + + template<typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<To, From>(0)) == 1; + }; + +template<typename From, typename To> + const bool mini_is_convertible<From, To>::value; + +int Test1[mini_is_convertible<int (B::*) (int), + int (A::*) (int)>::value ? -1 : 1]; +int Test2[mini_is_convertible<int (B::*), int (A::*)>::value ? -1 : 1]; +int Test3[mini_is_convertible<int (A::*) (int), + int (B::*) (int)>::value ? -1 : 1]; +int Test4[mini_is_convertible<int (A::*), int (B::*)>::value ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae22.C b/gcc/testsuite/g++.dg/template/sfinae22.C new file mode 100644 index 000000000..cdac99d91 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae22.C @@ -0,0 +1,39 @@ +// PR c++/44908 +// { dg-options "-std=c++0x" } + +#include <utility> + +struct A { }; + +struct B +: public virtual A { }; + +template<typename From, typename To> + class mini_is_convertible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename To1> + static void test_aux(To1); + + template<typename To1, typename From1> + static decltype(test_aux<To1>(std::declval<From1>()), one()) + test(int); + + template<typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<To, From>(0)) == 1; + }; + +template<typename From, typename To> + const bool mini_is_convertible<From, To>::value; + +static_assert (!mini_is_convertible<int (B::*) (int), + int (A::*) (int)>::value, ""); +static_assert (!mini_is_convertible<int (B::*), int (A::*)>::value, ""); +static_assert (!mini_is_convertible<int (A::*) (int), + int (B::*) (int)>::value, ""); +static_assert (!mini_is_convertible<int (A::*), int (B::*)>::value, ""); diff --git a/gcc/testsuite/g++.dg/template/sfinae23.C b/gcc/testsuite/g++.dg/template/sfinae23.C new file mode 100644 index 000000000..9e0197a70 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae23.C @@ -0,0 +1,23 @@ +// PR c++/44969 +// { dg-options "-std=c++0x" } + +template<typename Tp, typename... Args> + class mini_is_constructible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename Tp1, typename... Args1> + static decltype(Tp1(Args1()...), one()) + test(int); + + template<typename, typename...> + static two test(...); + + public: + static const bool value = sizeof(test<Tp, Args...>(0)) == 1; + }; + +class A { }; + +int Test[mini_is_constructible<int, A, A>::value ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae24.C b/gcc/testsuite/g++.dg/template/sfinae24.C new file mode 100644 index 000000000..7138c96e6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae24.C @@ -0,0 +1,26 @@ +// PR c++/44969 + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename Tp, typename Arg1, typename Arg2> + class mini_is_constructible + { + typedef char one; + typedef struct { char arr[2]; } two; + + template<typename Tp1, typename Arg1_, typename Arg2_> + static typename + enable_if<(sizeof(Tp1(Arg1_(), Arg2_()), 1) > 0), one>::type + test(int); + + template<typename, typename, typename> + static two test(...); + + public: + static const bool value = sizeof(test<Tp, Arg1, Arg2>(0)) == 1; + }; + +class A { }; + +int Test[mini_is_constructible<int, A, A>::value ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae25.C b/gcc/testsuite/g++.dg/template/sfinae25.C new file mode 100644 index 000000000..e9ee83e12 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae25.C @@ -0,0 +1,14 @@ +template <int I> +struct A { }; + +template <int J> +void f(A<1/J>); + +template <int J> +void f(...) { } + +int main() +{ + f<0>(); +} + diff --git a/gcc/testsuite/g++.dg/template/sfinae26.C b/gcc/testsuite/g++.dg/template/sfinae26.C new file mode 100644 index 000000000..dcb018f80 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae26.C @@ -0,0 +1,34 @@ +// Origin: PR c++/46170 +// { dg-do compile } + +namespace util { + struct option_value { + }; + template <class T> struct options_map_impl { + typedef T options_struct_type; + typedef bool (*opt_func)(const option_value&, options_struct_type&); + template <class V, V K> static bool set_member_constant(const option_value&, + options_struct_type&, V options_struct_type::*); + template <class V, V options_struct_type::*mem, V K> static bool + set_member_constant(const option_value& opt, options_struct_type& t) { + return set_member_constant<V,K>(opt, t, mem); + } + }; +} +struct cflat_options { + bool show_precharges; +}; +typedef util::options_map_impl<cflat_options> options_map_impl_type; +class register_options_modifier { + typedef options_map_impl_type::opt_func modifier_type; +public: register_options_modifier(); + register_options_modifier(const char* Mode, const modifier_type COM, + const char* h); +}; +static const register_options_modifier +cflat_opt_mod_show_precharges("precharges", + &options_map_impl_type::set_member_constant<bool, + &cflat_options::show_precharges, true>, "show precharge expressions"), + cflat_opt_mod_no_show_precharges("no-" "precharges", + &options_map_impl_type::set_member_constant<bool, + &cflat_options::show_precharges, false>, "hide precharge expressions"); diff --git a/gcc/testsuite/g++.dg/template/sfinae27.C b/gcc/testsuite/g++.dg/template/sfinae27.C new file mode 100644 index 000000000..0ecd1700d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae27.C @@ -0,0 +1,33 @@ +// Origin: PR c++/46162 + +struct small_type { char dummy; }; +struct large_type { char dummy[2]; }; + +template<class T> +struct has_foo_member_variable +{ + template<int T::*> struct tester; + template<class U> static small_type has_foo(tester<&U::foo> *); + template<class U> static large_type has_foo(...); + static const bool value = (sizeof(has_foo<T>(0)) == sizeof(small_type)); +}; + +struct A +{ + static int foo() + { + return 0; + } +}; + +struct B +{ + static int foo; +}; + +void +bar() +{ + bool b = has_foo_member_variable<A>::value; +} + diff --git a/gcc/testsuite/g++.dg/template/sfinae3.C b/gcc/testsuite/g++.dg/template/sfinae3.C new file mode 100644 index 000000000..349463d95 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae3.C @@ -0,0 +1,17 @@ +// PR c++/24671 +// { dg-do compile } + +template<typename> struct A +{ + typedef int X; + static const int i = 0; +}; + +template<typename> struct B +{ + B(const B&); + typedef typename A<char[A<B>::i]>::X Y; // { dg-error "forbids zero-size array" } + template<typename T> B(T, Y); +}; + +B<int> b(0,0); // { dg-message "instantiated from here" } diff --git a/gcc/testsuite/g++.dg/template/sfinae4.C b/gcc/testsuite/g++.dg/template/sfinae4.C new file mode 100644 index 000000000..a9650511e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae4.C @@ -0,0 +1,35 @@ +// DR 339 +// +// Test of the use of free functions with SFINAE +void foo(int) { } +template<typename T> void foo(T*) { } + +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename T> + typename enable_if<(sizeof(foo(create_a<T const&>()), 1) > 0), + yes_type>::type + check_has_foo(const volatile T&); + +no_type check_has_foo(...); + +template<typename T> +struct has_foo +{ + static const bool value = + (sizeof(check_has_foo(create_a<T const&>())) == sizeof(yes_type)); +}; + +struct X { }; + +int a1[has_foo<int>::value? 1 : -1]; +int a2[has_foo<long>::value? 1 : -1]; +int a3[has_foo<int*>::value? 1 : -1]; +int a4[has_foo<X>::value? -1 : 1]; +int a5[has_foo<int X::*>::value? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae5.C b/gcc/testsuite/g++.dg/template/sfinae5.C new file mode 100644 index 000000000..516e5cc85 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae5.C @@ -0,0 +1,47 @@ +// DR 339 +// +// Test of the use of member functions with SFINAE +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename T> + typename enable_if<(sizeof(create_a<T>().foo(), 1) > 0), + yes_type>::type + check_has_member_foo(const volatile T&); + +no_type check_has_member_foo(...); + +template<typename T> +struct has_foo +{ + static const bool value = + (sizeof(check_has_member_foo(create_a<T const&>())) == sizeof(yes_type)); +}; + +struct X { }; +struct Y { + void foo(); +}; +struct Z { + void foo(int); +}; + +struct A { + int foo; +}; + +struct B { + static int foo(); +}; + +int a1[has_foo<X>::value? -1 : 1]; +int a2[has_foo<Y>::value? 1 : -1]; +int a3[has_foo<Z>::value? -1 : 1]; +int a4[has_foo<int>::value? -1 : 1]; +int a5[has_foo<A>::value? -1 : 1]; +int a6[has_foo<B>::value? 1 : -1]; diff --git a/gcc/testsuite/g++.dg/template/sfinae6.C b/gcc/testsuite/g++.dg/template/sfinae6.C new file mode 100644 index 000000000..64567aae2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae6.C @@ -0,0 +1,83 @@ +// DR 339 +// +// Test of the use of the function call operator with SFINAE +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); + +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename F, typename T1, typename T2> + typename enable_if<sizeof(create_a<F>()(create_a<T1>(), create_a<T2>()), 1), + yes_type>::type + check_is_callable2(type<F>, type<T1>, type<T2>); + +no_type check_is_callable2(...); + +template<typename F, typename T1, typename T2 = T1> +struct is_callable2 +{ + static const bool value = + (sizeof(check_is_callable2(type<F>(), type<T1>(), type<T2>())) + == sizeof(yes_type)); +}; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + + +struct A; +struct B; + +struct A { + A(B); +}; + +struct B { + B(A); +}; + +struct F1 { }; + +struct F2 { + bool operator()(int, float); +}; + +struct F3 { + bool operator()(int); +}; + +struct F4 { + void operator()(A, A); + void operator()(B, B); +}; + +struct F5 { + void operator()(A, A); + +private: + void operator()(B, B); +}; + +STATIC_ASSERT((is_callable2<int(*)(int, int), long, int>::value)); +STATIC_ASSERT((!is_callable2<int(*)(int, int), int*, int>::value)); +STATIC_ASSERT((!is_callable2<F1, int, int>::value)); +STATIC_ASSERT((is_callable2<F2, int, int>::value)); +STATIC_ASSERT((!is_callable2<F2, int*, int>::value)); +STATIC_ASSERT((!is_callable2<F3, int, int>::value)); +STATIC_ASSERT((is_callable2<F4, A, A>::value)); +STATIC_ASSERT((is_callable2<F4, B, B>::value)); +STATIC_ASSERT((!is_callable2<F4, A, B>::value)); +STATIC_ASSERT((is_callable2<F5, A, A>::value)); +STATIC_ASSERT((!is_callable2<F5, A, B>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae6_neg.C b/gcc/testsuite/g++.dg/template/sfinae6_neg.C new file mode 100644 index 000000000..2df4ade47 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae6_neg.C @@ -0,0 +1,58 @@ +// DR 339 +// +// Test of the use of the function call operator with SFINAE +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); + +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +template<typename F, typename T1, typename T2> + typename enable_if<sizeof(create_a<F>()(create_a<T1>(), create_a<T2>()), 1), + yes_type>::type + check_is_callable2(type<F>, type<T1>, type<T2>); + +no_type check_is_callable2(...); + +template<typename F, typename T1, typename T2 = T1> +struct is_callable2 +{ + static const bool value = + (sizeof(check_is_callable2(type<F>(), type<T1>(), type<T2>())) + == sizeof(yes_type)); // { dg-error "within this context" } +}; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + + +struct A; +struct B; + +struct A { + A(B); +}; + +struct B { + B(A); +}; + +struct F { + void operator()(A, A); + +private: + void operator()(B, B); // { dg-error "is private" } +}; + +STATIC_ASSERT((is_callable2<F, B, B>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae7.C b/gcc/testsuite/g++.dg/template/sfinae7.C new file mode 100644 index 000000000..8551eb279 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae7.C @@ -0,0 +1,199 @@ +// DR 339 +// +// Test of the use of various binary operators with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#define DEFINE_INFIX_BINARY_TRAIT(Name,Op) \ +template<typename T, typename U> \ + typename enable_if<(sizeof(create_a<T>() Op create_a<U>(), 1) > 0), \ + yes_type>::type \ + JOIN(check_,Name)(type<T>, type<U>); \ + \ +no_type JOIN(check_,Name)(...); \ + \ +template<typename T, typename U = T> \ +struct Name \ +{ \ + static const bool value = \ + (sizeof(JOIN(check_,Name)(type<T>(), type<U>())) == sizeof(yes_type)); \ +} + +template<typename T, typename U> + typename enable_if<(sizeof(create_a<T>()[create_a<U>()], 1) > 0), + yes_type>::type + check_subscript(int); + +template<typename T, typename U> + no_type check_subscript(...); + +template<typename T, typename U> +struct can_subscript +{ + static const bool value = + (sizeof(check_subscript<T, U>(0)) == sizeof(yes_type)); +}; + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct X { }; +struct Y { int operator[](X); }; + +// is_addable +DEFINE_INFIX_BINARY_TRAIT(is_addable, +); +X operator+(X, X); +X operator+(X, Y); +STATIC_ASSERT((is_addable<int>::value)); +STATIC_ASSERT((is_addable<int, long>::value)); +STATIC_ASSERT((is_addable<X>::value)); +STATIC_ASSERT((is_addable<int*, int>::value)); +STATIC_ASSERT((!is_addable<int*>::value)); +STATIC_ASSERT((is_addable<X, Y>::value)); +STATIC_ASSERT((!is_addable<Y>::value)); + +// is_subtractable +DEFINE_INFIX_BINARY_TRAIT(is_subtractable, -); +X operator-(X, X); +X operator-(X, Y); +STATIC_ASSERT((is_subtractable<int>::value)); +STATIC_ASSERT((is_subtractable<int, long>::value)); +STATIC_ASSERT((is_subtractable<X>::value)); +STATIC_ASSERT((is_subtractable<int*, int>::value)); +STATIC_ASSERT((is_subtractable<int*>::value)); +STATIC_ASSERT((is_subtractable<X, Y>::value)); +STATIC_ASSERT((!is_subtractable<Y>::value)); +STATIC_ASSERT((!is_subtractable<int X::*>::value)); + +// is_multiplicable +DEFINE_INFIX_BINARY_TRAIT(is_multiplicable, *); +X operator*(X, X); +X operator*(X, Y); +STATIC_ASSERT((is_multiplicable<int>::value)); +STATIC_ASSERT((is_multiplicable<int, long>::value)); +STATIC_ASSERT((is_multiplicable<X>::value)); +STATIC_ASSERT((!is_multiplicable<int*, int>::value)); +STATIC_ASSERT((!is_multiplicable<int*>::value)); +STATIC_ASSERT((is_multiplicable<X, Y>::value)); +STATIC_ASSERT((!is_multiplicable<Y>::value)); +STATIC_ASSERT((!is_multiplicable<int X::*>::value)); + +// is_divisible +DEFINE_INFIX_BINARY_TRAIT(is_divisible, /); +X operator/(X, X); +X operator/(X, Y); +STATIC_ASSERT((is_divisible<int>::value)); +STATIC_ASSERT((is_divisible<int, long>::value)); +STATIC_ASSERT((is_divisible<X>::value)); +STATIC_ASSERT((!is_divisible<int*, int>::value)); +STATIC_ASSERT((!is_divisible<int*>::value)); +STATIC_ASSERT((is_divisible<X, Y>::value)); +STATIC_ASSERT((!is_divisible<Y>::value)); +STATIC_ASSERT((!is_divisible<int X::*>::value)); + +// has_remainder +DEFINE_INFIX_BINARY_TRAIT(has_remainder, %); +X operator%(X, X); +X operator%(X, Y); +STATIC_ASSERT((has_remainder<int>::value)); +STATIC_ASSERT((has_remainder<int, long>::value)); +STATIC_ASSERT((!has_remainder<float>::value)); +STATIC_ASSERT((has_remainder<X>::value)); +STATIC_ASSERT((!has_remainder<int*, int>::value)); +STATIC_ASSERT((!has_remainder<int*>::value)); +STATIC_ASSERT((has_remainder<X, Y>::value)); +STATIC_ASSERT((!has_remainder<Y>::value)); +STATIC_ASSERT((!has_remainder<int X::*>::value)); + +// has_xor +DEFINE_INFIX_BINARY_TRAIT(has_xor, ^); +X operator^(X, X); +X operator^(X, Y); +STATIC_ASSERT((has_xor<int>::value)); +STATIC_ASSERT((has_xor<int, long>::value)); +STATIC_ASSERT((!has_xor<float>::value)); +STATIC_ASSERT((has_xor<X>::value)); +STATIC_ASSERT((!has_xor<int*, int>::value)); +STATIC_ASSERT((!has_xor<int*>::value)); +STATIC_ASSERT((has_xor<X, Y>::value)); +STATIC_ASSERT((!has_xor<Y>::value)); +STATIC_ASSERT((!has_xor<int X::*>::value)); + +// has_bitand +DEFINE_INFIX_BINARY_TRAIT(has_bitand, &); +X operator&(X, X); +X operator&(X, Y); +STATIC_ASSERT((has_bitand<int>::value)); +STATIC_ASSERT((has_bitand<int, long>::value)); +STATIC_ASSERT((!has_bitand<float>::value)); +STATIC_ASSERT((has_bitand<X>::value)); +STATIC_ASSERT((!has_bitand<int*, int>::value)); +STATIC_ASSERT((!has_bitand<int*>::value)); +STATIC_ASSERT((has_bitand<X, Y>::value)); +STATIC_ASSERT((!has_bitand<Y>::value)); +STATIC_ASSERT((!has_bitand<int X::*>::value)); + +// has_bitor +DEFINE_INFIX_BINARY_TRAIT(has_bitor, |); +X operator|(X, X); +X operator|(X, Y); +STATIC_ASSERT((has_bitor<int>::value)); +STATIC_ASSERT((has_bitor<int, long>::value)); +STATIC_ASSERT((!has_bitor<float>::value)); +STATIC_ASSERT((has_bitor<X>::value)); +STATIC_ASSERT((!has_bitor<int*, int>::value)); +STATIC_ASSERT((!has_bitor<int*>::value)); +STATIC_ASSERT((has_bitor<X, Y>::value)); +STATIC_ASSERT((!has_bitor<Y>::value)); +STATIC_ASSERT((!has_bitor<int X::*>::value)); + +// has_left_shift +DEFINE_INFIX_BINARY_TRAIT(has_left_shift, <<); +X operator<<(X, X); +X operator<<(X, Y); +STATIC_ASSERT((has_left_shift<int>::value)); +STATIC_ASSERT((has_left_shift<int, long>::value)); +STATIC_ASSERT((!has_left_shift<float>::value)); +STATIC_ASSERT((has_left_shift<X>::value)); +STATIC_ASSERT((!has_left_shift<int*, int>::value)); +STATIC_ASSERT((!has_left_shift<int*>::value)); +STATIC_ASSERT((has_left_shift<X, Y>::value)); +STATIC_ASSERT((!has_left_shift<Y>::value)); +STATIC_ASSERT((!has_left_shift<int X::*>::value)); + +// has_right_shift +DEFINE_INFIX_BINARY_TRAIT(has_right_shift, >>); +X operator>>(X, X); +X operator>>(X, Y); +STATIC_ASSERT((has_right_shift<int>::value)); +STATIC_ASSERT((has_right_shift<int, long>::value)); +STATIC_ASSERT((!has_right_shift<float>::value)); +STATIC_ASSERT((has_right_shift<X>::value)); +STATIC_ASSERT((!has_right_shift<int*, int>::value)); +STATIC_ASSERT((!has_right_shift<int*>::value)); +STATIC_ASSERT((has_right_shift<X, Y>::value)); +STATIC_ASSERT((!has_right_shift<Y>::value)); +STATIC_ASSERT((!has_right_shift<int X::*>::value)); + +// can_subscript +STATIC_ASSERT((can_subscript<int*, int>::value)); +STATIC_ASSERT((can_subscript<int, int*>::value)); +STATIC_ASSERT((can_subscript<int(&)[7], int>::value)); +STATIC_ASSERT((can_subscript<int, int(&)[7]>::value)); +STATIC_ASSERT((!can_subscript<X, Y>::value)); +STATIC_ASSERT((can_subscript<Y, X>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae8.C b/gcc/testsuite/g++.dg/template/sfinae8.C new file mode 100644 index 000000000..5ac09c6b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae8.C @@ -0,0 +1,182 @@ +// DR 339 +// +// Test of the use of various boolean binary operators with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +bool accepts_bool(bool); + +#define DEFINE_BINARY_PREDICATE_TRAIT(Name,Op) \ +template<typename T, typename U> \ + typename enable_if<sizeof(accepts_bool(create_a<T>() Op create_a<U>())), \ + yes_type>::type \ + JOIN(check_,Name)(type<T>, type<U>); \ + \ +no_type JOIN(check_,Name)(...); \ + \ +template<typename T, typename U = T> \ +struct Name \ +{ \ + static const bool value = \ + (sizeof(JOIN(check_,Name)(type<T>(), type<U>())) == sizeof(yes_type)); \ +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct X { }; +struct Y { }; + +struct convertible_to_bool { + operator int convertible_to_bool::* (); +}; + +struct not_convertible_to_bool { }; + +// is_less_than_comparable +DEFINE_BINARY_PREDICATE_TRAIT(is_less_than_comparable,<); +bool operator<(X, X); +convertible_to_bool operator<(X, Y); +not_convertible_to_bool operator<(Y, X); + +STATIC_ASSERT((is_less_than_comparable<int>::value)); +STATIC_ASSERT((is_less_than_comparable<int, long>::value)); +STATIC_ASSERT((is_less_than_comparable<int*>::value)); +STATIC_ASSERT((is_less_than_comparable<X>::value)); +STATIC_ASSERT((is_less_than_comparable<X, Y>::value)); +STATIC_ASSERT((!is_less_than_comparable<Y, X>::value)); +STATIC_ASSERT((!is_less_than_comparable<Y>::value)); + +// is_less_equal_comparable +DEFINE_BINARY_PREDICATE_TRAIT(is_less_equal_comparable,<=); +bool operator<=(X, X); +convertible_to_bool operator<=(X, Y); +not_convertible_to_bool operator<=(Y, X); + +STATIC_ASSERT((is_less_equal_comparable<int>::value)); +STATIC_ASSERT((is_less_equal_comparable<int, long>::value)); +STATIC_ASSERT((is_less_equal_comparable<int*>::value)); +STATIC_ASSERT((is_less_equal_comparable<X>::value)); +STATIC_ASSERT((is_less_equal_comparable<X, Y>::value)); +STATIC_ASSERT((!is_less_equal_comparable<Y, X>::value)); +STATIC_ASSERT((!is_less_equal_comparable<Y>::value)); + +// is_greater_than_comparable +DEFINE_BINARY_PREDICATE_TRAIT(is_greater_than_comparable,>); +bool operator>(X, X); +convertible_to_bool operator>(X, Y); +not_convertible_to_bool operator>(Y, X); + +STATIC_ASSERT((is_greater_than_comparable<int>::value)); +STATIC_ASSERT((is_greater_than_comparable<int, long>::value)); +STATIC_ASSERT((is_greater_than_comparable<int*>::value)); +STATIC_ASSERT((is_greater_than_comparable<X>::value)); +STATIC_ASSERT((is_greater_than_comparable<X, Y>::value)); +STATIC_ASSERT((!is_greater_than_comparable<Y, X>::value)); +STATIC_ASSERT((!is_greater_than_comparable<Y>::value)); + +// is_greater_equal_comparable +DEFINE_BINARY_PREDICATE_TRAIT(is_greater_equal_comparable,>=); +bool operator>=(X, X); +convertible_to_bool operator>=(X, Y); +not_convertible_to_bool operator>=(Y, X); + +STATIC_ASSERT((is_greater_equal_comparable<int>::value)); +STATIC_ASSERT((is_greater_equal_comparable<int, long>::value)); +STATIC_ASSERT((is_greater_equal_comparable<int*>::value)); +STATIC_ASSERT((is_greater_equal_comparable<X>::value)); +STATIC_ASSERT((is_greater_equal_comparable<X, Y>::value)); +STATIC_ASSERT((!is_greater_equal_comparable<Y, X>::value)); +STATIC_ASSERT((!is_greater_equal_comparable<Y>::value)); + +// is_equality_comparable +struct Z : X { }; +DEFINE_BINARY_PREDICATE_TRAIT(is_equality_comparable,==); +bool operator==(X, X); +convertible_to_bool operator==(X, Y); +not_convertible_to_bool operator==(Y, X); + +STATIC_ASSERT((is_equality_comparable<int>::value)); +STATIC_ASSERT((is_equality_comparable<int, long>::value)); +STATIC_ASSERT((is_equality_comparable<int*>::value)); +STATIC_ASSERT((is_equality_comparable<X>::value)); +STATIC_ASSERT((is_equality_comparable<X, Y>::value)); +STATIC_ASSERT((!is_equality_comparable<Y, X>::value)); +STATIC_ASSERT((!is_equality_comparable<Y>::value)); +STATIC_ASSERT((is_equality_comparable<int X::*>::value)); +STATIC_ASSERT((!is_equality_comparable<int X::*, int Y::*>::value)); +STATIC_ASSERT((!is_equality_comparable<int*, float*>::value)); +STATIC_ASSERT((is_equality_comparable<X*, Z*>::value)); +STATIC_ASSERT((!is_equality_comparable<X*, Y*>::value)); + +// is_not_equal_comparable +DEFINE_BINARY_PREDICATE_TRAIT(is_not_equal_comparable,!=); +bool operator!=(X, X); +convertible_to_bool operator!=(X, Y); +not_convertible_to_bool operator!=(Y, X); + +STATIC_ASSERT((is_not_equal_comparable<int>::value)); +STATIC_ASSERT((is_not_equal_comparable<int, long>::value)); +STATIC_ASSERT((is_not_equal_comparable<int*>::value)); +STATIC_ASSERT((is_not_equal_comparable<X>::value)); +STATIC_ASSERT((is_not_equal_comparable<X, Y>::value)); +STATIC_ASSERT((!is_not_equal_comparable<Y, X>::value)); +STATIC_ASSERT((!is_not_equal_comparable<Y>::value)); +STATIC_ASSERT((is_not_equal_comparable<int X::*>::value)); +STATIC_ASSERT((!is_not_equal_comparable<int X::*, int Y::*>::value)); +STATIC_ASSERT((!is_not_equal_comparable<int*, float*>::value)); +STATIC_ASSERT((is_not_equal_comparable<X*, Z*>::value)); +STATIC_ASSERT((!is_not_equal_comparable<X*, Y*>::value)); + +// has_logical_and +DEFINE_BINARY_PREDICATE_TRAIT(has_logical_and,&&); +bool operator&&(X, X); +convertible_to_bool operator&&(X, Y); +not_convertible_to_bool operator&&(Y, X); + +STATIC_ASSERT((has_logical_and<int>::value)); +STATIC_ASSERT((has_logical_and<int, long>::value)); +STATIC_ASSERT((has_logical_and<int*>::value)); +STATIC_ASSERT((has_logical_and<X>::value)); +STATIC_ASSERT((has_logical_and<X, Y>::value)); +STATIC_ASSERT((!has_logical_and<Y, X>::value)); +STATIC_ASSERT((!has_logical_and<Y>::value)); +STATIC_ASSERT((has_logical_and<int X::*>::value)); +STATIC_ASSERT((has_logical_and<int X::*, int Y::*>::value)); +STATIC_ASSERT((has_logical_and<int*, float*>::value)); +STATIC_ASSERT((has_logical_and<X*, Z*>::value)); +STATIC_ASSERT((has_logical_and<X*, Y*>::value)); + +// has_logical_or +DEFINE_BINARY_PREDICATE_TRAIT(has_logical_or,||); +bool operator||(X, X); +convertible_to_bool operator||(X, Y); +not_convertible_to_bool operator||(Y, X); + +STATIC_ASSERT((has_logical_or<int>::value)); +STATIC_ASSERT((has_logical_or<int, long>::value)); +STATIC_ASSERT((has_logical_or<int*>::value)); +STATIC_ASSERT((has_logical_or<X>::value)); +STATIC_ASSERT((has_logical_or<X, Y>::value)); +STATIC_ASSERT((!has_logical_or<Y, X>::value)); +STATIC_ASSERT((!has_logical_or<Y>::value)); +STATIC_ASSERT((has_logical_or<int X::*>::value)); +STATIC_ASSERT((has_logical_or<int X::*, int Y::*>::value)); +STATIC_ASSERT((has_logical_or<int*, float*>::value)); +STATIC_ASSERT((has_logical_or<X*, Z*>::value)); +STATIC_ASSERT((has_logical_or<X*, Y*>::value)); diff --git a/gcc/testsuite/g++.dg/template/sfinae9.C b/gcc/testsuite/g++.dg/template/sfinae9.C new file mode 100644 index 000000000..4e27ff61b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae9.C @@ -0,0 +1,207 @@ +// DR 339 +// +// Test of the use of various assignment operators with SFINAE + +// Boilerplate helpers +typedef char yes_type; +struct no_type { char data[2]; }; + +template<typename T> T create_a(); +template<typename T> struct type { }; + +template<bool, typename T = void> struct enable_if { typedef T type; }; +template<typename T> struct enable_if<false, T> { }; + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#define DEFINE_INFIX_BINARY_TRAIT(Name,Op) \ +template<typename T, typename U> \ + typename enable_if<(sizeof(create_a<T>() Op create_a<U>(), 1) > 0), \ + yes_type>::type \ + JOIN(check_,Name)(type<T>, type<U>); \ + \ +no_type JOIN(check_,Name)(...); \ + \ +template<typename T, typename U = T> \ +struct Name \ +{ \ + static const bool value = \ + (sizeof(JOIN(check_,Name)(type<T&>(), type<U>())) == sizeof(yes_type)); \ +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define STATIC_ASSERT(Expr) static_assert(Expr, #Expr) +#else +# define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1] +#endif + +struct Y { + Y& operator=(Y&); +}; + +struct X { + X& operator=(Y); + X& operator+=(X); + X& operator-=(X); + X& operator*=(X); + X& operator/=(X); + X& operator%=(X); + X& operator^=(X); + X& operator&=(X); + X& operator|=(X); + X& operator<<=(X); + X& operator>>=(X); +}; +struct Z { }; + +// is_assignable +DEFINE_INFIX_BINARY_TRAIT(is_assignable, =); +STATIC_ASSERT((is_assignable<int>::value)); +STATIC_ASSERT((is_assignable<int, long>::value)); +STATIC_ASSERT((is_assignable<X>::value)); +STATIC_ASSERT((!is_assignable<int*, int>::value)); +STATIC_ASSERT((is_assignable<int*>::value)); +STATIC_ASSERT((is_assignable<X, Y>::value)); +STATIC_ASSERT((!is_assignable<X, Z>::value)); +STATIC_ASSERT((!is_assignable<Y>::value)); +STATIC_ASSERT((!is_assignable<const int, long>::value)); + +// has_plus_assign +DEFINE_INFIX_BINARY_TRAIT(has_plus_assign, +=); +X& operator+=(X&, Y); +STATIC_ASSERT((has_plus_assign<int>::value)); +STATIC_ASSERT((has_plus_assign<int, long>::value)); +STATIC_ASSERT((has_plus_assign<X>::value)); +STATIC_ASSERT((has_plus_assign<int*, int>::value)); +STATIC_ASSERT((!has_plus_assign<int*>::value)); +STATIC_ASSERT((has_plus_assign<X, Y>::value)); +STATIC_ASSERT((!has_plus_assign<X, Z>::value)); +STATIC_ASSERT((!has_plus_assign<Y>::value)); +STATIC_ASSERT((!has_plus_assign<const int, long>::value)); + +// has_minus_assign +DEFINE_INFIX_BINARY_TRAIT(has_minus_assign, -=); +X& operator-=(X&, Y); +STATIC_ASSERT((has_minus_assign<int>::value)); +STATIC_ASSERT((has_minus_assign<int, long>::value)); +STATIC_ASSERT((has_minus_assign<X>::value)); +STATIC_ASSERT((has_minus_assign<int*, int>::value)); +STATIC_ASSERT((!has_minus_assign<int*>::value)); +STATIC_ASSERT((has_minus_assign<X, Y>::value)); +STATIC_ASSERT((!has_minus_assign<X, Z>::value)); +STATIC_ASSERT((!has_minus_assign<Y>::value)); +STATIC_ASSERT((!has_minus_assign<int X::*>::value)); +STATIC_ASSERT((!has_minus_assign<const int, long>::value)); + +// has_multiply_assign +DEFINE_INFIX_BINARY_TRAIT(has_multiply_assign, *=); +X& operator*=(X&, Y); +STATIC_ASSERT((has_multiply_assign<int>::value)); +STATIC_ASSERT((has_multiply_assign<int, long>::value)); +STATIC_ASSERT((has_multiply_assign<X>::value)); +STATIC_ASSERT((!has_multiply_assign<int*, int>::value)); +STATIC_ASSERT((!has_multiply_assign<int*>::value)); +STATIC_ASSERT((has_multiply_assign<X, Y>::value)); +STATIC_ASSERT((!has_multiply_assign<X, Z>::value)); +STATIC_ASSERT((!has_multiply_assign<Y>::value)); +STATIC_ASSERT((!has_multiply_assign<int X::*>::value)); +STATIC_ASSERT((!has_multiply_assign<const int, long>::value)); + +// has_divide_assign +DEFINE_INFIX_BINARY_TRAIT(has_divide_assign, /=); +X& operator/=(X&, Y); +STATIC_ASSERT((has_divide_assign<int>::value)); +STATIC_ASSERT((has_divide_assign<int, long>::value)); +STATIC_ASSERT((has_divide_assign<X>::value)); +STATIC_ASSERT((!has_divide_assign<int*, int>::value)); +STATIC_ASSERT((!has_divide_assign<int*>::value)); +STATIC_ASSERT((has_divide_assign<X, Y>::value)); +STATIC_ASSERT((!has_divide_assign<X, Z>::value)); +STATIC_ASSERT((!has_divide_assign<Y>::value)); +STATIC_ASSERT((!has_divide_assign<int X::*>::value)); + +// has_remainder_assign +DEFINE_INFIX_BINARY_TRAIT(has_remainder_assign, %=); +X& operator%=(X&, Y); +STATIC_ASSERT((has_remainder_assign<int>::value)); +STATIC_ASSERT((has_remainder_assign<int, long>::value)); +STATIC_ASSERT((!has_remainder_assign<float>::value)); +STATIC_ASSERT((has_remainder_assign<X>::value)); +STATIC_ASSERT((!has_remainder_assign<int*, int>::value)); +STATIC_ASSERT((!has_remainder_assign<int*>::value)); +STATIC_ASSERT((has_remainder_assign<X, Y>::value)); +STATIC_ASSERT((!has_remainder_assign<X, Z>::value)); +STATIC_ASSERT((!has_remainder_assign<Y>::value)); +STATIC_ASSERT((!has_remainder_assign<int X::*>::value)); + +// has_xor_assign +DEFINE_INFIX_BINARY_TRAIT(has_xor_assign, ^=); +X& operator^=(X&, Y); +STATIC_ASSERT((has_xor_assign<int>::value)); +STATIC_ASSERT((has_xor_assign<int, long>::value)); +STATIC_ASSERT((!has_xor_assign<float>::value)); +STATIC_ASSERT((has_xor_assign<X>::value)); +STATIC_ASSERT((!has_xor_assign<int*, int>::value)); +STATIC_ASSERT((!has_xor_assign<int*>::value)); +STATIC_ASSERT((has_xor_assign<X, Y>::value)); +STATIC_ASSERT((!has_xor_assign<X, Z>::value)); +STATIC_ASSERT((!has_xor_assign<Y>::value)); +STATIC_ASSERT((!has_xor_assign<int X::*>::value)); + +// has_bitand_assign +DEFINE_INFIX_BINARY_TRAIT(has_bitand_assign, &=); +X& operator&=(X&, Y); +STATIC_ASSERT((has_bitand_assign<int>::value)); +STATIC_ASSERT((has_bitand_assign<int, long>::value)); +STATIC_ASSERT((!has_bitand_assign<float>::value)); +STATIC_ASSERT((has_bitand_assign<X>::value)); +STATIC_ASSERT((!has_bitand_assign<int*, int>::value)); +STATIC_ASSERT((!has_bitand_assign<int*>::value)); +STATIC_ASSERT((has_bitand_assign<X, Y>::value)); +STATIC_ASSERT((!has_bitand_assign<X, Z>::value)); +STATIC_ASSERT((!has_bitand_assign<Y>::value)); +STATIC_ASSERT((!has_bitand_assign<int X::*>::value)); + +// has_bitor_assign +DEFINE_INFIX_BINARY_TRAIT(has_bitor_assign, |=); +X& operator|=(X&, Y); +STATIC_ASSERT((has_bitor_assign<int>::value)); +STATIC_ASSERT((has_bitor_assign<int, long>::value)); +STATIC_ASSERT((!has_bitor_assign<float>::value)); +STATIC_ASSERT((has_bitor_assign<X>::value)); +STATIC_ASSERT((!has_bitor_assign<int*, int>::value)); +STATIC_ASSERT((!has_bitor_assign<int*>::value)); +STATIC_ASSERT((has_bitor_assign<X, Y>::value)); +STATIC_ASSERT((!has_bitor_assign<X, Z>::value)); +STATIC_ASSERT((!has_bitor_assign<Y>::value)); +STATIC_ASSERT((!has_bitor_assign<int X::*>::value)); + +// has_left_shift_assign +DEFINE_INFIX_BINARY_TRAIT(has_left_shift_assign, <<=); +X& operator<<=(X&, Y); +STATIC_ASSERT((has_left_shift_assign<int>::value)); +STATIC_ASSERT((has_left_shift_assign<int, long>::value)); +STATIC_ASSERT((!has_left_shift_assign<float>::value)); +STATIC_ASSERT((has_left_shift_assign<X>::value)); +STATIC_ASSERT((!has_left_shift_assign<int*, int>::value)); +STATIC_ASSERT((!has_left_shift_assign<int*>::value)); +STATIC_ASSERT((has_left_shift_assign<X, Y>::value)); +STATIC_ASSERT((!has_left_shift_assign<X, Z>::value)); +STATIC_ASSERT((!has_left_shift_assign<Y>::value)); +STATIC_ASSERT((!has_left_shift_assign<int X::*>::value)); + +// has_right_shift_assign +DEFINE_INFIX_BINARY_TRAIT(has_right_shift_assign, >>=); +X& operator>>=(X&, Y); +STATIC_ASSERT((has_right_shift_assign<int>::value)); +STATIC_ASSERT((has_right_shift_assign<int, long>::value)); +STATIC_ASSERT((!has_right_shift_assign<float>::value)); +STATIC_ASSERT((has_right_shift_assign<X>::value)); +STATIC_ASSERT((!has_right_shift_assign<int*, int>::value)); +STATIC_ASSERT((!has_right_shift_assign<int*>::value)); +STATIC_ASSERT((has_right_shift_assign<X, Y>::value)); +STATIC_ASSERT((!has_right_shift_assign<X, Z>::value)); +STATIC_ASSERT((!has_right_shift_assign<Y>::value)); +STATIC_ASSERT((!has_right_shift_assign<int X::*>::value)); diff --git a/gcc/testsuite/g++.dg/template/shift1.C b/gcc/testsuite/g++.dg/template/shift1.C new file mode 100644 index 000000000..a4ceec92c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/shift1.C @@ -0,0 +1,11 @@ +// PR c++/18140 +// { dg-options "-std=gnu++98" } + +template <int N> struct IntHolder { + static const int value = N; +}; + +template <int N, int S> struct ShrIntHolder { + static const int value = IntHolder< N>>S >::value; +}; + diff --git a/gcc/testsuite/g++.dg/template/sizeof-template-argument.C b/gcc/testsuite/g++.dg/template/sizeof-template-argument.C new file mode 100644 index 000000000..2cdc32859 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof-template-argument.C @@ -0,0 +1,15 @@ +/* This used to ICE (PR c++/29573) */ +/* { dg-do compile } */ + +template<int> struct A {}; + +template<typename> struct B : A <sizeof(=)> {}; /* { dg-error "parse error in template argument list" } */ + +template<typename> struct C : A <sizeof(=)> {}; /* { dg-error "parse error in template argument list" } */ + +int a; + +template<typename> struct D : A <sizeof(a=1)> {}; /* This used to ICE as well. */ + +template<typename> struct E : A <sizeof(a=1)> {}; /* This used to ICE as well. */ + diff --git a/gcc/testsuite/g++.dg/template/sizeof1.C b/gcc/testsuite/g++.dg/template/sizeof1.C new file mode 100644 index 000000000..45a7db48c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof1.C @@ -0,0 +1,15 @@ +// Test use of `sizeof' as a template parameter. +// Origin: smacdonald@seimac.com + +// { dg-do compile } + +template <unsigned I> struct A { static char *value; }; + +template <typename SizeType> +struct B +{ +char * f() const +{ +return (A<sizeof(void *)>::value); +} +}; diff --git a/gcc/testsuite/g++.dg/template/sizeof10.C b/gcc/testsuite/g++.dg/template/sizeof10.C new file mode 100644 index 000000000..5ecf13e13 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof10.C @@ -0,0 +1,7 @@ +// PR c++/23357 + +template<typename T> bool foo() +{ + const long int i = sizeof(T) > 1 ? sizeof(T) : 0; + return i > 0; +} diff --git a/gcc/testsuite/g++.dg/template/sizeof11.C b/gcc/testsuite/g++.dg/template/sizeof11.C new file mode 100644 index 000000000..7428e0b23 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof11.C @@ -0,0 +1,14 @@ +// PR c++/29435 + +template < class T > struct A {}; +template < int> void g() +{ + sizeof (A < int>); +} + +template < class T > struct B; +template < int> void f() +{ + sizeof (B<int>); // { dg-error "incomplete" } +} + diff --git a/gcc/testsuite/g++.dg/template/sizeof12.C b/gcc/testsuite/g++.dg/template/sizeof12.C new file mode 100644 index 000000000..e165d2aab --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof12.C @@ -0,0 +1,19 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/41863 + +template<int X> +struct Bar +{ +}; + +template<typename T> +class Foo +{ + T m_foo; + + void + crash() + { + Bar<sizeof(m_foo)> bar; + } +}; diff --git a/gcc/testsuite/g++.dg/template/sizeof13.C b/gcc/testsuite/g++.dg/template/sizeof13.C new file mode 100644 index 000000000..2f4a26e50 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof13.C @@ -0,0 +1,17 @@ +// PR c++/42623 +// We should choose f(B) because f(A<undef>) involves applying sizeof to +// an incomplete class, so it is removed by SFINAE. +// { dg-do link } + +struct undef; + +template <typename U, int N = sizeof(U)> struct A { A(int); }; +template <typename U> void f(A<U>); + +template <typename U> struct B { B(int) { } }; +template <typename U> void f(B<U>) { } + +int main() +{ + f<undef>(0); +} diff --git a/gcc/testsuite/g++.dg/template/sizeof2.C b/gcc/testsuite/g++.dg/template/sizeof2.C new file mode 100644 index 000000000..76d1cf44c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof2.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +template<int size> +struct Foobar { + // Contents irrelevant +}; + +template <typename A> +struct Wrapper { + // Contents irrelevant +}; + +template <typename A> +Foobar<sizeof(Wrapper<A>)> * +compiler_bug (A) +{ + return 0; +} + +int main() +{ + compiler_bug(1); +} diff --git a/gcc/testsuite/g++.dg/template/sizeof3.C b/gcc/testsuite/g++.dg/template/sizeof3.C new file mode 100644 index 000000000..a98bbc30a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof3.C @@ -0,0 +1,13 @@ +// The call to f is not potentially evaluated (3.2), so f<int> is not used, +// so it should not be instantiated. + +template <class T> +T f (T) +{ + typename T::X x; +} + +int main() +{ + int i = sizeof (f(0)); +} diff --git a/gcc/testsuite/g++.dg/template/sizeof4.C b/gcc/testsuite/g++.dg/template/sizeof4.C new file mode 100644 index 000000000..4856a2741 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof4.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: <anthwil at nortelnetworks dot com> +// c++/4933: using sizeof with comma operator as template argument + +template<unsigned F> +struct Foo {}; + +template<typename T> +T makeT(); + +template<typename T,typename U> +struct Bar +{ + typedef Foo + < + sizeof((makeT<T>(), makeT<U>())) + > Type; +}; diff --git a/gcc/testsuite/g++.dg/template/sizeof5.C b/gcc/testsuite/g++.dg/template/sizeof5.C new file mode 100644 index 000000000..4096fed53 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof5.C @@ -0,0 +1,15 @@ +// PR c++/9907 +// Origin: nes@lrde.epita.fr +// sizeof(foo()) was not considered constant. + + +template <unsigned n> struct bar {}; + +int foo(); + +template <class T> +void baz() +{ + bar<sizeof(foo())> b; +} + diff --git a/gcc/testsuite/g++.dg/template/sizeof6.C b/gcc/testsuite/g++.dg/template/sizeof6.C new file mode 100644 index 000000000..3ef3794b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof6.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// Contributed by Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +// PR c++/13683: bogus warning about passing non-PODs through ellipsis + +struct B {}; +struct NonPOD : B {}; + +struct A +{ + static int check(...); + static NonPOD GetNonPOD(void); + enum { value = sizeof(A::check(A::GetNonPOD())) }; +}; diff --git a/gcc/testsuite/g++.dg/template/sizeof7.C b/gcc/testsuite/g++.dg/template/sizeof7.C new file mode 100644 index 000000000..4964bfd25 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof7.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// Testcase by: bangerth@dealii.org +// PR c++/10858: failure with calling a method inside sizeof in a template + + template <int> struct P {}; + + void bar (); + + template <class T> struct X { + static int foo(void (*)()); + P<sizeof(foo(&bar))> p; + }; + + template class X<int>; diff --git a/gcc/testsuite/g++.dg/template/sizeof8.C b/gcc/testsuite/g++.dg/template/sizeof8.C new file mode 100644 index 000000000..861febc16 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof8.C @@ -0,0 +1,9 @@ +// { dg-do compile } +// Testcase by: bangerth@dealii.org +// PR c++/11406: ICE + +template <int> struct S{}; + +template <int N> S<sizeof(new double[N])> f() {} + +template S<sizeof(void*)> f<2>(); diff --git a/gcc/testsuite/g++.dg/template/sizeof9.C b/gcc/testsuite/g++.dg/template/sizeof9.C new file mode 100644 index 000000000..8d9ec95ae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sizeof9.C @@ -0,0 +1,6 @@ +// PR c++/21025 + +template<int N> struct X { char x[N]; }; +template<typename T> X<1 + sizeof(T) - sizeof(T)> F(T const &); +template<int N> struct S { int d() { F(1); } }; + diff --git a/gcc/testsuite/g++.dg/template/spec1.C b/gcc/testsuite/g++.dg/template/spec1.C new file mode 100644 index 000000000..27996377f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec1.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: <schmid@snake.iap.physik.tu-darmstadt.de> + +// Bug: ICE during invalid instantiation of member function +// which enclosing class is specialized. + +template <class T> +struct A +{ + void f(T) {} +}; + +template<> +struct A<int> +{ + void f(int) {} +}; + +template +void A<int>::f(int); // { dg-error "not match" } diff --git a/gcc/testsuite/g++.dg/template/spec10.C b/gcc/testsuite/g++.dg/template/spec10.C new file mode 100644 index 000000000..4bf7f46a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec10.C @@ -0,0 +1,27 @@ +// { dg-do run } + +// Origin: Lynn Akers <lakers@peachtree.com> + +// PR c++/10940: Problem handling parameter list for static member +// that is a specialization of a member template of a template class. + +template<int b> +class o +{ +public: + template<typename T> static void do_add(T* p, T v); +}; + +template<> +template<typename T> +inline void o<32>::do_add(T* p, T v) +{ + *p += v; +} + +int main() +{ + int a = 0x1000; + o<32>().do_add<int>(&a, 0x2000); + return (a != 0x3000); +} diff --git a/gcc/testsuite/g++.dg/template/spec11.C b/gcc/testsuite/g++.dg/template/spec11.C new file mode 100644 index 000000000..36d93a94e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec11.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: jhbrown@bluefinrobotics.com + +// PR c++/13635: ICE explicit specialization of member function template + +template <class foo> +class bar { +public: + template <class baz> + int func(baz *x); +}; + +template <> +template <class baz> +int bar<double>::func(baz *x) { return 5;} + +template <> +template <> +int bar<double>::func(int *x) { return 5;} diff --git a/gcc/testsuite/g++.dg/template/spec12.C b/gcc/testsuite/g++.dg/template/spec12.C new file mode 100644 index 000000000..7cf2e2f0a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec12.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Contributed by: Wolfgang Bangerth <bangerth at dealii dot org> +// PR c++/14409: Accepts invalid function signature for explicit instantiation + +struct X +{ + template <typename U> + void foo (U) {} + + template <typename U> + void foo_const (U) const {} +}; + +template void X::foo (int); +template void X::foo_const (int) const; + +template void X::foo (int) const; // { dg-error "" } +template void X::foo_const (int); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/spec13.C b/gcc/testsuite/g++.dg/template/spec13.C new file mode 100644 index 000000000..f2a3a373e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec13.C @@ -0,0 +1,16 @@ +// { dg-options "-w" } + +template <typename T> +struct S { + int i; + template <typename U> void f(U) {} +}; + +template<> +template <typename U> +void S<int>::f(U) { i; } + +void f() { + S<int> s; + s.f<int>(3); +} diff --git a/gcc/testsuite/g++.dg/template/spec14.C b/gcc/testsuite/g++.dg/template/spec14.C new file mode 100644 index 000000000..9b59565c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec14.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: <weissr at informatik dot uni-tuebingen dot de> +// PR c++/3671: Non-type enum parameters must not be converted + +enum T1 {a}; +enum T2 {b}; + +struct Y { + template <T1 i> void foo() {} + template <T2 i> void foo() {} +}; + +struct Z { + template <T1 i> void foo() {} +}; + +template void Y::foo<b> (); +template void Z::foo<b> (); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/spec15.C b/gcc/testsuite/g++.dg/template/spec15.C new file mode 100644 index 000000000..37fbc08e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec15.C @@ -0,0 +1,35 @@ +// { dg-do compile } +// Contributed by Wolfgang Bangerth <bangerth at ticam dot utexas dot edu> +// PR c++/509: Make sure specializations of member templates match correctly +// between template and non-template overloads. + +template <class T> +struct A { + template <class U> void f (U); + void f2 (int); + + template <class U> void h (U); + void h (long); +}; + +template <> +struct A<float> { + template <class U> void g (U); + void g2 (float); +}; + +template <> void A<int>::f (int); // { dg-error "" } +// { dg-message "need 2" "" { target *-*-* } 21 } +template <> template <> void A<int>::f (int); + +template <> void A<int>::f2 (int); +template <> template <> void A<int>::f2 (int); // { dg-error "" } + +template <> void A<float>::g (float); +template <> template <> void A<float>::g(float); // { dg-error "" } + +template <> void A<float>::g2 (float); // { dg-error "" } +template <> template <> void A<float>::g2(float); // { dg-error "" } + +template <> void A<long>::h (long); +template <> template <> void A<long>::h(long); diff --git a/gcc/testsuite/g++.dg/template/spec16.C b/gcc/testsuite/g++.dg/template/spec16.C new file mode 100644 index 000000000..c872052a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec16.C @@ -0,0 +1,11 @@ +// { dg-do compile } +// Contributed by Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +// PR c++/14497: Reject specialization without template headers + +template <int N> +struct A { + template<int M> void B () ; +}; + +void A<0>::B<0>() { // { dg-error "specializing member 'A<0>::B<0>' requires 'template<>' syntax" } +} diff --git a/gcc/testsuite/g++.dg/template/spec17.C b/gcc/testsuite/g++.dg/template/spec17.C new file mode 100644 index 000000000..237557684 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec17.C @@ -0,0 +1,11 @@ +// PR c++/16224 + +namespace io { + template <typename> int foo(); // { dg-error "" } +} + +using namespace io; + +template<> int foo<int>(); // { dg-error "" } + +int a = foo<int>(); diff --git a/gcc/testsuite/g++.dg/template/spec18.C b/gcc/testsuite/g++.dg/template/spec18.C new file mode 100644 index 000000000..a22e8543d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec18.C @@ -0,0 +1,13 @@ +// PR c++/17936 + +template<int, int N> struct A +{ + void foo(); +}; + +template<int N> struct A<1, N> +{ + void foo(); +}; + +template<> void A<1, 2>::foo(); diff --git a/gcc/testsuite/g++.dg/template/spec19.C b/gcc/testsuite/g++.dg/template/spec19.C new file mode 100644 index 000000000..082431533 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec19.C @@ -0,0 +1,23 @@ +// PR c++/18962 + +template<class T1,int N1> +class Klasse +{ +public: + template <class T2,int N2> + void function( const Klasse<T2,N2>& ); +}; + +template<> +template<class T2,int N2> +void Klasse<int,1>::function( const Klasse<T2,N2>& param ) +{ + param; // make sure we use the argument list from the definition. +} + +int main() +{ + Klasse<int,1> instance; + Klasse<char,2> param; + instance.function( param ); +} diff --git a/gcc/testsuite/g++.dg/template/spec2.C b/gcc/testsuite/g++.dg/template/spec2.C new file mode 100644 index 000000000..de0fe4c15 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec2.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: <schmid@snake.iap.physik.tu-darmstadt.de> + +// Bug: Overloading of ordinary and template member function +// which enclosing class is specialized is not handled correctly. + +template <class T> +struct A +{ + void f(T) {} +}; + +template<> +struct A<int> +{ + void f(int) {} + template <class T> void f(T) {} +}; + +template +void A<int>::f(int); diff --git a/gcc/testsuite/g++.dg/template/spec20.C b/gcc/testsuite/g++.dg/template/spec20.C new file mode 100644 index 000000000..71548e4af --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec20.C @@ -0,0 +1,19 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 Mar 2005 <nathan@codesourcery.com> + +// Origin: Giovanni Bajo <giovannibajo@libero.it> +// Bug 19203: Failure to implement DR 214 + +template <class A> +void foo(const A& a); + +template <class RET, class ARG1> +int foo(RET (&)(ARG1)); // this one + + +float decl(int); + +int bar(void) +{ + return foo(decl); +} diff --git a/gcc/testsuite/g++.dg/template/spec21.C b/gcc/testsuite/g++.dg/template/spec21.C new file mode 100644 index 000000000..e04ac5a2d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec21.C @@ -0,0 +1,28 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 Mar 2005 <nathan@codesourcery.com> + +// { dg-do run } +// DR214 + +template <class T> T f(int) {return 0;} +template <class T, class U> T f(U){return 1;} + +template <typename T, typename R> T checked_cast (R const &) {return 0;} +template <typename T, typename R> T checked_cast (R *) {return 1;} + + +int main () +{ + int i = 0; + + if (f<int>(1)) + return 1; + + if (checked_cast<int>(i) != 0) + return 2; + + if (checked_cast<int>(&i) != 1) + return 3; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/spec22.C b/gcc/testsuite/g++.dg/template/spec22.C new file mode 100644 index 000000000..f916ea468 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec22.C @@ -0,0 +1,21 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Apr 2005 <nathan@codesourcery.com> + +// PR 20723 +// Origin: Andrew Pinski <pinskia@gcc.gnu.org> +// Nathan Sidwell <nathan@gcc.gnu.org> + +template <typename T> class srp; +template <typename T> struct ptr +{ + template <typename U> ptr(const srp<U> &other); // { dg-message "ptr<T>::ptr" } +}; +template <typename T> struct srp +{ + template <typename U> operator ptr<U>(void) const; // { dg-message "srp<T>::operator" } +}; +ptr<int> parent_get() +{ + srp<int> parent; // { dg-message "candidate" } + return parent; // { dg-error "is ambiguous" } +} diff --git a/gcc/testsuite/g++.dg/template/spec23.C b/gcc/testsuite/g++.dg/template/spec23.C new file mode 100644 index 000000000..3d401f00e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec23.C @@ -0,0 +1,26 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Apr 2005 <nathan@codesourcery.com> + +// PR 20723 +// Origin: Andrew Pinski <pinskia@gcc.gnu.org> +// Nathan Sidwell <nathan@gcc.gnu.org> + +struct Foo +{ + template <typename T> + Foo (const T &); // { dg-message "T = Bar" } +}; + +struct Bar +{ + template <typename T> + operator T () const; // { dg-message "T = Foo" } +}; + +Foo Quux (Bar const &b) +{ + return b; // { dg-error "ambiguous" } + // { dg-message "candidate" "candidate note" { target *-*-* } 22 } +} + + diff --git a/gcc/testsuite/g++.dg/template/spec24.C b/gcc/testsuite/g++.dg/template/spec24.C new file mode 100644 index 000000000..08848952e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec24.C @@ -0,0 +1,22 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 June 2005 <nathan@codesourcery.com> + +// PR 20350: ICE on member specialization with later initialization +// Origin: Carlo Wood carlo@gcc.gnu.org + +template <int i> struct Mutex +{ + static int mutex; +}; + +template <int i> +int Mutex<i>::mutex = {1}; + +template <> int Mutex<0>::mutex; +template <> int Mutex<0>::mutex = 0; + +void g() +{ + Mutex<0>::mutex = 0; +} + diff --git a/gcc/testsuite/g++.dg/template/spec25.C b/gcc/testsuite/g++.dg/template/spec25.C new file mode 100644 index 000000000..3f641fe5a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec25.C @@ -0,0 +1,10 @@ +namespace N { + template <typename T> + struct S { + void f() {} + }; +} + +namespace K { + template <> void N::S<char>::f() {} // { dg-error "namespace|definition" } +} diff --git a/gcc/testsuite/g++.dg/template/spec26.C b/gcc/testsuite/g++.dg/template/spec26.C new file mode 100644 index 000000000..3d187071a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec26.C @@ -0,0 +1,35 @@ +// dg-do run +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 16 Sep 2005 <nathan@codesourcery.com> + +// PR 23519 template specialization ordering (DR214) +// Origin: Maxim Yegorushkin <maxim.yegorushkin@gmail.com> + +struct A +{ + template<class T> int operator+(T&) { return 1;} +}; + +template<class T> struct B +{ + int operator-(A&) {return 2;} + template<typename R> int operator*(R&) {return 3;} +}; + +template <typename T, typename R> int operator-(B<T>, R&) {return 4;} +template<class T> int operator+(A&, B<T>&) { return 5;} +template <typename T> int operator*(T &, A&){return 6;} + +int main() +{ + A a; + B<A> b; + if ((a + b) != 5) + return 1; + + if ((b - a) != 2) + return 2; + + if ((b * a) != 6) + return 3; +} diff --git a/gcc/testsuite/g++.dg/template/spec27.C b/gcc/testsuite/g++.dg/template/spec27.C new file mode 100644 index 000000000..a31adadd3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec27.C @@ -0,0 +1,14 @@ +// PR c++/24139 + +template<typename T> +struct O { + struct I; +}; + +template<> +struct O<int>::I +{ + I(); +}; + +O<int>::I::I() {} diff --git a/gcc/testsuite/g++.dg/template/spec28.C b/gcc/testsuite/g++.dg/template/spec28.C new file mode 100644 index 000000000..f0bb22cae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec28.C @@ -0,0 +1,6 @@ +// PR c++/25854 +// Bad diagnostic +// { dg-do compile } + +template<typename> struct A {}; // { dg-error "provided" } +template<> struct A<> {}; // { dg-error "wrong number" } diff --git a/gcc/testsuite/g++.dg/template/spec29.C b/gcc/testsuite/g++.dg/template/spec29.C new file mode 100644 index 000000000..4df00ee7d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec29.C @@ -0,0 +1,13 @@ +// PR c++/25855 +// { dg-do run } + +template <typename T> int qCompare(const T *t1, const T *t2) { return 1; } +template <typename T> int qCompare(T *t1, T *t2) { return 2; } +template <typename T1, typename T2> int qCompare(const T1 *t1, const T2 *t2) { + return 3; } +template<> int qCompare(const char *t1, const char *t2) { return 4; } +int main() +{ + if (qCompare("a", "b") != 4) + return 1; +} diff --git a/gcc/testsuite/g++.dg/template/spec3.C b/gcc/testsuite/g++.dg/template/spec3.C new file mode 100644 index 000000000..d3fa401b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec3.C @@ -0,0 +1,16 @@ +// PR c++/3870 +// Test that performing a type instantiation in order to match up a +// specialization doesn't clobber last_function_parms. + +template <class T> +struct A { typedef int I; }; + +template <class T> +inline typename T::I +foo (typename T::I, const T*); + +template <> +int foo (int i, const A<long>*) +{ + return i + 1; +} diff --git a/gcc/testsuite/g++.dg/template/spec30.C b/gcc/testsuite/g++.dg/template/spec30.C new file mode 100644 index 000000000..403b812f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec30.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +template<int N> +inline int +foo (int a) +{ + return a; +} + +template<> +inline int +foo<0> (int a = 123) // { dg-error "default argument" } +{ + return a + 1; +} diff --git a/gcc/testsuite/g++.dg/template/spec31.C b/gcc/testsuite/g++.dg/template/spec31.C new file mode 100644 index 000000000..3b36ab486 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec31.C @@ -0,0 +1,10 @@ +// PR c++/28058 + +template<int> struct A +{ + A() {} +}; + +A<0> a; + +template<> A<0>::A() {} // { dg-error "specialization" } diff --git a/gcc/testsuite/g++.dg/template/spec32.C b/gcc/testsuite/g++.dg/template/spec32.C new file mode 100644 index 000000000..6ef172b50 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec32.C @@ -0,0 +1,6 @@ +//PR c++/28861 + +struct A +{ + template<template<int> class B> struct B<0>; // { dg-error "name of class shadows" } +}; diff --git a/gcc/testsuite/g++.dg/template/spec33.C b/gcc/testsuite/g++.dg/template/spec33.C new file mode 100644 index 000000000..7b7a75198 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec33.C @@ -0,0 +1,7 @@ +//PR c++/27667 + +struct A +{ + template<int> static void foo () {} + template<> static void foo<0>() {} // { dg-error "explicit|template" } +}; diff --git a/gcc/testsuite/g++.dg/template/spec34.C b/gcc/testsuite/g++.dg/template/spec34.C new file mode 100644 index 000000000..6c28e57fb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec34.C @@ -0,0 +1,9 @@ +// PR c++/26988 + +struct B{}; + +struct Bar : virtual B { + template <typename T> Bar( T const& cast ); +}; + +template <> Bar::Bar( int const & cast ) {} diff --git a/gcc/testsuite/g++.dg/template/spec35.C b/gcc/testsuite/g++.dg/template/spec35.C new file mode 100644 index 000000000..709ece5dd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec35.C @@ -0,0 +1,29 @@ +// PR c++/31923 +// C++ DR 605 -- "...the linkage of an explicit specialization must be that of +// the template." + +// { dg-require-weak "" } +// { dg-do compile { target i?86-*-* x86_64-*-* } } + +template<class T> +static void f1 (T) { } + +// { dg-final { scan-assembler-not ".glob(a|)l\[\t \]*_?_Z2f1IfEvT_" } } +template<> +void f1<float> (float) { } // Expected to have static linkage + +template<class T> +void f2 (T) { } + +// { dg-final { scan-assembler ".glob(a|)l\[\t \]*_?_Z2f2IfEvT_" } } +template<> +void f2<float> (float) { } // Expected to have global linkage + +void instantiator () +{ + // { dg-final { scan-assembler-not ".glob(a|)l\[\t \]*_?_Z2f1IiEvT_" } } + f1(0); // Expected to have static linkage + + // { dg-final { scan-assembler ".weak(_definition)?\[\t \]*_?_Z2f2IiEvT_" { target { ! { *-*-mingw* *-*-cygwin } } } } } + f2(0); // Expected to have weak global linkage +} diff --git a/gcc/testsuite/g++.dg/template/spec36.C b/gcc/testsuite/g++.dg/template/spec36.C new file mode 100644 index 000000000..7e8dc5241 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec36.C @@ -0,0 +1,16 @@ +/* PR c++/38089 */ +/* { dg-do compile } */ + +struct basic_string +{ + basic_string(const int __s); +}; +namespace MyNS { + class MyClass { + template <typename T> + T test() { } /* { dg-error "from definition" } */ + }; +} +template <> +basic_string MyNS::MyClass::test() /* { dg-error "specialization of" } */ +{ return 1; } diff --git a/gcc/testsuite/g++.dg/template/spec37.C b/gcc/testsuite/g++.dg/template/spec37.C new file mode 100644 index 000000000..2c01eb028 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec37.C @@ -0,0 +1,6 @@ +// PR c++/28300 + +template<typename> struct A +{ + template<typename T> struct A<T*>; // { dg-error "namespace scope" } +}; diff --git a/gcc/testsuite/g++.dg/template/spec4.C b/gcc/testsuite/g++.dg/template/spec4.C new file mode 100644 index 000000000..18116acb5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec4.C @@ -0,0 +1,11 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <wolfgang.bangerth@iwr.uni-heidelberg.de> + +// PR c++/2863 +// Default function argument and template specialization. + +struct X { + template <int dim> void f(int=0); +}; + +template <> void X::f<1> () {} // { dg-error "(not match|declaration)" } diff --git a/gcc/testsuite/g++.dg/template/spec5.C b/gcc/testsuite/g++.dg/template/spec5.C new file mode 100644 index 000000000..ad101b01d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec5.C @@ -0,0 +1,3 @@ +template <int i> struct A; +template <> struct A<0> { struct B; }; +struct A<0>::B {}; diff --git a/gcc/testsuite/g++.dg/template/spec6.C b/gcc/testsuite/g++.dg/template/spec6.C new file mode 100644 index 000000000..915b83312 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec6.C @@ -0,0 +1,10 @@ +template <bool, int> struct X {}; + +template <bool C> struct X<C,1> { + typedef double* type; + type foo () const; +}; + +template <bool C> +typename X<C,1>::type +X<C,1>::foo () const {} diff --git a/gcc/testsuite/g++.dg/template/spec7.C b/gcc/testsuite/g++.dg/template/spec7.C new file mode 100644 index 000000000..18d3c90c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec7.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// PR c++/6440: Specialization of member class template. + +template<class T> struct A +{ + template<class U> struct B {}; +}; + +template<> template<class U> +struct A<int>::B +{ + void f(); + template <class V> void g(V); +}; + +template<> template<> template <class V> void A<int>::B<char>::g(V) +{ +} + +A<int>::B<char> b; + +int h() +{ + b.f(); + b.g(0); +} diff --git a/gcc/testsuite/g++.dg/template/spec8.C b/gcc/testsuite/g++.dg/template/spec8.C new file mode 100644 index 000000000..ccbf17c2f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec8.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +// Specialization of member class template. + +template<class T1> struct A +{ + template<class T2> struct B {}; + template<class T2> struct C {}; +}; + +template <> template <> struct A<int>::B<int>; +template <> template <class U> struct A<int>::B {}; +A<int>::B<int> ab; // { dg-error "incomplete" } + +A<int>::C<char> ac; +template <> template <class U> struct A<int>::C {}; // { dg-error "specialization" } diff --git a/gcc/testsuite/g++.dg/template/spec9.C b/gcc/testsuite/g++.dg/template/spec9.C new file mode 100644 index 000000000..013fa0d99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec9.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Lynn Akers <lakers@peachtree.com> +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/10956: Incorrect template substitution for member template +// specialization inside template class. + +template <int> struct C { + template<typename T> void pre_add(T); +}; + +template<> +template<typename T> +void C<32>::pre_add(T) { + T pre; +} + +int main() { + C<32>().pre_add<int>(1); +} diff --git a/gcc/testsuite/g++.dg/template/static1.C b/gcc/testsuite/g++.dg/template/static1.C new file mode 100644 index 000000000..98e1acb9e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static1.C @@ -0,0 +1,4 @@ +template <typename T> struct A +{ + static const int t[1][1]={{0}}; // { dg-error "brace-enclosed|in-class" } +}; diff --git a/gcc/testsuite/g++.dg/template/static10.C b/gcc/testsuite/g++.dg/template/static10.C new file mode 100644 index 000000000..881db081c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static10.C @@ -0,0 +1,24 @@ +// PR c++/19555 + +namespace __gnu_debug_def { } +namespace std +{ + using namespace __gnu_debug_def; + template<typename _Tp> class allocator {}; // { dg-message "std::allocator" } +} +namespace __gnu_debug_def +{ + template<typename _Tp, + typename _Allocator = std::allocator<_Tp> > + class vector + { + void + swap(vector<_Tp,_Allocator>& __x); + }; +} +namespace std +{ + template<> void + vector<int, allocator<int> >::swap(vector<int, allocator<int> >&) { } // { dg-error "" } + // { dg-message "suggested alternative" "suggested alternative" { target *-*-* } 22 } +} diff --git a/gcc/testsuite/g++.dg/template/static11.C b/gcc/testsuite/g++.dg/template/static11.C new file mode 100644 index 000000000..3e489eac5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static11.C @@ -0,0 +1,8 @@ +// PR c++/19826 + +template<typename T> struct A +{ + static const T i = 1; + char a[i]; +}; + diff --git a/gcc/testsuite/g++.dg/template/static12.C b/gcc/testsuite/g++.dg/template/static12.C new file mode 100644 index 000000000..73becab27 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static12.C @@ -0,0 +1,13 @@ +// PR c++/18470 + +template<typename> struct A +{ + static const int i=1; +}; + +template<typename T> struct B : A<T> +{ + using A<T>::i; + char s[i]; // fails + char t[A<T>::i]; // compiles +}; diff --git a/gcc/testsuite/g++.dg/template/static13.C b/gcc/testsuite/g++.dg/template/static13.C new file mode 100644 index 000000000..c43f55547 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static13.C @@ -0,0 +1,14 @@ +// PR c++/23099 + +struct Base { + int x; +}; + +template <typename T> +struct A { + static const int N = sizeof(static_cast<Base*>(T())); +}; + +struct Derived : Base { + A<Derived*> a; +}; diff --git a/gcc/testsuite/g++.dg/template/static14.C b/gcc/testsuite/g++.dg/template/static14.C new file mode 100644 index 000000000..5bc0e731a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static14.C @@ -0,0 +1,13 @@ +struct Base { + int x; +}; + +template <typename T> +struct A { + static const int N = sizeof(static_cast<Base*>(T())); + int a[N]; +}; + +struct Derived : Base { + A<Derived*> a; +}; diff --git a/gcc/testsuite/g++.dg/template/static15.C b/gcc/testsuite/g++.dg/template/static15.C new file mode 100644 index 000000000..d8faa35a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static15.C @@ -0,0 +1,71 @@ +// PR c++/23667 +// { dg-options "-std=gnu++98" } + +template<int dummy> + struct X + { + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; + }; + +template<int dummy> + const int X<dummy>::n_primes; + +template<int dummy> + const unsigned long X<dummy>::primes[n_primes + 1] = + { + 2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul, + 37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul, + 83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul, + 157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul, + 277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul, + 503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul, + 953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul, + 1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul, + 3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul, + 5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul, + 11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul, + 19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul, + 33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul, + 57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul, + 99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul, + 159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul, + 256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul, + 410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul, + 658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul, + 1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul, + 1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul, + 2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul, + 4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul, + 6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul, + 11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul, + 16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul, + 24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul, + 36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul, + 54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul, + 80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul, + 118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul, + 176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul, + 260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul, + 386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul, + 573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul, + 849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul, + 1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul, + 1725587117ul, 1866894511ul, 2019773507ul, 2185171673ul, + 2364114217ul, 2557710269ul, 2767159799ul, 2993761039ul, + 3238918481ul, 3504151727ul, 3791104843ul, 4101556399ul, + 4294967291ul, + 4294967291ul // sentinel so we don't have to test result of + // lower_bound + }; + +template<bool b> + struct static_assert; + +template<> + struct static_assert<true> { }; + +int main() +{ + static_assert< X<0>::n_primes == 256 >(); +} diff --git a/gcc/testsuite/g++.dg/template/static16.C b/gcc/testsuite/g++.dg/template/static16.C new file mode 100644 index 000000000..f33ac3a55 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static16.C @@ -0,0 +1,20 @@ +// PR c++/23691 + +namespace std { + class type_info { + bool operator==(const type_info& __arg) const; + }; +} +template <class T, T val> struct integral_constant { + static const T value = val; +}; +template< typename T > struct is_integral : integral_constant<bool,false> {}; +template <bool B> struct enable_if_c {}; +template<typename Functor> +typename enable_if_c<(is_integral<Functor>::value)>::type +operator==(const int& f, Functor g); +template<class D> +int get_deleter( std::type_info const & ti ) +{ + return ti == typeid(D); +} diff --git a/gcc/testsuite/g++.dg/template/static17.C b/gcc/testsuite/g++.dg/template/static17.C new file mode 100644 index 000000000..bf79bccc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static17.C @@ -0,0 +1,13 @@ +// PR c++/23896 + +template <int> struct X {}; + +template <typename T> struct length { + static const int value = 2; +}; + +template <typename T> void foo () { + sizeof(X<length<T>::value>); +} + +template void foo<int>(); diff --git a/gcc/testsuite/g++.dg/template/static18.C b/gcc/testsuite/g++.dg/template/static18.C new file mode 100644 index 000000000..2a2ace939 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static18.C @@ -0,0 +1,13 @@ +// PR c++/23914 + +template <class T> +struct foo_template { + static const unsigned complexity = 0; +}; + +template <int x> struct STATIC_ASSERTION {}; + +void gcc_402_problem_minimal() +{ + sizeof(STATIC_ASSERTION< foo_template<int>::complexity >); +} diff --git a/gcc/testsuite/g++.dg/template/static19.C b/gcc/testsuite/g++.dg/template/static19.C new file mode 100644 index 000000000..d720127b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static19.C @@ -0,0 +1,18 @@ +// PR c++/24275 + +template <bool val> struct bool_var { + static const bool value = val; +}; +namespace is_inc_ { + struct any { + template <class T> any(T const&); + }; + int operator++(any const&); + template <class T> struct impl { + static T &x; + static const bool value = sizeof(++x) == 1; + }; +} +template<typename T> struct is_incr : bool_var< is_inc_::impl<T>::value> {}; +struct not_incr{}; +typedef int sa1[ is_incr<not_incr>::value ? -1 : 1]; diff --git a/gcc/testsuite/g++.dg/template/static2.C b/gcc/testsuite/g++.dg/template/static2.C new file mode 100644 index 000000000..881f07ce9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static2.C @@ -0,0 +1,17 @@ +class A; + +template<int A::* P> +class B +{ +public: + static int A::* const p = P; // { dg-error "" } +}; + +class A +{ +public: + +int dummy; + +B<&A::dummy> d; +}; diff --git a/gcc/testsuite/g++.dg/template/static20.C b/gcc/testsuite/g++.dg/template/static20.C new file mode 100644 index 000000000..6f1096b88 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static20.C @@ -0,0 +1,14 @@ +// PR c++/24277 + +template< int Bits > struct uint_t { + typedef unsigned short fast; +}; +template < int Bits > struct mask_uint_t { + typedef typename uint_t< Bits >::fast fast; + static const fast sig_bits = 1; + static const fast sig_bits_fast = fast(sig_bits); +}; +template < int Bits> int checksum ( ) { + return 1 & mask_uint_t<Bits>::sig_bits_fast; +} +int i = checksum<1>(); diff --git a/gcc/testsuite/g++.dg/template/static21-a.cc b/gcc/testsuite/g++.dg/template/static21-a.cc new file mode 100644 index 000000000..9489ae7d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static21-a.cc @@ -0,0 +1,17 @@ +template<int dummy> + struct X + { + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; + }; + + template<int dummy> + const int X<dummy>::n_primes; + + template<int dummy> + const unsigned long X<dummy>::primes[n_primes + 1] = + { 0 }; + + +const unsigned long *f1(void){return &X<0>::primes[0];} +int main(){} diff --git a/gcc/testsuite/g++.dg/template/static21.C b/gcc/testsuite/g++.dg/template/static21.C new file mode 100644 index 000000000..66b045087 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static21.C @@ -0,0 +1,20 @@ +// PR c++/24389 +// { dg-additional-sources "static21-a.cc" } +// { dg-do link } + +template<int dummy> +struct X +{ + static const int n_primes = 256; + static const unsigned long primes[n_primes + 1]; +}; + +template<int dummy> +const int X<dummy>::n_primes; + +template<int dummy> +const unsigned long X<dummy>::primes[n_primes + 1] = + { 0 }; + +const unsigned long *f(void){return &X<0>::primes[0];} + diff --git a/gcc/testsuite/g++.dg/template/static22.C b/gcc/testsuite/g++.dg/template/static22.C new file mode 100644 index 000000000..02c7a0cd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static22.C @@ -0,0 +1,11 @@ +// PR c++/26266 + +template<typename> struct A +{ + static const int i = 1; + static const int j = i; + static const int k = int(j); + int x[k]; +}; + +A<char> a; diff --git a/gcc/testsuite/g++.dg/template/static23.C b/gcc/testsuite/g++.dg/template/static23.C new file mode 100644 index 000000000..b28400a64 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static23.C @@ -0,0 +1,15 @@ +// PR c++/26266 + +template<typename> struct A +{ + static const int i = 1; +}; + +template<typename> struct B +{ + static const int j = A<char>::i; + static const int k = int(j); + int x[k]; +}; + +B<char> b; diff --git a/gcc/testsuite/g++.dg/template/static24.C b/gcc/testsuite/g++.dg/template/static24.C new file mode 100644 index 000000000..3d8f9e326 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static24.C @@ -0,0 +1,15 @@ +template<typename> struct A; + +template<> struct A<char> +{ + static const char i = 1; +}; + +template<typename T> struct B +{ + static const int j = A<T>::i; + static const int k = int(j); + int x[k]; +}; + +B<char> b; diff --git a/gcc/testsuite/g++.dg/template/static25.C b/gcc/testsuite/g++.dg/template/static25.C new file mode 100644 index 000000000..20c0c846e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static25.C @@ -0,0 +1,14 @@ +// PR c++/27819 + +struct A +{ + static const char i = 1; +}; + +template<int> struct B +{ + static const int j = A::i; + int x[int(j)]; +}; + +B<0> b; diff --git a/gcc/testsuite/g++.dg/template/static26.C b/gcc/testsuite/g++.dg/template/static26.C new file mode 100644 index 000000000..095248bac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static26.C @@ -0,0 +1,10 @@ +// PR c++/28016 +// { dg-final { scan-assembler-not "computed" } } + +template<class T1, class T2> +struct scalar_divides_assign { + static const bool computed ; +}; + +template<class T1, class T2> +const bool scalar_divides_assign<T1,T2>::computed = true; diff --git a/gcc/testsuite/g++.dg/template/static27.C b/gcc/testsuite/g++.dg/template/static27.C new file mode 100644 index 000000000..0b63967e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static27.C @@ -0,0 +1,13 @@ +// PR c++/28235 + +template<typename> struct A +{ + static const bool i = true; + template<bool = i> struct B {}; + B<> b; +}; + +void f() { + A<int> a1, a2; + a1.b = a2.b; +} diff --git a/gcc/testsuite/g++.dg/template/static28.C b/gcc/testsuite/g++.dg/template/static28.C new file mode 100644 index 000000000..eb5ec5313 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static28.C @@ -0,0 +1,15 @@ +// PR c++/29518 + +template< bool C > int assertion_failed( int); +template< class > +struct N +{ + static bool const okay = true; + enum { + t = sizeof( assertion_failed<okay>( 0)) + }; +}; +int main() +{ + N<int> n; +} diff --git a/gcc/testsuite/g++.dg/template/static29.C b/gcc/testsuite/g++.dg/template/static29.C new file mode 100644 index 000000000..a949c0cd8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static29.C @@ -0,0 +1,5 @@ +// PR c++/29570 + +template<int> struct A { static const int i; }; + +template<int N> const int A<N>::i = { A<N>::i }; diff --git a/gcc/testsuite/g++.dg/template/static3.C b/gcc/testsuite/g++.dg/template/static3.C new file mode 100644 index 000000000..65cf2c9e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static3.C @@ -0,0 +1,25 @@ +template <class data> class foo +{ + public: + static const int a; + static const int b; + static const int c; + static const int d; +}; + +template <class data> const int foo<data>::a = 1; +template <class data> const int foo<data>::b = a; +template <class data> const int foo<data>::c = b; +template <class data> const int foo<data>::d = c; + +typedef foo<int> fooInt; + +int main( void ) +{ + fooInt *f; + + f = new fooInt(); + + if (f->c != 1 || f->d != 1) + return 1; +} diff --git a/gcc/testsuite/g++.dg/template/static30.C b/gcc/testsuite/g++.dg/template/static30.C new file mode 100644 index 000000000..01fa5dc1e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static30.C @@ -0,0 +1,10 @@ +// PR c++/31992 + +template <int> struct A +{ + static const int i1; + static const int i2; +}; + +template <int N> const int A<N>::i1(A<N>::i); +template <int N> const int A<N>::i2(3, A<N>::i); diff --git a/gcc/testsuite/g++.dg/template/static31.C b/gcc/testsuite/g++.dg/template/static31.C new file mode 100644 index 000000000..935a8a790 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static31.C @@ -0,0 +1,19 @@ +// PR c++/32674 + +class C +{ + static const int j = 3; +}; + +template<int> class A +{ + static const int i1; + static const int i2; + static const int i3; + static const int i4; +}; + +template<int N> const int A<N>::i1(C::j); +template<int N> const int A<N>::i2 = C::j; +template<int N> const int A<N>::i3(C::j, 5); // { dg-error "compound expression" } +template<int N> const int A<N>::i4 = (C::j, 7); diff --git a/gcc/testsuite/g++.dg/template/static4.C b/gcc/testsuite/g++.dg/template/static4.C new file mode 100644 index 000000000..c5486326c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static4.C @@ -0,0 +1,7 @@ +template <class R> +struct A { + static int _test; // { dg-error "" } + static int _test; // { dg-error "" } +}; +template <class R> int A<R>::_test = 0; +struct B : public A <int> { }; diff --git a/gcc/testsuite/g++.dg/template/static5.C b/gcc/testsuite/g++.dg/template/static5.C new file mode 100644 index 000000000..05eaf8fbd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static5.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// Origin: Mirek Fidler <cxl@ntllib.org> +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/12932: ICE address of static function as template argument + +struct Test { + static void fun(); +}; + +template <void (*fun)()> +void foo () { (*fun)(); } + + +template +void foo<Test::fun> (); diff --git a/gcc/testsuite/g++.dg/template/static6.C b/gcc/testsuite/g++.dg/template/static6.C new file mode 100644 index 000000000..30ecae940 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static6.C @@ -0,0 +1,14 @@ +// PR c++/13969 + +struct B { + static const int N=10; +}; + +template <int> struct X {}; + +template <typename> struct S { + static const int N = B::N; + X<N> x; +}; + +template class S<float>; diff --git a/gcc/testsuite/g++.dg/template/static7.C b/gcc/testsuite/g++.dg/template/static7.C new file mode 100644 index 000000000..edb8e6a8d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static7.C @@ -0,0 +1,16 @@ +// PR c++/17530 +// { dg-do link } + +typedef void (*Func) (); +void f (Func) {} +struct B +{ + static void staticfunc () {} +}; +template <int> +void C(){ f (B::staticfunc); } +int main () +{ + C<0>(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/static8.C b/gcc/testsuite/g++.dg/template/static8.C new file mode 100644 index 000000000..f8229fd82 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static8.C @@ -0,0 +1,8 @@ +// PR c++/17585 + +template <void (*p)(void)> struct S03 {}; +class C03 { +public: + static void f(void) {} + void g(void) { S03<&f> s03; } +}; diff --git a/gcc/testsuite/g++.dg/template/static9.C b/gcc/testsuite/g++.dg/template/static9.C new file mode 100644 index 000000000..884564760 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/static9.C @@ -0,0 +1,9 @@ +// PR c++/17524 + +template<typename T> struct A +{ + static const T i = 0; // { dg-error "declared void" "void" } + // { dg-error "invalid|non-literal" "invalid" { target *-*-* } 5 } +}; + +A<void> a; // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/stdarg1.C b/gcc/testsuite/g++.dg/template/stdarg1.C new file mode 100644 index 000000000..94804eeed --- /dev/null +++ b/gcc/testsuite/g++.dg/template/stdarg1.C @@ -0,0 +1,55 @@ +// PR c++/47022 +// { dg-do compile } +// Suppress a warning that is irrelevant to the purpose of this test. +// { dg-options "-Wno-abi" { target arm_eabi } } + +#include <cstdarg> + +template <typename T> +void +f1 (T *p, va_list ap) +{ + *p = va_arg (ap, long double); + *p += va_arg (ap, double); +} + +template <typename T> +void +f2 (T *p, va_list ap) +{ + *p = __real__ va_arg (ap, _Complex int); + *p += __imag__ va_arg (ap, _Complex double); + *p += __imag__ va_arg (ap, _Complex long double); +} + +template <typename T> +void +f3 (T *p, va_list ap) +{ + *p = va_arg (ap, T); +} + +void +foo (int x, va_list ap) +{ + if (x == 0) + { + long double ld; + f1 (&ld, ap); + } + else if (x == 1) + { + int i; + f2 (&i, ap); + } + else if (x == 2) + { + long double ld; + f3 (&ld, ap); + } + else if (x == 3) + { + _Complex double cd; + f3 (&cd, ap); + } +} diff --git a/gcc/testsuite/g++.dg/template/stmtexpr1.C b/gcc/testsuite/g++.dg/template/stmtexpr1.C new file mode 100644 index 000000000..a470ca8f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/stmtexpr1.C @@ -0,0 +1,10 @@ +// PR c++/17404 +// { dg-do compile } +// { dg-options "" } + +template <int> void foo () +{ + __builtin_expect (({0;}), 1); +} + +template void foo<1> (); diff --git a/gcc/testsuite/g++.dg/template/stmtexpr2.C b/gcc/testsuite/g++.dg/template/stmtexpr2.C new file mode 100644 index 000000000..ef29b43c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/stmtexpr2.C @@ -0,0 +1,26 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/36408 +// { dg-options "" } +// { dg-do compile } + +template<int> +void +foo() +{ + int i = ({ }); // { dg-error "void value not ignored" } +} + +template<int> +void +bar() +{ + int i = ({ ({}); }); // { dg-error "void value not ignored" } +} + +int +main () +{ + foo<0> (); + bar<0> (); +} + diff --git a/gcc/testsuite/g++.dg/template/string1.C b/gcc/testsuite/g++.dg/template/string1.C new file mode 100644 index 000000000..a5d6c7dd6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/string1.C @@ -0,0 +1,7 @@ +// PR c++/28337 + +template <int> void foo() +{ + (0 ? "" : "X") + 1; +} + diff --git a/gcc/testsuite/g++.dg/template/strlen1.C b/gcc/testsuite/g++.dg/template/strlen1.C new file mode 100644 index 000000000..ddec51d7b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/strlen1.C @@ -0,0 +1,9 @@ +template <typename A1> +void monk2 (A1) {} + +unsigned int strlen (const char*); + +void monk () +{ + monk2 (strlen ("")); +} diff --git a/gcc/testsuite/g++.dg/template/subst1.C b/gcc/testsuite/g++.dg/template/subst1.C new file mode 100644 index 000000000..827af23d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/subst1.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 16 Sep 2002 <nathan@codesourcery.com> + +// PR 7718. ICE. + +template <typename OBJECT> +void default_initializer(const OBJECT &) { } + + +template <typename OBJECT, void init_function(const OBJECT &)> +class cContainer { + public: + template <typename INITIALIZER> + void Add(const INITIALIZER &initializer) { + init_function(initializer); + } +}; + +int main() { + cContainer<int, default_initializer<int> > c; + + c.Add<int>(42); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/template-id-1.C b/gcc/testsuite/g++.dg/template/template-id-1.C new file mode 100644 index 000000000..60ce4e7ff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/template-id-1.C @@ -0,0 +1,33 @@ +// Copyright (C) 2002 Free Software Foundation +// Origin: C++/1058 +// Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> +// { dg-do compile } + +struct A { + typedef int Y; + typedef double Z; +}; + +struct B { + template<typename T> + void func(typename T::Y, typename T::Z) { } +}; + +template<typename T> +struct X { + void gunc(); +}; + +template<typename T> +void X<T>::gunc() +{ + B b; + b.func<A>(0, 3.); +} + +int main() +{ + X<int> x; + x.gunc(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/template-id-2.C b/gcc/testsuite/g++.dg/template/template-id-2.C new file mode 100644 index 000000000..6d37350e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/template-id-2.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: Richard Guenther <rguenth@tat.physik.uni-tuebingen.de> + +// PR c++/12924 + +template<typename> struct A {}; + +template<> struct A<void> +{ + template<typename T> void foo() + { + A<T> a; + a.template foo<int>(); // { dg-error "no member" } + } +}; + +void bar() +{ + A<void> a; + a.foo<int>(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/template-id-4.C b/gcc/testsuite/g++.dg/template/template-id-4.C new file mode 100644 index 000000000..26f4809bc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/template-id-4.C @@ -0,0 +1,22 @@ +// PR c++/48157 + +struct AType +{ + template<class AA> + void SomeFuncTemplate() + { } +}; + +template < class T > +struct TTest2 +{ + template<T> struct helper; + + template<class U> + static void check(helper<&U::template SomeFuncTemplate<int> > *); +}; + +int main() +{ + TTest2< void (AType::*)() >::check<AType>(0); +} diff --git a/gcc/testsuite/g++.dg/template/this-targ1.C b/gcc/testsuite/g++.dg/template/this-targ1.C new file mode 100644 index 000000000..6864be5ab --- /dev/null +++ b/gcc/testsuite/g++.dg/template/this-targ1.C @@ -0,0 +1,23 @@ +// PR c++/47904 + +template <bool> +struct S +{ +}; + +template <class T> +class U +{ + T t; + int foo () const + { + S <sizeof (t) == 1> s; + return 1; + } + int bar () const + { + S <sizeof (t) == 1> s; + return 1; + } +}; + diff --git a/gcc/testsuite/g++.dg/template/ttp1.C b/gcc/testsuite/g++.dg/template/ttp1.C new file mode 100644 index 000000000..7b323028e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp1.C @@ -0,0 +1,9 @@ +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// { dg-do compile } + +template <template <typename T> class A > +class B : virtual A<void> +{ + typedef int INT; + INT i; +}; diff --git a/gcc/testsuite/g++.dg/template/ttp10.C b/gcc/testsuite/g++.dg/template/ttp10.C new file mode 100644 index 000000000..09bdb1a84 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp10.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/16175: Missing cv qualifier in error message output + +template <typename> struct Template {}; + +template<template<typename> class D> +struct B { + static void foo1(const D<void> *); // { dg-error "const" } + static void foo2(volatile D<void> *);// { dg-error "volatile" } +}; + +class E : protected B<Template> {}; + +void bar() { + E::foo1 (0); // { dg-error "context" } + E::foo2 (0); // { dg-error "context" } +} diff --git a/gcc/testsuite/g++.dg/template/ttp11.C b/gcc/testsuite/g++.dg/template/ttp11.C new file mode 100644 index 000000000..84867e107 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp11.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// Origin: heinlein@informatik.uni-ulm.de + +// PR c++/14429: Matching of template template parameter containing +// non-type parameter with type that depends on earlier parameter. + +template <template <typename U, U* p> class T> +struct X {}; + +template <template <typename U, U* p> class T> +struct Y { + X<T> x; +}; diff --git a/gcc/testsuite/g++.dg/template/ttp12.C b/gcc/testsuite/g++.dg/template/ttp12.C new file mode 100644 index 000000000..554738bf4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp12.C @@ -0,0 +1,19 @@ +// Copyright (C) 2004 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +// Check the type of non-type parameter in template template parameter +// only if it is dependent. + +template <template <int* p> class T> +struct X {}; + +template <typename U, template <U* p> class T> +struct Y { + X<T> x; +}; + +template <int* p> struct Z {}; + +Y<int, Z> y1; +Y<char, Z> y2; // { dg-error "mismatch|expected|invalid" } diff --git a/gcc/testsuite/g++.dg/template/ttp13.C b/gcc/testsuite/g++.dg/template/ttp13.C new file mode 100644 index 000000000..2c35b3a79 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp13.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/15664: Template substitution of template template parameter + +template <int N> struct S { + template<template<typename> class A> + friend void foo(); +}; + +template<template<typename> class A> +void foo(); + +template <typename> struct X {}; + +int main () { + S<1> s; + foo<X>(); +} diff --git a/gcc/testsuite/g++.dg/template/ttp14.C b/gcc/testsuite/g++.dg/template/ttp14.C new file mode 100644 index 000000000..2b216090b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp14.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: akim@epita.fr +// Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/18276: Template substitution of template template parameter + +template<template<int> class> struct A; + +template<int> struct B +{ + template<template<int> class> friend class A; +}; + +B<0> b; diff --git a/gcc/testsuite/g++.dg/template/ttp15.C b/gcc/testsuite/g++.dg/template/ttp15.C new file mode 100644 index 000000000..5bb285eb5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp15.C @@ -0,0 +1,21 @@ +struct Dense { + static const unsigned int dim = 1; +}; + +template <template <typename> class View, + typename Block> +void operator+(float, View<Block> const&); + +template <typename Block, + unsigned int Dim = Block::dim> +struct Lvalue_proxy { + operator float() const; +}; + +void +test_1d (void) +{ + Lvalue_proxy<Dense> p; + float b; + b + p; +} diff --git a/gcc/testsuite/g++.dg/template/ttp16.C b/gcc/testsuite/g++.dg/template/ttp16.C new file mode 100644 index 000000000..c556c7d98 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp16.C @@ -0,0 +1,7 @@ +template <template <typename> class C> +void f() {} + +template <typename T, typename U = int> +struct S {}; + +template void f<S>(); // { dg-error "match" } diff --git a/gcc/testsuite/g++.dg/template/ttp17.C b/gcc/testsuite/g++.dg/template/ttp17.C new file mode 100644 index 000000000..f1ddeb12e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp17.C @@ -0,0 +1,7 @@ +template <template <typename> class C> +void f(C<double>) {} + +template <typename T, typename U = int> +struct S {}; + +template void f(S<double>); // { dg-error "match" } diff --git a/gcc/testsuite/g++.dg/template/ttp18.C b/gcc/testsuite/g++.dg/template/ttp18.C new file mode 100644 index 000000000..095c07fb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp18.C @@ -0,0 +1,10 @@ +template <template <typename> class T> +void f(T<int>) {} + +template <typename T> +union U {}; + +void g() { + f(U<int>()); +} + diff --git a/gcc/testsuite/g++.dg/template/ttp19.C b/gcc/testsuite/g++.dg/template/ttp19.C new file mode 100644 index 000000000..12a37c9cd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp19.C @@ -0,0 +1,7 @@ +// PR c++/27689 + +void f (...); +template <template <typename> class F, typename T> void f (F<T>); +template <typename> struct foo { struct bar {}; }; +void g (foo<int>::bar x) { f(x); } + diff --git a/gcc/testsuite/g++.dg/template/ttp2.C b/gcc/testsuite/g++.dg/template/ttp2.C new file mode 100644 index 000000000..45d9abddf --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp2.C @@ -0,0 +1,17 @@ +// Copyright (C) 2001 Free Software Foundation +// Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> +// { dg-do compile } + +template <class U> struct Alloc {}; + +template <class T, class U = Alloc<T> > struct Vector {}; + +template <template <class T, class U = Alloc<T> > class TT> +struct C { + TT<int> tt; +}; + +int main() +{ + C<Vector> c; +} diff --git a/gcc/testsuite/g++.dg/template/ttp20.C b/gcc/testsuite/g++.dg/template/ttp20.C new file mode 100644 index 000000000..0d1784c9f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp20.C @@ -0,0 +1,11 @@ +// PR c++/27424 +// Bug: failing to substitute the 'int' into C + +template<typename T> struct A +{ + template<template<T> class> struct B {}; + template<T> struct C; + B<C> b; +}; + +A<int> a; diff --git a/gcc/testsuite/g++.dg/template/ttp21.C b/gcc/testsuite/g++.dg/template/ttp21.C new file mode 100644 index 000000000..f0bda99d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp21.C @@ -0,0 +1,5 @@ +// PR c++/28853 +// { dg-do compile } + +template<template<int> class A> +int A<0>::i; // { dg-error "template template parameter" } diff --git a/gcc/testsuite/g++.dg/template/ttp22.C b/gcc/testsuite/g++.dg/template/ttp22.C new file mode 100644 index 000000000..08eaa3042 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp22.C @@ -0,0 +1,8 @@ +// PR c++/28860 +// { dg-do compile } + +template<template<int> class A> +class A<0>; // { dg-error "shadows template template parameter" } + +template<template<int> class B> +class B<0> {}; // { dg-error "shadows template template parameter" } diff --git a/gcc/testsuite/g++.dg/template/ttp23.C b/gcc/testsuite/g++.dg/template/ttp23.C new file mode 100644 index 000000000..1210f042f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp23.C @@ -0,0 +1,17 @@ +// PR c++/29236 + +template <typename T> struct A {}; + +template <template <typename> class P> +struct B { + template <template <typename> class Q> + friend bool foo (const B<Q>& a); +}; + +template <template <typename> class Q> +bool foo (const B<Q>& a); + +void bar () { + B<A> a; + foo (a); +} diff --git a/gcc/testsuite/g++.dg/template/ttp24.C b/gcc/testsuite/g++.dg/template/ttp24.C new file mode 100644 index 000000000..2b8e28515 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp24.C @@ -0,0 +1,6 @@ +// PR c++/30897 + +template<template <typename T, typename = T > class U> struct A +{ + template<int> U<int> foo(); +}; diff --git a/gcc/testsuite/g++.dg/template/ttp25.C b/gcc/testsuite/g++.dg/template/ttp25.C new file mode 100644 index 000000000..861d187d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp25.C @@ -0,0 +1,29 @@ +// { dg-do compile } +template<typename T, template<T> class C> +void f1(T, C<5>); // { dg-message "note" } + +template<typename T, template<T> class C> +void f2(C<5>, T); + +template<typename T, template<T> class C> +void f3(C<5>, T); // { dg-message "note" } + +template<typename T> struct metafun { typedef T type; }; + +template<> struct metafun<short> { typedef int type; }; + +template<typename T, template<typename metafun<T>::type> class C> +void f4(T, C<5>); // { dg-message "note" } + +template<int N> struct X {}; +void g() { + f1(5l, X<5>()); // { dg-error "no matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 20 } + f2(X<5>(), 5); + f3(X<5>(), 5l); // { dg-error "no matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 23 } + f4(5, X<5>()); + f4(5l, X<5>()); // { dg-error "no matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 26 } + f4((short)5, X<5>()); +} diff --git a/gcc/testsuite/g++.dg/template/ttp26.C b/gcc/testsuite/g++.dg/template/ttp26.C new file mode 100644 index 000000000..6ba5cb28a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp26.C @@ -0,0 +1,5 @@ +// PR c++/34052 +template<typename T = int, typename U> class C; // { dg-error "no default argument" } + +template<template<typename T = int, typename U> class C> struct X; // { dg-error "no default argument" } + diff --git a/gcc/testsuite/g++.dg/template/ttp27.C b/gcc/testsuite/g++.dg/template/ttp27.C new file mode 100644 index 000000000..f69369085 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp27.C @@ -0,0 +1,6 @@ +// PR c++/35678 + +template<typename T, T> struct A; +template<typename> struct B; +template<template<typename T, T> class U> struct B<U<char, 'h'> > {}; +B<A<char,'h'> > x; diff --git a/gcc/testsuite/g++.dg/template/ttp3.C b/gcc/testsuite/g++.dg/template/ttp3.C new file mode 100644 index 000000000..a7f231a7f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp3.C @@ -0,0 +1,26 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 5213. We failed to spot that class List was a template, rather +// than a non-template or specialization + + +template <class T> class vector { }; + +class OUTER { + public: + template <class T> + class List { }; + + vector<class List> data; // { dg-error "invalid|required|ISO C" "" } +}; + +template <class T> +class List { }; + +// This next line should just do a lookup of 'class List', and then +// get a type/value mismatch. Instead we try and push 'class List' +// into the global namespace and get a redeclaration error. +vector<class List > data; // { dg-error "invalid|required|declaration" "" } diff --git a/gcc/testsuite/g++.dg/template/ttp4.C b/gcc/testsuite/g++.dg/template/ttp4.C new file mode 100644 index 000000000..4dff70103 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp4.C @@ -0,0 +1,11 @@ +// { dg-do compile } +// Origin: Ewgenij Gawrilow <gawrilow@math.tu-berlin.de> + +// PR c++/6723 +// ICE when default template argument contains instantiation of +// template template parameter. + +template <typename A, typename B, + template <typename,typename> class Predicate, + bool _matches=Predicate<A,B>::answer> +struct helper { }; diff --git a/gcc/testsuite/g++.dg/template/ttp5.C b/gcc/testsuite/g++.dg/template/ttp5.C new file mode 100644 index 000000000..ee9d1ff7c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp5.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +// Origin: sneechy@hotmail.com + +// PR c++/8772: Incorrect diagnostics for template template parameter +// mismatch + +template <int> struct A { + template <int> struct B { + enum { v = 1 }; + }; +}; + +template <template <int> class F> struct C { + enum { v = F<1>::v || 2 }; +}; + +template <int n> struct D { + enum { v = C<A<n>::B>::v }; // { dg-error "mismatch|class template" } +}; diff --git a/gcc/testsuite/g++.dg/template/ttp6.C b/gcc/testsuite/g++.dg/template/ttp6.C new file mode 100644 index 000000000..a4c6ab059 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp6.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Origin: Eelis van der Weegen <gccbugs@contacts.eelis.net> + +// PR c++/10552: Member class template as template template argument +// substitution issue. + +template <template <typename> class A, typename> +struct B +{ + typedef typename A<int>::t t; +}; + +template <typename D> +struct E +{ + template <typename> struct F { typedef int t; }; + typedef typename B<F, D>::t t; +}; + +typedef E<int>::t t; diff --git a/gcc/testsuite/g++.dg/template/ttp7.C b/gcc/testsuite/g++.dg/template/ttp7.C new file mode 100644 index 000000000..0bcaa8f72 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp7.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// Contributed by Andrew Pinski <pinskia at gcc dot gnu dot org> +// PR c++/13810: ICE while parsing invalid default argument for a +// template template parameter. + +struct X; +template<int> struct A {}; + +template<template<int> class = X > struct B1 {}; // { dg-error "as a default value" } +template<template<int> class = A<0> > struct B2 {}; // { dg-error "as a default value" } + +template <typename T> +struct S { + template <template <typename> class = S> struct I1 {}; // { dg-error "as a default value" } + template <template <typename> class = ::S> struct I2 {}; +}; diff --git a/gcc/testsuite/g++.dg/template/ttp8.C b/gcc/testsuite/g++.dg/template/ttp8.C new file mode 100644 index 000000000..99f99b965 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp8.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// Contributed by: Niall Douglas <s_gccbugzilla at netprod dot com> +// PR c++/14284: Failure to select specialization + +template<typename> struct S; +template<template<class> class> struct I {}; + +template<class, int> struct Match; + +template<template<class> class C> +struct Match<I<C>, 0> {}; + +template<template<class> class C, int i> +struct Match<I<C>, i>; + +Match<I<S>, 0> v; diff --git a/gcc/testsuite/g++.dg/template/ttp9.C b/gcc/testsuite/g++.dg/template/ttp9.C new file mode 100644 index 000000000..060ab7788 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp9.C @@ -0,0 +1,28 @@ +// { dg-do compile } + +// Origin: David Abrahams <dave@boost-consulting.com> +// Wolfgang Bangerth <bangerth@ticam.utexas.edu> + +// PR c++/12170: Deducing template template parameter from nested +// class template. + +template <typename> struct W {}; + +template< template<typename> class F, typename T> +int foo(W< F<T> >); + + +template<typename T> +struct L { + static int const value = sizeof(foo(W<T>())); + typedef T type; +}; + + +template <typename> +struct Y { + template <typename> struct X { typedef int type; }; + typedef typename L<X<int> >::type type; +}; + +template struct Y<int>; diff --git a/gcc/testsuite/g++.dg/template/type1.C b/gcc/testsuite/g++.dg/template/type1.C new file mode 100644 index 000000000..b74d975ac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/type1.C @@ -0,0 +1,8 @@ +// Test for helpful error messages on invalid nested-name-specifiers. + +struct A { + template <class T> struct B { static int c; }; +}; + +int A::B::c; // { dg-error "parameters" } +int A::C::d; // { dg-error "declared" } diff --git a/gcc/testsuite/g++.dg/template/type2.C b/gcc/testsuite/g++.dg/template/type2.C new file mode 100644 index 000000000..509c4820d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/type2.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// Origin: Juan Carlos Arevalo-Baeza <jcab@JCABs-Rumblings.com> + +// PR c++/8442 +// Type template parameter incorrectly treated as template template +// parameter. + +template <typename T> struct A {}; + +template <typename T> struct B +{ + template <typename U> struct C {}; + template <typename U> A<C<U> > foo(U); +}; + +B<void> b; diff --git a/gcc/testsuite/g++.dg/template/typedef1.C b/gcc/testsuite/g++.dg/template/typedef1.C new file mode 100644 index 000000000..75b00e0fb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef1.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 9 Dec 2001 <nathan@nathan@codesourcery.com> + +// PR 72 + +template <typename T> struct A +{ + typedef T type; +}; + +template <typename T> struct B +{ + typedef int xxx; // { dg-error "" } + typedef T xxx; // { dg-error "" } + typedef typename A<T>::type xxx; // { dg-error "" } + typedef A<int>::type xxx; // { dg-error "" } +}; + +B<int> good; diff --git a/gcc/testsuite/g++.dg/template/typedef10.C b/gcc/testsuite/g++.dg/template/typedef10.C new file mode 100644 index 000000000..c2a2108f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef10.C @@ -0,0 +1,14 @@ +// PR c++/34573 + +template < class Gtr_> +void compute_gr() +{ + typedef int Less_chain; + struct utils { + utils(const Less_chain& lc) {}; + }; + utils U(1); +} +int main(void){ + compute_gr<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/typedef11.C b/gcc/testsuite/g++.dg/template/typedef11.C new file mode 100644 index 000000000..c7c7c989f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef11.C @@ -0,0 +1,25 @@ +// Author: Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/26693 +// { dg-do compile } + + +class Alpha +{ + typedef int X; // { dg-error "'typedef int Alpha::X' is private" } +}; + +template<int> +class Beta +{ + typedef int Y; // { dg-error "'typedef int Beta<0>::Y' is private" } +}; + +template <int> +int +bar () +{ + Beta<0>::Y i = 0; + return Alpha::X (); +} + +int i = bar<0> (); // { dg-error "within this context" } diff --git a/gcc/testsuite/g++.dg/template/typedef12.C b/gcc/testsuite/g++.dg/template/typedef12.C new file mode 100644 index 000000000..30605044f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef12.C @@ -0,0 +1,23 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: Jason Merrill <jason@redhat.com>, PR c++/26693 +// { dg-do compile } + +class A +{ + protected: + typedef int mytype; +}; + +template <class T> class B; + +class C: public A +{ + template <class T> friend class B; +}; + +template <class T> class B +{ + C::mytype mem; +}; + +B<int> b; diff --git a/gcc/testsuite/g++.dg/template/typedef13.C b/gcc/testsuite/g++.dg/template/typedef13.C new file mode 100644 index 000000000..a22e1cb11 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef13.C @@ -0,0 +1,16 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/26693 +// { dg-do compile } + +class A +{ + typedef int mytype; // { dg-error "typedef int A::mytype' is private" } +}; + +template <class T> class B : public A +{ + mytype mem; // { dg-error "within this context" } +}; + +B<int> b; // { dg-message "instantiated from here" } + diff --git a/gcc/testsuite/g++.dg/template/typedef14.C b/gcc/testsuite/g++.dg/template/typedef14.C new file mode 100644 index 000000000..caa565a08 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef14.C @@ -0,0 +1,16 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/26693 +// { dg-do compile } + +template <class T> +struct A +{ + typedef int mytype; + + void + foo () + { + mytype v = ~static_cast<mytype> (0); + } +}; + diff --git a/gcc/testsuite/g++.dg/template/typedef15.C b/gcc/testsuite/g++.dg/template/typedef15.C new file mode 100644 index 000000000..e9e3d94ff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef15.C @@ -0,0 +1,25 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/26693 +// { dg-do compile } + +template<class T> struct C0; + +struct Foo { + typedef int TypedefedFoo; + typedef C0<Foo> TypedefedC0; +}; + +template<class T> +struct C0 +{ + typedef Foo TypedefedFoo; + typename T::TypedefedC0::TypedefedFoo m; +}; + +template<class U> +struct C1 +{ + typedef C0<Foo> TypedefedC0; +}; + +C0<C1<int> > c; diff --git a/gcc/testsuite/g++.dg/template/typedef16.C b/gcc/testsuite/g++.dg/template/typedef16.C new file mode 100644 index 000000000..29870605a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef16.C @@ -0,0 +1,27 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/26693 +// { dg-do compile } + +struct C0 +{ +}; + +template<class T, class U> +struct C1 +{ + typedef C0 TypedefedC0; + + template<class W> + void foo (TypedefedC0 *, W) + { + } + + template<class W> C1 (W w) + { + TypedefedC0 c; + foo (&c, w); + } + +}; +C0 c0; +C1<int, char> c1 (&c0); diff --git a/gcc/testsuite/g++.dg/template/typedef17.C b/gcc/testsuite/g++.dg/template/typedef17.C new file mode 100644 index 000000000..263e28886 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef17.C @@ -0,0 +1,32 @@ +// PR c++/37806 + +extern "C" int printf (const char *, ...); + +template <typename T> +struct S1 +{ + typedef void (function_type)(int) const; +}; + + +struct S2: public S1<int> +{ + virtual function_type f = 0; +}; + +struct S3: public S2 +{ + void + f (int i) const + { + printf ("Hello world: %d\n", i); + } +}; + + +int +main() +{ + S3 s; + s.f(5); +} diff --git a/gcc/testsuite/g++.dg/template/typedef18.C b/gcc/testsuite/g++.dg/template/typedef18.C new file mode 100644 index 000000000..8ea3c736a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef18.C @@ -0,0 +1,24 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/40007 +// { dg-do compile } + +template<typename T> +struct x +{ + protected: + typedef int type; +}; + +template<typename T> +struct y : public x<T> +{ + typename x<T>::type z; +}; + +template<> +struct y<void> : public x<void> +{ + typedef x<void>::type z; +}; + +template class y<int>; diff --git a/gcc/testsuite/g++.dg/template/typedef19.C b/gcc/testsuite/g++.dg/template/typedef19.C new file mode 100644 index 000000000..2fac20ea0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef19.C @@ -0,0 +1,21 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/40007 +// { dg-do compile } + +class A +{ + typedef int mytype; // { dg-error "'typedef int A::mytype' is private" } +}; + +template <class T> +class B : public A +{ +}; + +template<class T> +class B<T*> : public A +{ + mytype mem; // { dg-error "within this context" } +}; + +B<int*> b; diff --git a/gcc/testsuite/g++.dg/template/typedef2.C b/gcc/testsuite/g++.dg/template/typedef2.C new file mode 100644 index 000000000..cfe0f3f75 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef2.C @@ -0,0 +1,4 @@ +// PR c++/18155 + +template<int> typedef struct A; // { dg-warning "'typedef' was ignored" } + // { dg-error "" "" { target *-*-* } 3 } diff --git a/gcc/testsuite/g++.dg/template/typedef20.C b/gcc/testsuite/g++.dg/template/typedef20.C new file mode 100644 index 000000000..c768ce0a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef20.C @@ -0,0 +1,27 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/40007 +// { dg-do compile } + +class x +{ + typedef int privtype; // { dg-error "is private" } + +protected: + typedef int type; +}; + +template<typename T> +struct y : public x +{ + typename x::type z; +}; + +template<typename T> +struct y<T*> : public x +{ + typedef x::type good; + typedef x::privtype bad; // { dg-error "within this context" } +}; + +template class y<int>; +template class y<int*>; diff --git a/gcc/testsuite/g++.dg/template/typedef21.C b/gcc/testsuite/g++.dg/template/typedef21.C new file mode 100644 index 000000000..3185331be --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef21.C @@ -0,0 +1,11 @@ +// PR c++/37037 + +typedef void F(void); +template <typename T> struct S +{ + static F f; +}; +template class S<int>; +template <class T> void S<T>::f(void) +{} + diff --git a/gcc/testsuite/g++.dg/template/typedef22.C b/gcc/testsuite/g++.dg/template/typedef22.C new file mode 100644 index 000000000..e3ecfcb36 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef22.C @@ -0,0 +1,18 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/14777 +// { dg-do compile } + +template <typename T> +struct B +{ +protected: + typedef int M; // { dg-error "protected" } +}; + +template <typename T> +struct A : B<T> { + typedef typename B<char>::M N; // { dg-error "context" } + A (int = N ()); +}; + +A<int> a = A<int> (); diff --git a/gcc/testsuite/g++.dg/template/typedef23.C b/gcc/testsuite/g++.dg/template/typedef23.C new file mode 100644 index 000000000..e70355037 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef23.C @@ -0,0 +1,25 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/42069 +// { dg-do compile } + +struct A +{ + static const int N = 0; +}; + +template<int> struct B {}; + +template<typename T, int> +struct C +{ + typedef T U; + B<U::N> b; +}; + +template<typename T> +struct C<T*, 0> +{ + B<T::N> b; +}; + +C<A*, 0> c; diff --git a/gcc/testsuite/g++.dg/template/typedef24.C b/gcc/testsuite/g++.dg/template/typedef24.C new file mode 100644 index 000000000..ddcae1d61 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef24.C @@ -0,0 +1,33 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/42225 +// { dg-do compile } + +template<class T> +struct A +{ + typedef T I; +}; + +template<class T, int> +struct B +{ + typedef T TT; + typedef typename TT::I TT_I; + typedef A<TT_I> TA; +}; + +template<class T> +void +foo() +{ + typedef T TT; + typedef typename TT::I TT_I; + typedef A<TT_I> TA; +} + +int +main() +{ + foo<A<int> >(); +} + diff --git a/gcc/testsuite/g++.dg/template/typedef25.C b/gcc/testsuite/g++.dg/template/typedef25.C new file mode 100644 index 000000000..4f5868f12 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef25.C @@ -0,0 +1,43 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/42225 +// { dg-options "-std=c++0x" } +// { dg-do compile } + +template<class T> +struct A +{ + typedef T I; + static const char *i; +}; + +template<class T, int> +struct B +{ + typedef T TT; + typedef decltype(TT::i) TT_I0; + typedef decltype(&TT::i) TT_I1; + typedef decltype(*TT::i) TT_I2; + typedef A<TT_I0> TA0; + typedef A<TT_I1> TA1; + typedef A<TT_I2> TA2; +}; + +template<class T> +void +foo() +{ + typedef T TT; + typedef decltype(TT::i) TT_I0; + typedef decltype(&TT::i) TT_I1; + typedef decltype(*TT::i) TT_I2; + typedef A<TT_I0> TA0; + typedef A<TT_I1> TA1; + typedef A<TT_I2> TA2; +} + +int +main() +{ + foo<A<int> >(); +} + diff --git a/gcc/testsuite/g++.dg/template/typedef26.C b/gcc/testsuite/g++.dg/template/typedef26.C new file mode 100644 index 000000000..7f4bc6b5c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef26.C @@ -0,0 +1,40 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/42225 +// { dg-do compile } + +struct A +{ + typedef int TI; +}; + +template<class T0> +struct S0 +{ + int i; +}; + +template<class _T, int> +struct S1 +{ + typedef _T T; + typedef typename T::TI TTI; + typedef S0<TTI> TT0; + typedef S0<typename T::TI> TT1; +}; + +template<class T> +void +foo(const T&) +{ + typedef typename T::TI TTI; + typedef S0<TTI> TT1; + typedef S0<typename T::TI> TT2; +} + +int +main() +{ + A a; + foo (a); +} + diff --git a/gcc/testsuite/g++.dg/template/typedef27.C b/gcc/testsuite/g++.dg/template/typedef27.C new file mode 100644 index 000000000..e50f17ccd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef27.C @@ -0,0 +1,55 @@ +// Origin: PR c++/42713 +// { dg-do compile } + +template<class T> +struct S +{ +}; + +template<class T> +struct S0 +{ + typedef T TT; +}; + +template<class U, class V> +struct super_struct : S0<V> +{ + typedef S0<V> super; +}; + +template<class U, class V, class W> +struct S1 : super_struct<U, V> +{ + typedef super_struct<U, V> super; + typedef typename super::super Super2; + typedef typename Super2::TT Super2TT; + void + foo() + { + S<Super2TT> s1; + } +}; + +template<class U, class V> +struct S2 : super_struct<U, V> +{ + typedef super_struct<U, V> super; + typedef typename super::super Super2; + typedef typename Super2::TT Super2TT; + void + foo() + { + S<Super2TT> s1; + } +}; + +int +main() +{ + S1<int, S<int>, int> s1; + s1.foo(); + S2<int, S<int> > s2; + s2.foo(); +} + diff --git a/gcc/testsuite/g++.dg/template/typedef28.C b/gcc/testsuite/g++.dg/template/typedef28.C new file mode 100644 index 000000000..a0bad1bb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef28.C @@ -0,0 +1,28 @@ +// Origin: PR c++/42820 +// { dg-do compile } + + +template <class T> struct vector{}; +struct Traits{struct Primitive{struct Id{};};}; + +template <class Tree, class Polyhedron> struct Tree_vs_naive +{ + typedef typename Tree::Primitive Primitive; + + void f() const + { + typedef vector<typename Primitive::Id> Id_vector; + } +}; + +template <class Tree> void test_hint_strategies() +{ + vector<typename Tree::Primitive::Id> v; +} + +int main(void) +{ + test_hint_strategies<Traits>(); +} + + diff --git a/gcc/testsuite/g++.dg/template/typedef29.C b/gcc/testsuite/g++.dg/template/typedef29.C new file mode 100644 index 000000000..bb3b81e35 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef29.C @@ -0,0 +1,25 @@ +// Origin: PR c++/42820 +// { dg-do compile } + +template <class T> struct vector{}; +template<class T>struct Traits{struct Primitive{struct Id{};};}; + +template <template<class T> class Tree, class Polyhedron> struct Tree_vs_naive +{ + typedef typename Tree<int>::Primitive Primitive; + + void f() const + { + typedef vector<typename Primitive::Id> Id_vector; + } +}; + +template <template<class T> class Tree> void test_hint_strategies() +{ + vector<typename Tree<int>::Primitive::Id> v; +} + +int main(void) +{ + test_hint_strategies<Traits>(); +} diff --git a/gcc/testsuite/g++.dg/template/typedef3.C b/gcc/testsuite/g++.dg/template/typedef3.C new file mode 100644 index 000000000..481f451d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef3.C @@ -0,0 +1,7 @@ +// PR c++/19397 +// { dg-do compile } + +template<typename> struct A +{ + typedef int ::template; // { dg-error "template" } +}; diff --git a/gcc/testsuite/g++.dg/template/typedef30.C b/gcc/testsuite/g++.dg/template/typedef30.C new file mode 100644 index 000000000..2f9362a1e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef30.C @@ -0,0 +1,20 @@ +// Origin: PR c++/43206 +// { dg-do compile } + +template<class A> struct NumericTraits{ typedef A TInputImage;}; +template<class B> class CovariantVector{}; +template<class C> struct Image{ typedef C PixelType;}; +template<class H, class E, class D> +class F { + typedef H G; + typedef + typename NumericTraits<typename G::PixelType>::RealType + InputRealType; +}; + +template<typename TInputImage, + typename TOutputImage=Image<CovariantVector<typename NumericTraits<typename TInputImage::PixelType>::TInputImage> > > +class XXX{}; + +XXX<Image<float> > x; + diff --git a/gcc/testsuite/g++.dg/template/typedef31.C b/gcc/testsuite/g++.dg/template/typedef31.C new file mode 100644 index 000000000..7d66e3f5b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef31.C @@ -0,0 +1,21 @@ +// Origin: PR c++/43558 +// { dg-do compile } + +class Compressible; +template <class T, class EngineTag> class Engine; +template <class T> +class Engine<T, Compressible> +{ + public: + typedef T Element_t; + //Element_t read(int); + T read(int); +}; + +template <class T> +T Engine<T, Compressible>::read(int) +{ +} + +Engine<int, Compressible> x; + diff --git a/gcc/testsuite/g++.dg/template/typedef32.C b/gcc/testsuite/g++.dg/template/typedef32.C new file mode 100644 index 000000000..b32e66c3f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef32.C @@ -0,0 +1,46 @@ +// Origin: PR c++/43704 +// { dg-do compile } + +template<typename T2, typename T3> +struct if_ +{ + typedef T2 type; +}; + +template<class I1> +struct iterator_restrict_traits +{ + struct iterator_category {}; +}; + +template<class T> +struct matrix +{ + struct ci {struct ic {};}; + class i {}; +}; + +template<class M, class TRI> +struct triangular_adaptor +{ + typedef typename if_<typename M::ci,typename M::i>::type ty1; + class iterator2 : iterator_restrict_traits<typename ty1::ic>::iterator_category + { + }; +}; + +template<class M> +struct banded_adaptor +{ + typedef typename if_<typename M::ci,typename M::i>::type ty1; + class iterator1 : iterator_restrict_traits<typename ty1::ic>::iterator_category + { + }; +}; + +template<class T> +struct singular_decomposition +{ + banded_adaptor<matrix<double> >::iterator1 it1; +}; + diff --git a/gcc/testsuite/g++.dg/template/typedef33.C b/gcc/testsuite/g++.dg/template/typedef33.C new file mode 100644 index 000000000..1d2117b3a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef33.C @@ -0,0 +1,21 @@ +// Origin PR c++/43800 +// { dg-do compile } + +template<class T, class U=T> +struct V +{ + typedef T t_type; +}; + +template<class T> +class J +{ + typedef typename V<T>::t_type t_type; + const t_type& f(); // #0: +private: + t_type b; +}; + +template<class T> +const typename V<T>::t_type& J<T>::f() {return b;} // #1 + diff --git a/gcc/testsuite/g++.dg/template/typedef34.C b/gcc/testsuite/g++.dg/template/typedef34.C new file mode 100644 index 000000000..a82e155e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef34.C @@ -0,0 +1,37 @@ +// Origin PR c++/45200 +// { dg-do compile } + +template<typename T> +struct remove_reference +{ + typedef T type; +}; + +template<typename TestType> +struct forward_as_lref +{ +}; + +template<typename Seq, typename N> +struct apply1 +{ + typedef typename remove_reference<Seq>::type seq; + typedef forward_as_lref<typename seq::seq_type> type; //#0 +}; + +template<typename Seq> +struct apply +{ + typedef forward_as_lref<typename remove_reference<Seq>::type::seq_type> type; //#1 +}; + +struct reverse_view +{ + typedef int seq_type; +}; + +int +main() +{ + apply<reverse_view >::type a2; +} diff --git a/gcc/testsuite/g++.dg/template/typedef35.C b/gcc/testsuite/g++.dg/template/typedef35.C new file mode 100644 index 000000000..2dddf0966 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef35.C @@ -0,0 +1,41 @@ +// Origin c++/45558 +// { dg-do compile } + +template <typename S, typename T> +struct C +{ + template <typename U> + struct B + { + template <typename W> + struct E + { + explicit E(const W &x) : w(x) {} + const W &w; + }; + }; +}; + +struct F; +template <typename X> +struct D +{ + D() {} +}; + +const D<F> g; +template <typename S, typename T> +struct A +{ + template <typename U> + struct B : C<S, T>::template B<U> + { + typedef typename C<S, T>::template B<U> V; + static const D<typename V::template E<D<F> > > a; + }; +}; + +template <typename S, typename T> +template <typename U> +const D<typename C<S, T>::template B<U>::template E<D<F> > > +A<S, T>::B<U>::a = typename C<S, T>::template B<U>::template E<D<F> >(g); diff --git a/gcc/testsuite/g++.dg/template/typedef36.C b/gcc/testsuite/g++.dg/template/typedef36.C new file mode 100644 index 000000000..318deef92 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef36.C @@ -0,0 +1,23 @@ +// Origin: PR c++/45606 +// { dg-do compile } + +template<class T, class U = int> +struct S0 +{ + typedef int const_iterator; +}; + +template<class T> +struct Test +{ + typedef S0<T> SAlias; + typedef typename SAlias::const_iterator const_iterator; + const_iterator begin (); +}; + +template<class T> +typename S0<T>::const_iterator +Test<T>::begin() +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/typedef37.C b/gcc/testsuite/g++.dg/template/typedef37.C new file mode 100644 index 000000000..eefa38316 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef37.C @@ -0,0 +1,58 @@ +// Origin: PR c++/47398 +// { dg-do compile } + +template<int> +struct A +{ + typedef int INT; +}; + +template<int I> +struct transform +{ + static int bar(); +}; + +template<class T, int a, class U, int b> +struct B +{ + typedef typename A<a>::INT TINT; + void baz(); +}; + +template<class T, int a, class U> +struct B<T, a, U, 1> +{ + typedef typename A<a>::INT TINT; + void foo(); +}; + +template<class T, int a, class U, int b> +void +B<T, a, U, b>::baz() +{ + int c = transform<sizeof(TINT)>::bar();//#0 +} + +template<class T, int a, class U> +void +B<T, a, U, 1>::foo() +{ + int c = transform<sizeof(TINT)>::bar();//#1 +} + +int +main() +{ + B<int, 2, char, 1> i; + i.foo(); + // While instantiating + // + // template<class T, int a, class U> void B<T, a, U, 1>::foo() + // + // lookup_template_class resolves transform<sizeof(TINT)> in #1 to + // the wrong one; it picks up the one in #0 instead. This is because + // to compare the two A<a> comp_template_args uses cp_tree_equal + // that fails to consider the number of siblings of parm 'a'. +return 0; +} diff --git a/gcc/testsuite/g++.dg/template/typedef38.C b/gcc/testsuite/g++.dg/template/typedef38.C new file mode 100644 index 000000000..445db17bd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef38.C @@ -0,0 +1,27 @@ +// Origin: PR c++/46394 +// { dg-options "-std=c++0x" } +// { dg-do compile } + +template<class T> +struct S0 +{ + typedef T type; +}; + +template<class... X> +struct S1 +{ + typedef int I; +}; + +struct A +{ + template<class...U, class V=typename S1<typename S0<U>::type...>::I> + A(U...u); +}; + +int +main() +{ + A a(1, 2); +} diff --git a/gcc/testsuite/g++.dg/template/typedef4.C b/gcc/testsuite/g++.dg/template/typedef4.C new file mode 100644 index 000000000..60fad0688 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef4.C @@ -0,0 +1,10 @@ +// PR c++/27572 +// { dg-do compile } + +template<typedef> void foo(); // { dg-error "no type|typedef declaration|template" } + +void bar() +{ + foo<int>(); // { dg-error "matching" } + // { dg-message "candidate" "candidate note" { target *-*-* } 8 } +} diff --git a/gcc/testsuite/g++.dg/template/typedef5.C b/gcc/testsuite/g++.dg/template/typedef5.C new file mode 100644 index 000000000..04b8eac3b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef5.C @@ -0,0 +1,7 @@ +// PR c++/27572 +// { dg-do compile } + +template<typedef,int> struct A1; // { dg-error "no type|typedef declaration|default argument" } +template<typedef x,int> struct A2; // { dg-error "type|typedef declaration|default argument" } +template<typedef x[],int> struct A3; // { dg-error "no type|typedef declaration|expected" } +template<typedef int x, int> struct A4; // { dg-error "typedef declaration|default argument" } diff --git a/gcc/testsuite/g++.dg/template/typedef6.C b/gcc/testsuite/g++.dg/template/typedef6.C new file mode 100644 index 000000000..c95945966 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef6.C @@ -0,0 +1,8 @@ +//PR c++/28303 + +template<typename T> struct A +{ + typedef struct typename T::X X; // { dg-error "expected identifier|two or more" } +}; + +template<typename T> A<T>::X::X() {} // { dg-error "not a type|forbids declaration|invalid use of" } diff --git a/gcc/testsuite/g++.dg/template/typedef7.C b/gcc/testsuite/g++.dg/template/typedef7.C new file mode 100644 index 000000000..2d39c90b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef7.C @@ -0,0 +1,15 @@ +// An intermediate version of the fix for c++/19407 broke this example. + +struct A +{ + typedef struct { int i; } S; +}; + +template <class T> +struct B: public A +{ + template <class U> + static S f (); +}; + +template struct B<int>; diff --git a/gcc/testsuite/g++.dg/template/typedef8.C b/gcc/testsuite/g++.dg/template/typedef8.C new file mode 100644 index 000000000..f13260688 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef8.C @@ -0,0 +1,21 @@ +// PR c++/34206 + +template<class _T1, class _T2> struct pair { }; +template <class T0, class T1> struct tuple { + template <class U1, class U2> + tuple& operator=(const pair<U1, U2>& k) { } +}; +template<class T1, class T2> inline tuple<T1&, T2&> tie(T1& t1, T2& t2) { } + +template <class T> struct A +{ + typedef T type; + pair<type, type> f(); +}; + +void g(A<int> a) +{ + typedef A<int>::type type; + type begin1, end1; + tie(begin1, end1) = a.f(); +} diff --git a/gcc/testsuite/g++.dg/template/typedef9.C b/gcc/testsuite/g++.dg/template/typedef9.C new file mode 100644 index 000000000..8d2ed3675 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef9.C @@ -0,0 +1,25 @@ +// PR c++/34846 + +template<typename, typename> struct __are_same { enum { __value = 0 }; }; +template<typename _Tp> struct __are_same<_Tp, _Tp> { enum { __value = 1 }; }; +template<typename, bool> struct __enable_if { }; +template<typename _Tp> struct __enable_if<_Tp, true> { typedef _Tp __type; }; +template<typename _Iterator, typename _Container> class __normal_iterator { +public: + __normal_iterator(); + template<typename _Iter> + __normal_iterator( + const __normal_iterator<_Iter, typename __enable_if<_Container, +(__are_same<_Iter, typename _Container::pointer>::__value) >::__type>& __i) + { } +}; +template<typename _Tp> class vector { +public: + typedef _Tp* pointer; + typedef __normal_iterator<int, vector<_Tp> > iterator; +}; +void test() { + typedef int t; + vector<t*>::iterator x; + vector<t*>::iterator y = x; +} diff --git a/gcc/testsuite/g++.dg/template/typeid-template-argument.C b/gcc/testsuite/g++.dg/template/typeid-template-argument.C new file mode 100644 index 000000000..38dbfd3f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typeid-template-argument.C @@ -0,0 +1,7 @@ +// This used to ICE (PR28420) + +// { dg-do compile } + +template<int> struct A; + +int i = sizeof(A<typeid>); // { dg-error "operator cannot appear in a constant-expression|template argument 1 is invalid" } diff --git a/gcc/testsuite/g++.dg/template/typename1.C b/gcc/testsuite/g++.dg/template/typename1.C new file mode 100644 index 000000000..86658c5f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename1.C @@ -0,0 +1,9 @@ +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> +// { dg-do compile } + +template <class T> +class B : virtual T::A +{ + typedef int INT; + INT i; +}; diff --git a/gcc/testsuite/g++.dg/template/typename10.C b/gcc/testsuite/g++.dg/template/typename10.C new file mode 100644 index 000000000..f6f9931df --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename10.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Copyright (C) 2006 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 25 Aug 2006 <nathan@codesourcery.com> + +// Origin: Tobias Schwinger <tschwinger@neoscientists.org> +// PR 27787. Too eager to resolve a typename + +template<typename X> +struct x +{ + template<typename Y> + struct y + { + typedef Y type; + }; +}; + +template<typename A> +struct a : x<A> +{ + template<typename B> + typename a::template y<B>::type f(B); +}; diff --git a/gcc/testsuite/g++.dg/template/typename11.C b/gcc/testsuite/g++.dg/template/typename11.C new file mode 100644 index 000000000..fb776105f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename11.C @@ -0,0 +1,11 @@ +// PR c++/28999 + +namespace N +{ + template<int> void foo(); +} + +template<int> struct A +{ + friend void typename N::foo<0>(); // { dg-error "type|expected" } +}; diff --git a/gcc/testsuite/g++.dg/template/typename12.C b/gcc/testsuite/g++.dg/template/typename12.C new file mode 100644 index 000000000..0bb78c7c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename12.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Copyright (C) 2007 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Jul 2007 <nathan@codesourcery.com> + +// Origin: sschunck@pdf.de +// PR 30818, failure to resolve typename typedef + +template < typename T > +class A +{ + typedef int type; + class B; +}; + +template < typename T > +class A<T>::B +{ + typedef typename A<T>::type type; + type f(); +}; + +template < typename T > +typename A<T>::B::type +A<T>::B::f() { return 0; } diff --git a/gcc/testsuite/g++.dg/template/typename13.C b/gcc/testsuite/g++.dg/template/typename13.C new file mode 100644 index 000000000..527b0d153 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename13.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Copyright (C) 2007 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Jul 2007 <nathan@codesourcery.com> + +template <typename T> struct A +{ + struct B; + typedef typename B::type type; +}; + +template <typename T> struct A<T>::B +{ + typedef typename A<T>::type type; + + type Foo (); +}; + +template <typename T> +typename A<T>::B::type +A<T>::B::Foo () +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/typename14.C b/gcc/testsuite/g++.dg/template/typename14.C new file mode 100644 index 000000000..7e73cb0f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename14.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Copyright (C) 2007 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Jul 2007 <nathan@codesourcery.com> + +template <typename T> struct A +{ + typedef const T X; + + struct B; +}; + +template <typename T> struct A<T>::B +{ + typedef volatile typename A<T>::X Y; + + T const volatile *Foo (); +}; + +template<typename T> +typename A<T>::B::Y *A<T>::B::Foo () +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/typename15.C b/gcc/testsuite/g++.dg/template/typename15.C new file mode 100644 index 000000000..fece885ea --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename15.C @@ -0,0 +1,12 @@ +// PR37314 ice-on-valid-code, from w.doeringer +template <typename T> +class Cdeque { + typedef T *pointer; + class iterator { + typedef typename Cdeque<T>::pointer pointer; + pointer operator->(); + }; +}; +template <typename T> T* Cdeque<T>::iterator::operator->() { } + + diff --git a/gcc/testsuite/g++.dg/template/typename16.C b/gcc/testsuite/g++.dg/template/typename16.C new file mode 100644 index 000000000..45da11162 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename16.C @@ -0,0 +1,25 @@ +// PR37314 rejects-valid, from w.doeringer +template <typename T> +struct A { + typedef __PTRDIFF_TYPE__ difference_type; + struct B { + typedef typename A<T>::difference_type difference_type; + difference_type operator-(B const&) const; + T t; + }; +}; +// + +template <typename T> +typename A<T>::B::difference_type A<T>::B::operator-(B const&) const { + return -1; +} + +// +int main() { + A<int>::B i; + ++i.t; + return 0; +} + + diff --git a/gcc/testsuite/g++.dg/template/typename17.C b/gcc/testsuite/g++.dg/template/typename17.C new file mode 100644 index 000000000..748b1f7ab --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename17.C @@ -0,0 +1,10 @@ +// { dg-do compile } + +// This should fail as A::foo<0> is not a typename at all. +struct A +{ + template<int> void foo(int i) + { + typename A::foo<0>(i1); // { dg-error "" } + } +}; diff --git a/gcc/testsuite/g++.dg/template/typename18.C b/gcc/testsuite/g++.dg/template/typename18.C new file mode 100644 index 000000000..4134ef6f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename18.C @@ -0,0 +1,14 @@ +// { dg-do compile } + +// These typename should work as they are types. +struct A +{ + typedef int a; + template <int> + struct f {}; + template<int> void foo(int i) + { + typename A::a(i1); + typename A::f<0>(i2); + } +}; diff --git a/gcc/testsuite/g++.dg/template/typename2.C b/gcc/testsuite/g++.dg/template/typename2.C new file mode 100644 index 000000000..b0e16d464 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename2.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "" } + +// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 21 Mar 2002 <nathan@codesourcery.com> + +// PR 5507. Overzealous implicit typename warning + +template<typename _CharT> +class __ctype_abstract_base +{ + typedef int mask; +}; + +template<typename _CharT> +class ctype : public __ctype_abstract_base<_CharT> +{ + typedef typename ctype::mask mask; +}; + +template<typename _CharT> +class ctype2 : public __ctype_abstract_base<_CharT> +{ + typedef mask mask; // { dg-error "does not name a type" "no type" } + // { dg-message "note" "note" { target *-*-* } 24 } +}; diff --git a/gcc/testsuite/g++.dg/template/typename3.C b/gcc/testsuite/g++.dg/template/typename3.C new file mode 100644 index 000000000..0ad9a2a0c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename3.C @@ -0,0 +1,7 @@ +// { dg-do compile } +// crash test - PR 7266 + +template <class A> +struct B { + typedef A::C::D E; // { dg-error "" } +}; diff --git a/gcc/testsuite/g++.dg/template/typename4.C b/gcc/testsuite/g++.dg/template/typename4.C new file mode 100644 index 000000000..18cdd1aba --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename4.C @@ -0,0 +1,3 @@ +struct B { template <typename U> struct C; }; +template <typename T> struct A { typedef typename T::C V; }; // { dg-error "not a type" } +void f () { A<B>::V p; } // { dg-message "instantiated" } diff --git a/gcc/testsuite/g++.dg/template/typename5.C b/gcc/testsuite/g++.dg/template/typename5.C new file mode 100644 index 000000000..2f72b5f86 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename5.C @@ -0,0 +1,19 @@ +// { dg-do compile } + +// Origin: ariels@compugen.co.il + +// PR c++/2513: typename handling when scope is dependent as +// described in DR108. + +template <bool flag> struct Select { + typedef int Result; +}; + +template <template<class> class Pred> struct FindType { + typedef typename Select<true>::Result Result; +}; + +template <int bits> struct Int { + template<typename T> struct RightSize {}; + typedef typename FindType<RightSize>::Result type; +}; diff --git a/gcc/testsuite/g++.dg/template/typename6.C b/gcc/testsuite/g++.dg/template/typename6.C new file mode 100644 index 000000000..937ea96aa --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename6.C @@ -0,0 +1,11 @@ +struct O { + template <typename T> + struct I { + I (int); + }; +}; + +template <typename T> +void f() { + typename ::O::I<int>(3); +} diff --git a/gcc/testsuite/g++.dg/template/typename7.C b/gcc/testsuite/g++.dg/template/typename7.C new file mode 100644 index 000000000..d9c8f2609 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename7.C @@ -0,0 +1,19 @@ +// PR c++/17501 + +template<int> struct A; + +template<> struct A<0> +{ + struct B + { + struct C + { + typedef int D; + }; + }; +}; + +template<int I> struct E +{ + typename A<I>::B::C::D i; +}; diff --git a/gcc/testsuite/g++.dg/template/typename8.C b/gcc/testsuite/g++.dg/template/typename8.C new file mode 100644 index 000000000..85f585d94 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename8.C @@ -0,0 +1,10 @@ +// PR c++/18738 + +namespace foo { + typedef int my_type; +} + +template<typename T> +struct A { + typename foo::my_type bar(); +}; diff --git a/gcc/testsuite/g++.dg/template/typename9.C b/gcc/testsuite/g++.dg/template/typename9.C new file mode 100644 index 000000000..5f6fb96bc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename9.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Dec 2004 <nathan@codesourcery.com> + +// PR 18981. ICE +// Origin: Andreas Schwab <schwab@suse.de> + +template <class T> +struct tree { + struct iterator; + struct sibling_iterator { + friend struct tree<T>::iterator; + }; +}; diff --git a/gcc/testsuite/g++.dg/template/unify1.C b/gcc/testsuite/g++.dg/template/unify1.C new file mode 100644 index 000000000..2f0a18cf4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify1.C @@ -0,0 +1,26 @@ +// Test non-type template argument folding. +// Origin: smacdonald@seimac.com + +// { dg-do compile } + +template < int I1, int I2 > +class unit +{ +public: + unit() {} + unit( const unit<I1,I2>& ) {} + + template< int Q1, int Q2 > + unit< I1 - Q1, I2 - Q2 > operator / ( const unit< Q1, Q2 >& rhs ) const { + return unit< I1 - Q1, I2 - Q2 >(); + } + +}; + +int main() +{ + const unit<1,0> u1; + const unit<2,0> u2; + + unit<-1,0> u3( u1 / u2 ); +} diff --git a/gcc/testsuite/g++.dg/template/unify10.C b/gcc/testsuite/g++.dg/template/unify10.C new file mode 100644 index 000000000..8dc434b75 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify10.C @@ -0,0 +1,60 @@ +// { dg-do compile } +// Origin: Wolfgang Bangerth <bangerth at ticam dot utexas dot edu> +// and Rene Fonseca <fonseca at mip dot sdu dot dk> +// PR c++/8271: Check cv-qualifiers while unifying pointer to member +// functions. + +struct MyClass { + void mMethod() throw() {} + void cMethod() const throw() {} + void vMethod() volatile throw() {} + void cvMethod() const volatile throw() {} +}; + +template<class CLASS> +void mFunction(void (CLASS::* method)()) {} // { dg-message "note" } + +template<class CLASS> +void cFunction(void (CLASS::* method)() const) {} // { dg-message "note" } + +template<class CLASS> +void vFunction(void (CLASS::* method)() volatile) {} // { dg-message "note" } + +template<class CLASS> +void cvFunction(void (CLASS::* method)() const volatile) {} // { dg-message "note" } + +int main() { + mFunction(&MyClass::mMethod); + mFunction(&MyClass::cMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 28 } + mFunction(&MyClass::vMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 30 } + mFunction(&MyClass::cvMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 32 } + + cFunction(&MyClass::mMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 35 } + cFunction(&MyClass::cMethod); + cFunction(&MyClass::vMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 38 } + cFunction(&MyClass::cvMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 40 } + + vFunction(&MyClass::mMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 43 } + vFunction(&MyClass::cMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 45 } + vFunction(&MyClass::vMethod); + vFunction(&MyClass::cvMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 48 } + + cvFunction(&MyClass::mMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 51 } + cvFunction(&MyClass::cMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 53 } + cvFunction(&MyClass::vMethod); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 55 } + cvFunction(&MyClass::cvMethod); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/unify11.C b/gcc/testsuite/g++.dg/template/unify11.C new file mode 100644 index 000000000..ed6b31c31 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify11.C @@ -0,0 +1,37 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin: PR c++/40684 +// { dg-options "-std=c++0x" } + +struct A +{ +}; + +template <typename S, typename T, typename U, typename S::v = &S::v::s> +typename S::A +foo (S c, T t, U u) // { dg-message "note" } +{ +} + +struct B +{ + struct C + { + template <typename U> + C (U t) + { + A a; + A b = foo (this, a, t); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 23 } + } + } c; + B () : c (A ()) + { + } +}; + +int +main () +{ + B f; +} + diff --git a/gcc/testsuite/g++.dg/template/unify2.C b/gcc/testsuite/g++.dg/template/unify2.C new file mode 100644 index 000000000..e5e6d1904 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify2.C @@ -0,0 +1,13 @@ +// { dg-do compile } + +template<int I> void f1 (char [][I+1]) {} +template<int I> void f2 (char [][I+0]) {} +template<int I> void f3 (char [][I]) {} +template<int I> void f4 (char [][I-0]) {} +template<int I> void f5 (char [][I-1]) {} + +template void f1 (char [][6]); // { dg-error "does not match" } +template void f2 (char [][6]); // { dg-error "does not match" } +template void f3 (char [][6]); +template void f4 (char [][6]); // { dg-error "does not match" } +template void f5 (char [][6]); // { dg-error "does not match" } diff --git a/gcc/testsuite/g++.dg/template/unify3.C b/gcc/testsuite/g++.dg/template/unify3.C new file mode 100644 index 000000000..190a0cb95 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify3.C @@ -0,0 +1,11 @@ +// Test unifying SCOPE_REF. +// Origin: Marc Duflot <m.duflot@ulg.ac.be> +// { dg-do compile } + +template <int n> class A {}; +template <int m> class R {}; + +template <int n> struct Trait { enum {m = n}; }; + +template <int n> R<Trait<n>::m> f(A<n>); +template <> R<1> f(A<1>) {return R<1>();} diff --git a/gcc/testsuite/g++.dg/template/unify4.C b/gcc/testsuite/g++.dg/template/unify4.C new file mode 100644 index 000000000..19d9f3a9f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify4.C @@ -0,0 +1,18 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 28 Jan 2003 <nathan@codesourcery.com> + +// PR 9437. We'd unify 'T *' with 'U C::*', which is obviously broken + +struct X +{ + template <typename T> + operator T* () const { return static_cast<T*> (0); } +} null; + +struct A { int i; }; + +static void f (int A::* pmi) { } + +int main () { f (null); } // { dg-error "cannot convert" "" } diff --git a/gcc/testsuite/g++.dg/template/unify5.C b/gcc/testsuite/g++.dg/template/unify5.C new file mode 100644 index 000000000..6928f1f84 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify5.C @@ -0,0 +1,10 @@ + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com> +// Origin:Matt Austern <austern@apple.com> + +// PR:c++/14007 + +template <typename T> struct X {}; // #1 +template <typename T> struct X<const T>; //#2 +template struct X<int&>; //#3 diff --git a/gcc/testsuite/g++.dg/template/unify6.C b/gcc/testsuite/g++.dg/template/unify6.C new file mode 100644 index 000000000..b12ecb29b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify6.C @@ -0,0 +1,23 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com> + +void Baz (); + +template <typename T> void Foo1 (T *); // #1 +template <typename T> void Foo1 (T const *a) {a (1);} // #2 + +template <typename T> T const *Foo2 (T *); + +template <typename T> void Foo3 (T *, T const * = 0); // { dg-message "note" } + +void Bar () +{ + Foo1 (&Baz); // #1 + + Foo2 (&Baz); + + Foo3 (&Baz); + + Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 21 } +} diff --git a/gcc/testsuite/g++.dg/template/unify7.C b/gcc/testsuite/g++.dg/template/unify7.C new file mode 100644 index 000000000..2bfa56303 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify7.C @@ -0,0 +1,15 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com> + +// PR c++/3518 +template <typename T> void Foo (const T &); +template <typename T> void Baz (const T (*)()); // { dg-message "note" } + +int &f (); + +int main() +{ + Foo (f); + Baz (f); // { dg-error "no matching function" "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 13 } +} diff --git a/gcc/testsuite/g++.dg/template/unify8.C b/gcc/testsuite/g++.dg/template/unify8.C new file mode 100644 index 000000000..9caf085f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify8.C @@ -0,0 +1,20 @@ +// { dg-do link } + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Jul 2005 <nathan@codesourcery.com> + +// Origin:Wolfgang Bangerth <bangerth@dealii.org> +// PR 21799: deduction of cvqualifiers on member functions was wrong + +template <class T> void f (T &, void (T::*)() ); +template <class T> void f (const T &, void (T::*)() const) {} + +struct X { + void g() const {} +}; + +const X *x; + +int main () { + f (*x, &X::g); +} diff --git a/gcc/testsuite/g++.dg/template/unify9.C b/gcc/testsuite/g++.dg/template/unify9.C new file mode 100644 index 000000000..40f6b9271 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify9.C @@ -0,0 +1,18 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Jul 2005 <nathan@codesourcery.com> + +// Origin:Wolfgang Bangerth <bangerth@dealii.org> +// PR 21799: deduction of cvqualifiers on member functions was wrong + +template <class T> void f (T &, void (T::*)() ); // { dg-message "note" } + +struct X { + void g() const {} +}; + +const X *x; + +int main () { + f (*x, &X::g); // { dg-error "no matching function" } + // { dg-message "candidate" "candidate note" { target *-*-* } 16 } +} diff --git a/gcc/testsuite/g++.dg/template/union1.C b/gcc/testsuite/g++.dg/template/union1.C new file mode 100644 index 000000000..9019c38a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/union1.C @@ -0,0 +1,29 @@ +// { dg-do run } + +extern "C" void abort (); + +void g (char c) +{ + if (c != 'a') + abort (); +} + +void h (int i) +{ + if (i != 3) + abort (); +} + +template <typename T> void f(T const &t) +{ + union { char c; T t_; }; + + c = 'a'; + g (c); + t_ = 3; + h (t_); +} + +int main () { + f (3); +} diff --git a/gcc/testsuite/g++.dg/template/union2.C b/gcc/testsuite/g++.dg/template/union2.C new file mode 100644 index 000000000..25f1e086f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/union2.C @@ -0,0 +1,12 @@ +/* PR c++/40557 */ +/* { dg-do compile } */ + +struct A +{ + typedef int X; +}; + +template<int> union B +{ + A::X x; +}; diff --git a/gcc/testsuite/g++.dg/template/using1.C b/gcc/testsuite/g++.dg/template/using1.C new file mode 100644 index 000000000..e4d4a004e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using1.C @@ -0,0 +1,42 @@ +// { dg-do run } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com> + +// PR 9447. Using decls in template classes. + +template <class T> +struct Foo { + int i; +}; + +struct Baz +{ + int j; +}; + +template <class T> +struct Bar : public Foo<T>, Baz { + using Foo<T>::i; + using Baz::j; + + int foo () { return i; } + int baz () { return j; } +}; + +int main() +{ + Bar<int> bar; + + bar.i = 1; + bar.j = 2; + + if (bar.foo() != 1) + return 1; + + if (bar.baz() != 2) + return 1; + + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/using10.C b/gcc/testsuite/g++.dg/template/using10.C new file mode 100644 index 000000000..8f0cbda2a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using10.C @@ -0,0 +1,11 @@ +// PR c++/22136 + +struct B { + void foo(); +}; + +template <typename T> class I : public B {}; + +template <typename T> class D : private I<T> { + I<T>::B::foo; +}; diff --git a/gcc/testsuite/g++.dg/template/using11.C b/gcc/testsuite/g++.dg/template/using11.C new file mode 100644 index 000000000..21cc5d2ef --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using11.C @@ -0,0 +1,8 @@ +struct X { + void f(); +}; + +template <typename T> +struct S : public T { + using X::f; +}; diff --git a/gcc/testsuite/g++.dg/template/using12.C b/gcc/testsuite/g++.dg/template/using12.C new file mode 100644 index 000000000..cebfab1ee --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using12.C @@ -0,0 +1,7 @@ +struct A { +}; + +template <typename T> +struct S : public A { + using A::operator(); // { dg-error "no member" } +}; diff --git a/gcc/testsuite/g++.dg/template/using13.C b/gcc/testsuite/g++.dg/template/using13.C new file mode 100644 index 000000000..3f86ede37 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using13.C @@ -0,0 +1,11 @@ +//PR c++/28051 + +template<int> struct A {}; + +template<int N> struct B : A<N> +{ + using A<N>::operator typename A<N>::X; // { dg-error "no type named" } +}; + +B<0> b; + diff --git a/gcc/testsuite/g++.dg/template/using14.C b/gcc/testsuite/g++.dg/template/using14.C new file mode 100644 index 000000000..ebb4e090a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using14.C @@ -0,0 +1,21 @@ +// PR c++/26102 + +template <class T> struct B1 { int i(); }; + +struct B2 { int i(); }; + +template <class T> struct C : public B1<T>, public B2 +{ + using B2::i; + void f() + { + i(); // should be accepted + i.i(); // { dg-error "member" } + } +}; + +int main() +{ + C<int> c; + c.f(); // { dg-message "instantiated" } +} diff --git a/gcc/testsuite/g++.dg/template/using15.C b/gcc/testsuite/g++.dg/template/using15.C new file mode 100644 index 000000000..b158ac09c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using15.C @@ -0,0 +1,25 @@ +// Reduced from the testcase for c++/29433 + +template <class T> +struct A: T +{ + void f(typename T::type); + using T::f; + void g() { f(1); } +}; + +template <class T> +struct B: T +{ typedef int type; }; + +struct C +{ + typedef double type; + void f(); +}; + +int main() +{ + A<B<A<C> > > a; + a.g(); +} diff --git a/gcc/testsuite/g++.dg/template/using2.C b/gcc/testsuite/g++.dg/template/using2.C new file mode 100644 index 000000000..5d21f575b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using2.C @@ -0,0 +1,30 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com> + +// PR 9447. Using decls in template classes. + +template <class T> +struct Foo { + int i; // { dg-error "Foo" } +}; + +struct Baz +{ + int i; // { dg-error "Baz" } +}; + +template <class T> +struct Bar : public Foo<T>, Baz { + using Foo<T>::i; + using Baz::i; + + int foo () { return i; } // { dg-error "request for member" } +}; + +void foo (Bar<int> &bar) +{ + bar.foo(); // { dg-message "instantiated" } +} + diff --git a/gcc/testsuite/g++.dg/template/using3.C b/gcc/testsuite/g++.dg/template/using3.C new file mode 100644 index 000000000..11f2899c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using3.C @@ -0,0 +1,42 @@ +// { dg-do run } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com> + +// PR 9447. Using decls in template classes. + +template <class T> +struct Foo { + int i (int) {return 1;} +}; + +struct Baz +{ + int k (int) {return 2;} +}; + +template <class T> +struct Bar : public Foo<T> , Baz { + using Foo<T>::i; + using Baz::k; + + int i (float) {return 3;} + int k (float) {return 3;} + + int foo() + { + if (i (1) != 1) + return 1; + if (k (1) != 2) + return 2; + + return 0; + } +}; + +int main() +{ + Bar<int> bar; + + return bar.foo(); +} diff --git a/gcc/testsuite/g++.dg/template/using4.C b/gcc/testsuite/g++.dg/template/using4.C new file mode 100644 index 000000000..8c46da464 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using4.C @@ -0,0 +1,39 @@ +// { dg-do run } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com> + +// PR 9447. Using decls in template classes. + +template <class T> +struct Foo { + int k (float) {return 1;} +}; + +struct Baz +{ + int k (int) {return 2;} +}; + +template <class T> +struct Bar : public Foo<T> , Baz { + using Foo<T>::k; + using Baz::k; + + int foo() + { + if (k (1.0f) != 1) + return 1; + if (k (1) != 2) + return 2; + + return 0; + } +}; + +int main() +{ + Bar<int> bar; + + return bar.foo(); +} diff --git a/gcc/testsuite/g++.dg/template/using5.C b/gcc/testsuite/g++.dg/template/using5.C new file mode 100644 index 000000000..096ddc0b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using5.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 31 Jul 2003 <nathan@codesourcery.com> + +// PR 9447. further test cases for dependent using decl + +template <typename T> struct Base; + +template <typename T> struct Derived : public Base<T> { + using Base<T>::i; + + Derived() { i; } + + int get_i() { return i.f(); } + +}; diff --git a/gcc/testsuite/g++.dg/template/using6.C b/gcc/testsuite/g++.dg/template/using6.C new file mode 100644 index 000000000..ee8d5be96 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using6.C @@ -0,0 +1,14 @@ +namespace foo { + template<typename T> + struct A {}; +} + +namespace bar { + template<typename T> + struct A {}; +} + +namespace foo { + using bar::A; // { dg-error "" } +} + diff --git a/gcc/testsuite/g++.dg/template/using7.C b/gcc/testsuite/g++.dg/template/using7.C new file mode 100644 index 000000000..390dfbaac --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using7.C @@ -0,0 +1,21 @@ +// { dg-do compile } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Aug 2003 <nathan@codesourcery.com> + +// PR 9447. Using decls in reopened template classes. + +template <typename> struct A { int i; }; + +template <typename T> struct B : public A<T> +{ + using A<T>::i; + int foo() const; +}; + +struct C {}; + +template <typename T> int B<T>::foo() const +{ + return i; +} diff --git a/gcc/testsuite/g++.dg/template/using8.C b/gcc/testsuite/g++.dg/template/using8.C new file mode 100644 index 000000000..a79158710 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using8.C @@ -0,0 +1,22 @@ +// { dg-do compile } + +// Origin: Sergey Shandar <comer@pisem.net> + +// PR c++/9810: Access checking for member function template +// appeared in using declaration. + +struct A +{ + template<class R> void F(R) {} +}; + +struct B: private A +{ + using A::F; +}; + +int main() +{ + B b; + b.F(3); +} diff --git a/gcc/testsuite/g++.dg/template/using9.C b/gcc/testsuite/g++.dg/template/using9.C new file mode 100644 index 000000000..ac5194509 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using9.C @@ -0,0 +1,12 @@ +// { dg-do compile } + +// Origin: stefaandr@hotmail.com + +// PR c++/17154: Using declaration in partial class template specialization. + +template <int numrows, class T> struct A { void test_A() {} }; +template <int numrows, class T> struct B {}; +template <class T> struct B <3, T> : public A <3, T> { + using A <3, T>::test_A; + void test_B_spec() { test_A(); } +}; diff --git a/gcc/testsuite/g++.dg/template/varmod1.C b/gcc/testsuite/g++.dg/template/varmod1.C new file mode 100644 index 000000000..6ae78d900 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/varmod1.C @@ -0,0 +1,11 @@ +// { dg-options "-w" } + +template<typename T> void foo(T); // { dg-message "note" } + +void bar() +{ + int i; + int A[i][i]; + foo(A); // { dg-error "" } + // { dg-message "candidate" "candidate note" { target *-*-* } 9 } +} diff --git a/gcc/testsuite/g++.dg/template/vla1.C b/gcc/testsuite/g++.dg/template/vla1.C new file mode 100644 index 000000000..fe93440f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/vla1.C @@ -0,0 +1,9 @@ +// PR c++/29226 +// { dg-options "" } + +template <bool> +static int label (int w) +{ + sizeof(int[w]); +} +int a = label<false>(1); diff --git a/gcc/testsuite/g++.dg/template/vla2.C b/gcc/testsuite/g++.dg/template/vla2.C new file mode 100644 index 000000000..183f8fadc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/vla2.C @@ -0,0 +1,20 @@ +// PR c++/28879 +// { dg-do compile } +// { dg-options "" } + +struct A +{ + static int i; + int j; +}; + +template<int> void foo () +{ + int x[A::i]; +//int y[A().j]; +} + +void bar () +{ + foo<6> (); +} diff --git a/gcc/testsuite/g++.dg/template/void1.C b/gcc/testsuite/g++.dg/template/void1.C new file mode 100644 index 000000000..732e9d06e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void1.C @@ -0,0 +1,4 @@ +// PR c++/27430 +// { dg-do compile } + +template<void[]> struct A; // { dg-error "array of void" } diff --git a/gcc/testsuite/g++.dg/template/void10.C b/gcc/testsuite/g++.dg/template/void10.C new file mode 100644 index 000000000..4904a281a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void10.C @@ -0,0 +1,10 @@ +//PR c++/28736 + +template<void> struct A // { dg-error "not a valid type" } +{ + template<typename> friend struct B; +}; + +template<typename> struct B {}; + +B<int> b; diff --git a/gcc/testsuite/g++.dg/template/void11.C b/gcc/testsuite/g++.dg/template/void11.C new file mode 100644 index 000000000..1aad7a157 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void11.C @@ -0,0 +1,12 @@ +// PR c++/31446 + +template<void> struct A // { dg-error "valid type" } + +{ + template<int> friend void foo(); +}; + +void bar() +{ + foo<0>(); // { dg-error "not declared|primary-expression" } +} diff --git a/gcc/testsuite/g++.dg/template/void12.C b/gcc/testsuite/g++.dg/template/void12.C new file mode 100644 index 000000000..1d064b63e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void12.C @@ -0,0 +1,7 @@ +// PR c++/28639 + +template<void> struct A // { dg-error "not a valid type" } +{ + static const int i = 1; + char a[i]; +}; diff --git a/gcc/testsuite/g++.dg/template/void13.C b/gcc/testsuite/g++.dg/template/void13.C new file mode 100644 index 000000000..3f36735db --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void13.C @@ -0,0 +1,11 @@ +// PR c++/30299 + +struct A +{ + int i; +}; + +template<void> struct B : A // { dg-error "not a valid type" } +{ + B() { this->i; } +}; diff --git a/gcc/testsuite/g++.dg/template/void14.C b/gcc/testsuite/g++.dg/template/void14.C new file mode 100644 index 000000000..7781c6187 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void14.C @@ -0,0 +1,7 @@ +// PR c++/36411 +// { dg-do compile } + +template<template<void> class> struct A // { dg-error "not a valid type" } +{ + template<template<int> class T> A<T> foo(); // { dg-error "mismatch|expected|invalid" } +}; diff --git a/gcc/testsuite/g++.dg/template/void2.C b/gcc/testsuite/g++.dg/template/void2.C new file mode 100644 index 000000000..eceb36219 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void2.C @@ -0,0 +1,9 @@ +// PR c++/27496 +// { dg-do compile } + +template<int> struct A +{ + template<void> friend class X; // { dg-error "void|valid type" } +}; + +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/void3.C b/gcc/testsuite/g++.dg/template/void3.C new file mode 100644 index 000000000..bb59934ff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void3.C @@ -0,0 +1,5 @@ +//PR c++/28637 + +template<void> struct A {}; // { dg-error "not a valid type" } +A<0> a; // { dg-error "type" } + diff --git a/gcc/testsuite/g++.dg/template/void4.C b/gcc/testsuite/g++.dg/template/void4.C new file mode 100644 index 000000000..fe30b2e37 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void4.C @@ -0,0 +1,7 @@ +//PR c++/28638 + +template<void> struct A; // { dg-error "not a valid type" } + +template<template<int> class> struct B {}; + +B<A> b; // { dg-error "template|invalid type" } diff --git a/gcc/testsuite/g++.dg/template/void5.C b/gcc/testsuite/g++.dg/template/void5.C new file mode 100644 index 000000000..bef9b91f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void5.C @@ -0,0 +1,5 @@ +//PR c++/28640 + +template<void> struct A; // { dg-error "not a valid type" } +template<int> struct A; + diff --git a/gcc/testsuite/g++.dg/template/void6.C b/gcc/testsuite/g++.dg/template/void6.C new file mode 100644 index 000000000..2d5f7ead1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void6.C @@ -0,0 +1,3 @@ +//PR c++/28594 + +template<void, int> struct A; // { dg-error "not a valid type" } diff --git a/gcc/testsuite/g++.dg/template/void7.C b/gcc/testsuite/g++.dg/template/void7.C new file mode 100644 index 000000000..95d87a207 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void7.C @@ -0,0 +1,8 @@ +//PR c++/28741 + +template<void> struct A // { dg-error "not a valid type" } +{ + static int i; +}; + +A<0> a; // { dg-error "invalid type|not a valid type" } diff --git a/gcc/testsuite/g++.dg/template/void8.C b/gcc/testsuite/g++.dg/template/void8.C new file mode 100644 index 000000000..e45c91c04 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void8.C @@ -0,0 +1,7 @@ +//PR c++/28737 + +template<void> struct A; // { dg-error "not a valid type" } + +template<typename> struct B; + +template<void N> struct B<A<N> > {}; // { dg-error "not a valid type|declared|invalid" } diff --git a/gcc/testsuite/g++.dg/template/void9.C b/gcc/testsuite/g++.dg/template/void9.C new file mode 100644 index 000000000..bb2ed66ff --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void9.C @@ -0,0 +1,4 @@ +//PR c++/28738 + +template<int,void> struct A {}; // { dg-error "not a valid type" } +template<int N> struct A<N,0> {}; // { dg-error "not a valid type" } diff --git a/gcc/testsuite/g++.dg/template/vtable1.C b/gcc/testsuite/g++.dg/template/vtable1.C new file mode 100644 index 000000000..c5f122adb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/vtable1.C @@ -0,0 +1,23 @@ +// Test that vtables are set up properly for constructors and destructors +// of template classes. + +// { dg-do run } + +int r; + +template <class T> +struct A { + virtual void f () { } + A() { f (); } + ~A() { f (); } +}; + +struct B : public A<int> { + virtual void f () { ++r; } +}; + +int main () +{ + { B b; } + return r; +} diff --git a/gcc/testsuite/g++.dg/template/vtable2.C b/gcc/testsuite/g++.dg/template/vtable2.C new file mode 100644 index 000000000..3bcc1ac3f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/vtable2.C @@ -0,0 +1,18 @@ +// Use a small template instantiation depth to speed up testing +// { dg-options "-ftemplate-depth-5" } +// { dg-do compile } + +// Origin: rullo.pat@tiscalinet.it +// Nathanael Nerode <neroden@gcc.gnu.org> +// Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/6749: Infinite loop generating vtable. + +template <class T> struct inner {}; + +template <class T> struct parent { + virtual void f() // { dg-error "instantiation depth" } + { parent<inner<T> > p; }; +}; + +template struct parent<int>; diff --git a/gcc/testsuite/g++.dg/template/warn1.C b/gcc/testsuite/g++.dg/template/warn1.C new file mode 100644 index 000000000..2b804f7ca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/warn1.C @@ -0,0 +1,36 @@ +// { dg-do compile } +// { dg-options "-Wall" } + +// Copyright (C) 2003 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 14 Aug 2003 <nathan@codesourcery.com> + +// PR 11512. erroneous warnings + +template <class T> void Foo(T i) +{ + i++, i++; + i, i++; // { dg-warning "left operand" "" } + i++, i; // { dg-warning "right operand" "" } + for (;; --i, ++i) + ; +} + +void Bar () +{ + Foo (1); // { dg-message "instantiated" } +} + +struct M {}; + +struct C +{ + M m; + C () :m (M ()) {} +}; + + +void Baz (int i) +{ + i ? i + 1 : i + 2; // { dg-warning "operand of" } + i ? i++ : 0; +} diff --git a/gcc/testsuite/g++.dg/template/wrap1.C b/gcc/testsuite/g++.dg/template/wrap1.C new file mode 100644 index 000000000..72f687efd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/wrap1.C @@ -0,0 +1,27 @@ +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Michael Matz 03 Mar 2002 <matz@suse.de> +// instance of an actual pattern in 252.eon from SPEC2000 + +// The last Wrapper<char> once wasn't completed when applying '='. + +template <class T> +class Wrapper { + public: + Wrapper (T& a); + Wrapper (const Wrapper<char>& ref); +}; + +template <class T> +class Element { +public: + T * operator[](int x); +}; + +void test() +{ + char bla = 42; + Element< Wrapper <unsigned char> > elem; + elem[1][1] = Wrapper<char> (bla); +} |