diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-02-16 09:31:36 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-02-16 09:31:36 +0000 |
| commit | ecb7e5c8afe929ee38155db94de6b084ec32a645 (patch) | |
| tree | 53010172e19c77ea447bcd89e117cda052ab52e0 /test/CXX/temp | |
| parent | 5044f5c816adfd5cba17f1adee1a10127296d0bf (diff) | |
Notes
Diffstat (limited to 'test/CXX/temp')
| -rw-r--r-- | test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp | 57 | ||||
| -rw-r--r-- | test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp | 129 | ||||
| -rw-r--r-- | test/CXX/temp/temp.decls/temp.mem/p5.cpp | 2 | ||||
| -rw-r--r-- | test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp | 2 | ||||
| -rw-r--r-- | test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp | 3 | ||||
| -rw-r--r-- | test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp | 95 | ||||
| -rw-r--r-- | test/CXX/temp/temp.names/p4.cpp | 15 | ||||
| -rw-r--r-- | test/CXX/temp/temp.res/temp.local/p1.cpp | 33 | ||||
| -rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp | 15 |
9 files changed, 346 insertions, 5 deletions
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp new file mode 100644 index 000000000000..83365a2a082c --- /dev/null +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [temp.arg.nontype]p1: +// +// A template-argument for a non-type, non-template template-parameter shall +// be one of: +// -- an integral constant expression; or +// -- the name of a non-type template-parameter ; or +namespace non_type_tmpl_param { + template <int N> struct X0 { X0(); }; + template <int N> X0<N>::X0() { } + template <int* N> struct X1 { X1(); }; + template <int* N> X1<N>::X1() { } + template <int& N> struct X3 { X3(); }; + template <int& N> X3<N>::X3() { } + template <int (*F)(int)> struct X4 { X4(); }; + template <int (*F)(int)> X4<F>::X4() { } + template <typename T, int (T::* M)(int)> struct X5 { X5(); }; + template <typename T, int (T::* M)(int)> X5<T, M>::X5() { } +} + +// -- the address of an object or function with external linkage, including +// function templates and function template-ids but excluding non-static +// class members, expressed as & id-expression where the & is optional if +// the name refers to a function or array, or if the corresponding +// template-parameter is a reference; or +namespace addr_of_obj_or_func { + template <int* p> struct X0 { }; + template <int (*fp)(int)> struct X1 { }; + // FIXME: Add reference template parameter tests. + + int i = 42; + int iarr[10]; + int f(int i); + template <typename T> T f_tmpl(T t); + void test() { + X0<&i> x0a; + X0<iarr> x0b; + X1<&f> x1a; + X1<f> x1b; + X1<f_tmpl> x1c; + X1<f_tmpl<int> > x1d; + } +} + +// -- a constant expression that evaluates to a null pointer value (4.10); or +// -- a constant expression that evaluates to a null member pointer value +// (4.11); or +// -- a pointer to member expressed as described in 5.3.1. + +namespace bad_args { + template <int* N> struct X0 { }; + int i = 42; + X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}} + int* iptr = &i; + X0<iptr> x0b; // FIXME: This should not be accepted. +} diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp new file mode 100644 index 000000000000..458aff2f0232 --- /dev/null +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [temp.arg.nontype] p5: +// The following conversions are performed on each expression used as +// a non-type template-argument. If a non-type template-argument cannot be +// converted to the type of the corresponding template-parameter then the +// program is ill-formed. +// -- for a non-type template-parameter of integral or enumeration type, +// integral promotions (4.5) and integral conversions (4.7) are applied. +// -- for a non-type template-parameter of type pointer to object, +// qualification conversions (4.4) and the array-to-pointer conversion +// (4.2) are applied; if the template-argument is of type +// std::nullptr_t, the null pointer conversion (4.10) is applied. +namespace pointer_to_object_parameters { + // PR6226 + struct Str { + Str(const char *); + }; + + template<const char *s> + struct A { + Str get() { return s; } + }; + + char hello[6] = "Hello"; + extern const char world[6]; + const char world[6] = "world"; + void test() { + (void)A<hello>().get(); + (void)A<world>().get(); + } + + class X { + public: + X(); + X(int, int); + operator int() const; + }; + + template<X const *Ptr> struct A2; + + X *X_ptr; + X an_X; + X array_of_Xs[10]; + A2<X_ptr> *a12; + A2<array_of_Xs> *a13; + A2<&an_X> *a13_2; + A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}} + + // PR6244 + struct X1 {} X1v; + template <X1*> struct X2 { }; + template <X1* Value> struct X3 : X2<Value> { }; + struct X4 : X3<&X1v> { }; +} + +// -- For a non-type template-parameter of type reference to object, no +// conversions apply. The type referred to by the reference may be more +// cv-qualified than the (otherwise identical) type of the +// template-argument. The template-parameter is bound directly to the +// template-argument, which shall be an lvalue. +namespace reference_parameters { + template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}} + template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}} + template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}} + template <const volatile int& N> struct S3 { }; + int i; + extern const int ci; + volatile int vi; + extern const volatile int cvi; + void test() { + S0<i> s0; + S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}} + S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}} + S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}} + + S1<i> s1; + S1<ci> s1c; + S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}} + S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}} + + S2<i> s2; + S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}} + S2<vi> s2v; + S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}} + + S3<i> s3; + S3<ci> s3c; + S3<vi> s3v; + S3<cvi> s3cv; + } + + namespace PR6250 { + template <typename T, const T &ref> void inc() { + ref++; // expected-error{{read-only variable is not assignable}} + } + + template<typename T, const T &ref> void bind() { + T &ref2 = ref; // expected-error{{drops qualifiers}} + } + + int counter; + void test() { + inc<int, counter>(); // expected-note{{instantiation of}} + bind<int, counter>(); // expected-note{{instantiation of}} + } + } +} + +// -- For a non-type template-parameter of type pointer to function, the +// function-to-pointer conversion (4.3) is applied; if the +// template-argument is of type std::nullptr_t, the null pointer +// conversion (4.10) is applied. If the template-argument represents +// a set of overloaded functions (or a pointer to such), the matching +// function is selected from the set (13.4). +// -- For a non-type template-parameter of type reference to function, no +// conversions apply. If the template-argument represents a set of +// overloaded functions, the matching function is selected from the set +// (13.4). +// -- For a non-type template-parameter of type pointer to member function, +// if the template-argument is of type std::nullptr_t, the null member +// pointer conversion (4.11) is applied; otherwise, no conversions +// apply. If the template-argument represents a set of overloaded member +// functions, the matching member function is selected from the set +// (13.4). +// -- For a non-type template-parameter of type pointer to data member, +// qualification conversions (4.4) are applied; if the template-argument +// is of type std::nullptr_t, the null member pointer conversion (4.11) +// is applied. diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp index 098ffa4dec75..b0078d4bdb6d 100644 --- a/test/CXX/temp/temp.decls/temp.mem/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp @@ -55,7 +55,7 @@ template double Foo::As2(); // Partial ordering with conversion function templates. struct X0 { template<typename T> operator T*() { - T x; + T x = 1; x = 17; // expected-error{{read-only variable is not assignable}} } diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp index 8fb736ca0313..95f9640a0b43 100644 --- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate function}} +template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} void g() { f<int,char*,double>("aa",3.0); diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp index bcfb71c987eb..1b7310f00055 100644 --- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp @@ -15,7 +15,8 @@ void test_f1(int *ip, float fv) { f1(ip, fv); } -template<typename T> void f2(T*, T*); // expected-note 2 {{candidate function}} +// TODO: this diagnostic can and should improve +template<typename T> void f2(T*, T*); // expected-note 2 {{candidate template ignored: failed template argument deduction}} struct ConvToIntPtr { operator int*() const; diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp new file mode 100644 index 000000000000..6edf079b3524 --- /dev/null +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test0 { + template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{failed template argument deduction}}\ + // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}} + + template<class A> void temp(A); + void test0() { + // okay: deduce T=int from first argument, A=int during overload + apply(0, &temp); + apply(0, &temp<>); + + // okay: deduce T=int from first and second arguments + apply(0, &temp<int>); + + // deduction failure: T=int from first, T=long from second + apply(0, &temp<long>); // expected-error {{no matching function for call to 'apply'}} + } + + void over(int); + int over(long); + + void test1() { + // okay: deductions match + apply(0, &over); + + // deduction failure: deduced T=long from first argument, T=int from second + apply(0L, &over); // expected-error {{no matching function for call to 'apply'}} + } + + void over(short); + + void test2() { + // deduce T=int from first arg, second arg is undeduced context, + // pick correct overload of 'over' during overload resolution for 'apply' + apply(0, &over); + } + + template<class A, class B> B temp2(A); + void test3() { + // deduce T=int from first arg, A=int B=void during overload resolution + apply(0, &temp2); + apply(0, &temp2<>); + apply(0, &temp2<int>); + + // overload failure + apply(0, &temp2<long>); // expected-error {{no matching function for call to 'apply'}} + } +} + +namespace test1 { + template<class T> void invoke(void (*f)(T)) { f(T()); } // expected-note 6 {{couldn't infer template argument}} \ + // expected-note {{failed template argument deduction}} + + template<class T> void temp(T); + void test0() { + // deduction failure: overload has template => undeduced context + invoke(&temp); // expected-error {{no matching function for call to 'invoke'}} + invoke(&temp<>); // expected-error {{no matching function for call to 'invoke'}} + + // okay: full template-id + invoke(&temp<int>); + } + + void over(int); + int over(long); + + void test1() { + // okay: only one overload matches + invoke(&over); + } + + void over(short); + + void test2() { + // deduction failure: overload has multiple matches => undeduced context + invoke(&over); // expected-error {{no matching function for call to 'invoke'}} + } + + template<class A, class B> B temp2(A); + void test3() { + // deduction failure: overload has template => undeduced context + // (even though partial application temp2<int> could in theory + // let us infer T=int) + invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}} + invoke(&temp2<>); // expected-error {{no matching function for call to 'invoke'}} + invoke(&temp2<int>); // expected-error {{no matching function for call to 'invoke'}} + + // okay: full template-id + invoke(&temp2<int, void>); + + // overload failure + invoke(&temp2<int, int>); // expected-error {{no matching function for call to 'invoke'}} + } +} diff --git a/test/CXX/temp/temp.names/p4.cpp b/test/CXX/temp/temp.names/p4.cpp new file mode 100644 index 000000000000..103a1bd537f8 --- /dev/null +++ b/test/CXX/temp/temp.names/p4.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct meta { + template<typename U> + struct apply { + typedef U* type; + }; +}; + +template<typename T, typename U> +void f(typename T::template apply<U>::type); + +void test_f(int *ip) { + f<meta, int>(ip); +} diff --git a/test/CXX/temp/temp.res/temp.local/p1.cpp b/test/CXX/temp/temp.res/temp.local/p1.cpp new file mode 100644 index 000000000000..ed534a462767 --- /dev/null +++ b/test/CXX/temp/temp.res/temp.local/p1.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++0x [temp.local]p1: +// Like normal (non-template) classes, class templates have an +// injected-class-name (Clause 9). The injected-class-name can be used with +// or without a template-argument-list. When it is used without +// a template-argument-list, it is equivalent to the injected-class-name +// followed by the template-parameters of the class template enclosed in <>. + +template <typename T> struct X0 { + X0(); + ~X0(); + X0 f(const X0&); +}; + +// Test non-type template parameters. +template <int N1, const int& N2, const int* N3> struct X1 { + X1(); + ~X1(); + X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; } +}; + +// When it is used with a template-argument-list, it refers to the specified +// class template specialization, which could be the current specialization +// or another specialization. +// FIXME: Test this clause. + +int i = 42; +int* iptr = &i; +void test() { + X0<int> x0; (void)x0; + X1<42, i, iptr> x1; (void)x1; +} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp index 3b5b5afa8ed9..88cfc5d7c397 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp @@ -18,7 +18,18 @@ namespace test1 { }; typedef A<int> AA; - template <> int AA::foo = 0; // expected-error {{cannot use typedef}} - int AA::bar = 1; // expected-error {{cannot use typedef}} expected-error {{template specialization requires 'template<>'}} + template <> int AA::foo = 0; + int AA::bar = 1; // expected-error {{template specialization requires 'template<>'}} int A<float>::bar = 2; // expected-error {{template specialization requires 'template<>'}} + + template <> class A<double> { + public: + static int foo; // expected-note{{attempt to specialize}} + static int bar; + }; + + typedef A<double> AB; + template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} \ + // expected-error{{does not specialize}} + int AB::bar = 1; } |
