diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-11-18 14:59:57 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-11-18 14:59:57 +0000 |
commit | b3d5a323a5ca92ea73443499cee2f15db1ff0fb3 (patch) | |
tree | 60a1694bec5a44d15456acc880cb2f91619f66aa /test/SemaTemplate | |
parent | 8f57cb0305232cb53fff00ef151ca716766f3437 (diff) | |
download | src-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.tar.gz src-b3d5a323a5ca92ea73443499cee2f15db1ff0fb3.zip |
Update clang to r89205.
Notes
Notes:
svn path=/vendor/clang/dist/; revision=199482
Diffstat (limited to 'test/SemaTemplate')
23 files changed, 431 insertions, 35 deletions
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp index d2e90c1daa8f..a8163127b000 100644 --- a/test/SemaTemplate/class-template-decl.cpp +++ b/test/SemaTemplate/class-template-decl.cpp @@ -41,15 +41,13 @@ struct test {}; // expected-note{{previous definition}} template<typename T> struct test : T {}; // expected-error{{redefinition}} -#if 0 -// FIXME: parse template declarations in these scopes, so that we can -// complain about the one at function scope. class X { public: template<typename T> class C; }; void f() { - template<typename T> class X; + template<typename T> class X; // expected-error{{expression}} } -#endif + +template<typename T> class X1 { } var; // expected-error{{declared as a template}} diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp index 4cd43b469ae0..2808404b1d99 100644 --- a/test/SemaTemplate/class-template-spec.cpp +++ b/test/SemaTemplate/class-template-spec.cpp @@ -19,7 +19,7 @@ int test_specs(A<float, float> *a1, A<float, int> *a2) { int test_incomplete_specs(A<double, double> *a1, A<double> *a2) { - (void)a1->x; // expected-error{{incomplete definition of type 'A<double, double>'}} + (void)a1->x; // expected-error{{member access into incomplete type}} (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}} } @@ -104,3 +104,8 @@ Foo<int>* v; Foo<int>& F() { return *v; } template <typename T> class Foo {}; Foo<int> x; + + +// Template template parameters +template<template<class T> class Wibble> +class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}} diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp index 79bf7c585e34..12c6f8b9c101 100644 --- a/test/SemaTemplate/constructor-template.cpp +++ b/test/SemaTemplate/constructor-template.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - struct X0 { // expected-note{{candidate}} X0(int); // expected-note{{candidate}} template<typename T> X0(T); @@ -52,3 +51,34 @@ template<class C> struct A {}; template <> struct A<int>{A(const A<int>&);}; struct B { A<int> x; B(B& a) : x(a.x) {} }; +struct X2 { + X2(); + X2(X2&); + template<typename T> X2(T); +}; + +X2 test(bool Cond, X2 x2) { + if (Cond) + return x2; // okay, uses copy constructor + + return X2(); // expected-error{{incompatible type}} +} + +struct X3 { + template<typename T> X3(T); +}; + +template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}} + +struct X4 { + X4(); + ~X4(); + X4(X4&); + template<typename T> X4(const T&, int = 17); +}; + +X4 test_X4(bool Cond, X4 x4) { + X4 a(x4, 17); // okay, constructor template + X4 b(x4); // okay, copy constructor + return X4(); // expected-error{{incompatible type}} +} diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp new file mode 100644 index 000000000000..7b7e18f74aec --- /dev/null +++ b/test/SemaTemplate/deduction.cpp @@ -0,0 +1,83 @@ +// RUN: clang-cc -fsyntax-only %s + +// Template argument deduction with template template parameters. +template<typename T, template<T> class A> +struct X0 { + static const unsigned value = 0; +}; + +template<template<int> class A> +struct X0<int, A> { + static const unsigned value = 1; +}; + +template<int> struct X0i; +template<long> struct X0l; +int array_x0a[X0<long, X0l>::value == 0? 1 : -1]; +int array_x0b[X0<int, X0i>::value == 1? 1 : -1]; + +template<typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template<typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +template<typename T> struct allocator { }; +template<typename T, typename Alloc = allocator<T> > struct vector {}; + +// Fun with meta-lambdas! +struct _1 {}; +struct _2 {}; + +// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. +template<typename T, typename Arg1, typename Arg2> +struct Replace { + typedef T type; +}; + +// Replacement of the whole type. +template<typename Arg1, typename Arg2> +struct Replace<_1, Arg1, Arg2> { + typedef Arg1 type; +}; + +template<typename Arg1, typename Arg2> +struct Replace<_2, Arg1, Arg2> { + typedef Arg2 type; +}; + +// Replacement through cv-qualifiers +template<typename T, typename Arg1, typename Arg2> +struct Replace<const T, Arg1, Arg2> { + typedef typename Replace<T, Arg1, Arg2>::type const type; +}; + +// Replacement of templates +template<template<typename> class TT, typename T1, typename Arg1, typename Arg2> +struct Replace<TT<T1>, Arg1, Arg2> { + typedef TT<typename Replace<T1, Arg1, Arg2>::type> type; +}; + +template<template<typename, typename> class TT, typename T1, typename T2, + typename Arg1, typename Arg2> +struct Replace<TT<T1, T2>, Arg1, Arg2> { + typedef TT<typename Replace<T1, Arg1, Arg2>::type, + typename Replace<T2, Arg1, Arg2>::type> type; +}; + +// Just for kicks... +template<template<typename, typename> class TT, typename T1, + typename Arg1, typename Arg2> +struct Replace<TT<T1, _2>, Arg1, Arg2> { + typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type; +}; + +int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1]; +int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1]; +int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1]; +int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1]; +int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1]; diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp index 33677aab73ac..0247ddc0ef28 100644 --- a/test/SemaTemplate/default-arguments.cpp +++ b/test/SemaTemplate/default-arguments.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} X<int, 1> *x1; @@ -42,3 +41,83 @@ template<> struct B<void> { typedef B<void*> type; }; + +// Nested default arguments for template parameters. +template<typename T> struct X1 { }; + +template<typename T> +struct X2 { + template<typename U = typename X1<T>::type> // expected-error{{no type named}} + struct Inner1 { }; + + template<T Value = X1<T>::value> // expected-error{{no member named 'value'}} + struct NonType1 { }; + + template<T Value> + struct Inner2 { }; + + template<typename U> + struct Inner3 { + template<typename X = T, typename V = U> + struct VeryInner { }; + + template<T Value1 = sizeof(T), T Value2 = sizeof(U), + T Value3 = Value1 + Value2> + struct NonType2 { }; + }; +}; + +X2<int> x2i; +X2<int>::Inner1<float> x2iif; + +X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}} + +X2<int>::NonType1<'a'> x2_nontype1; +X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}} + +// Check multi-level substitution into template type arguments +X2<int>::Inner3<float>::VeryInner<> vi; +X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; + +template<typename T, typename U> +struct is_same { static const bool value = false; }; + +template<typename T> +struct is_same<T, T> { static const bool value = true; }; + +int array1[is_same<__typeof__(vi), + X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1]; + +int array2[is_same<__typeof(x2_deep_nontype), + X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), + sizeof(char)+sizeof(int)> >::value? 1 : -1]; + +// Template template parameter defaults +template<template<typename T> class X = X2> struct X3 { }; +int array3[is_same<X3<>, X3<X2> >::value? 1 : -1]; + +struct add_pointer { + template<typename T> + struct apply { + typedef T* type; + }; +}; + +template<typename T, template<typename> class X = T::template apply> + struct X4; +int array4[is_same<X4<add_pointer>, + X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; + +template<int> struct X5 {}; // expected-note{{has a different type 'int'}} +template<long> struct X5b {}; +template<typename T, + template<T> class B = X5> // expected-error{{template template argument has different}} \ + // expected-note{{previous non-type template parameter}} + struct X6 {}; + +X6<int> x6a; +X6<long> x6b; // expected-note{{while checking a default template argument}} +X6<long, X5b> x6c; + + +template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}} diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index 9c0f1ecf0c3b..34ac2d967efc 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -65,8 +65,8 @@ void test_x0(X0<int> xi) { xi.f(17); } -struct NotDefaultConstructible { // expected-note{{candidate}} - NotDefaultConstructible(int); // expected-note{{candidate}} +struct NotDefaultConstructible { // expected-note 2{{candidate}} + NotDefaultConstructible(int); // expected-note 2{{candidate}} }; void test_x0_not_default_constructible(X0<NotDefaultConstructible> xn) { @@ -85,6 +85,18 @@ void test_X1() { X1<int> x1; } +template<typename T> +struct X2 { + void operator()(T = T()); // expected-error{{no matching}} +}; + +void test_x2(X2<int> x2i, X2<NotDefaultConstructible> x2n) { + x2i(); + x2i(17); + x2n(NotDefaultConstructible(17)); + x2n(); // expected-note{{in instantiation of default function argument}} +} + // PR5283 namespace PR5283 { template<typename T> struct A { @@ -108,3 +120,27 @@ struct D { }; D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}} } + +// PR5301 +namespace pr5301 { + void f(int, int = 0); + + template <typename T> + void g(T, T = 0); + + template <int I> + void i(int a = I); + + template <typename T> + void h(T t) { + f(0); + g(1); + g(t); + i<2>(); + } + + void test() { + h(0); + } +} + diff --git a/test/SemaTemplate/enum-argument.cpp b/test/SemaTemplate/enum-argument.cpp index 101a1d0cd9da..1d782df202e3 100644 --- a/test/SemaTemplate/enum-argument.cpp +++ b/test/SemaTemplate/enum-argument.cpp @@ -5,3 +5,19 @@ template <Enum v> struct C { typedef C<v> Self; }; template struct C<val>; + +template<typename T> +struct get_size { + static const unsigned value = sizeof(T); +}; + +template<typename T> +struct X0 { + enum { + Val1 = get_size<T>::value, + Val2, + SumOfValues = Val1 + Val2 + }; +}; + +X0<int> x0i; diff --git a/test/SemaTemplate/example-dynarray.cpp b/test/SemaTemplate/example-dynarray.cpp index 2b752b4f1f49..6f3e58e32ab6 100644 --- a/test/SemaTemplate/example-dynarray.cpp +++ b/test/SemaTemplate/example-dynarray.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -emit-llvm-only %s +// RUN: clang -emit-llvm -S -o %t %s #include <stddef.h> #include <stdlib.h> #include <assert.h> diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp new file mode 100644 index 000000000000..08ba9c3a0cd5 --- /dev/null +++ b/test/SemaTemplate/instantiate-attr.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template <typename T> +struct A { + char a __attribute__((aligned(16))); +}; +int a[sizeof(A<int>) == 16 ? 1 : -1]; + diff --git a/test/SemaTemplate/instantiate-decl-init.cpp b/test/SemaTemplate/instantiate-decl-init.cpp new file mode 100644 index 000000000000..d957f2de7da5 --- /dev/null +++ b/test/SemaTemplate/instantiate-decl-init.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR5426 - the non-dependent obj would be fully processed and wrapped in a +// CXXConstructExpr at definition time, which would lead to a failure at +// instantiation time. +struct arg { + arg(); +}; + +struct oldstylemove { + oldstylemove(oldstylemove&); + oldstylemove(const arg&); +}; + +template <typename T> +void fn(T t, const arg& arg) { + oldstylemove obj(arg); +} + +void test() { + fn(1, arg()); +} diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp index b3ddb3fafa31..d2c9e6b5ed82 100644 --- a/test/SemaTemplate/instantiate-member-pointers.cpp +++ b/test/SemaTemplate/instantiate-member-pointers.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - struct Y { int x; }; @@ -25,3 +24,32 @@ struct X2 { template struct X2<int, Y>; template struct X2<int&, Y>; // expected-note{{instantiation}} template struct X2<const void, Y>; // expected-note{{instantiation}} + +template<typename T, typename Class, T Class::*Ptr> +struct X3 { + X3<T, Class, Ptr> &operator=(const T& value) { + return *this; + } +}; + +X3<int, Y, &Y::x> x3; + +typedef int Y::*IntMember; + +template<IntMember Member> +struct X4 { + X3<int, Y, Member> member; + + int &getMember(Y& y) { return y.*Member; } +}; + +int &get_X4(X4<&Y::x> x4, Y& y) { + return x4.getMember(y); +} + +template<IntMember Member> +void accept_X4(X4<Member>); + +void test_accept_X4(X4<&Y::x> x4) { + accept_X4(x4); +} diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp index 36f3b6fd490d..95556bcc221b 100644 --- a/test/SemaTemplate/instantiate-member-template.cpp +++ b/test/SemaTemplate/instantiate-member-template.cpp @@ -103,3 +103,16 @@ void test_X1(int *ip, int i, double *dp) { X1<int*>::Inner4<int>::value = 17; i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}} } + + +template<typename T> +struct X2 { + template<T *Ptr> // expected-error{{pointer to a reference}} + struct Inner; + + template<T Value> // expected-error{{cannot have type 'float'}} + struct Inner2; +}; + +X2<int&> x2a; // expected-note{{instantiation}} +X2<float> x2b; // expected-note{{instantiation}} diff --git a/test/SemaTemplate/instantiate-overloaded-arrow.cpp b/test/SemaTemplate/instantiate-overloaded-arrow.cpp new file mode 100644 index 000000000000..7f0ef0c990ad --- /dev/null +++ b/test/SemaTemplate/instantiate-overloaded-arrow.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %s +// PR5488 + +struct X { + int x; +}; + +struct Iter { + X* operator->(); +}; + +template <typename T> +void Foo() { + (void)Iter()->x; +} + +void Func() { + Foo<int>(); +} + diff --git a/test/SemaTemplate/instantiate-template-template-parm.cpp b/test/SemaTemplate/instantiate-template-template-parm.cpp index b158251915a0..30ba113e20d4 100644 --- a/test/SemaTemplate/instantiate-template-template-parm.cpp +++ b/test/SemaTemplate/instantiate-template-template-parm.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - template<template<typename T> class MetaFun, typename Value> struct apply { typedef typename MetaFun<Value>::type type; @@ -19,3 +18,29 @@ int i; apply<add_pointer, int>::type ip = &i; apply<add_reference, int>::type ir = i; apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot be initialized with a value of type 'int'}} + +// Template template parameters +template<int> struct B; // expected-note{{has a different type 'int'}} + +template<typename T, + template<T Value> class X> // expected-error{{cannot have type 'float'}} \ + // expected-note{{with type 'long'}} +struct X0 { }; + +X0<int, B> x0b1; +X0<float, B> x0b2; // expected-note{{while substituting}} +X0<long, B> x0b3; // expected-error{{template template argument has different template parameters}} + +template<template<int V> class TT> // expected-note{{parameter with type 'int'}} +struct X1 { }; + +template<typename T, template<T V> class TT> +struct X2 { + X1<TT> x1; // expected-error{{has different template parameters}} +}; + +template<int V> struct X3i { }; +template<long V> struct X3l { }; // expected-note{{different type 'long'}} + +X2<int, X3i> x2okay; +X2<long, X3l> x2bad; // expected-note{{instantiation}} diff --git a/test/SemaTemplate/instantiate-using-decl.cpp b/test/SemaTemplate/instantiate-using-decl.cpp index fd9010fa4bbb..a1cf355c890e 100644 --- a/test/SemaTemplate/instantiate-using-decl.cpp +++ b/test/SemaTemplate/instantiate-using-decl.cpp @@ -1,5 +1,7 @@ // RUN: clang-cc -fsyntax-only -verify %s +namespace N { } + template<typename T> struct A { void f(); @@ -10,6 +12,7 @@ struct B : A<T> { using A<T>::f; void g() { + using namespace N; f(); } }; diff --git a/test/SemaTemplate/instantiation-default-2.cpp b/test/SemaTemplate/instantiation-default-2.cpp index 740832c5ba39..4d9a0e2717bf 100644 --- a/test/SemaTemplate/instantiation-default-2.cpp +++ b/test/SemaTemplate/instantiation-default-2.cpp @@ -15,4 +15,4 @@ Constant<float (*)(int, double), &f> *c5; Constant<float (*)(int, int), f> *c6; // expected-error{{non-type template argument of type 'float (*)(int, double)' cannot be converted to a value of type 'float (*)(int, int)'}} -Constant<float, 0> *c7; // expected-note{{in instantiation of default argument for 'Constant<float>' required here}} +Constant<float, 0> *c7; // expected-note{{while substituting}} diff --git a/test/SemaTemplate/member-function-template.cpp b/test/SemaTemplate/member-function-template.cpp index 83bf16c69004..1d46d31e35d3 100644 --- a/test/SemaTemplate/member-function-template.cpp +++ b/test/SemaTemplate/member-function-template.cpp @@ -49,3 +49,27 @@ void test_X_f0_explicit(X x, int i, long l) { // PR4608 class A { template <class x> x a(x z) { return z+y; } int y; }; +// PR5419 +struct Functor { + template <typename T> + bool operator()(const T& v) const { + return true; + } +}; + +void test_Functor(Functor f) { + f(1); +} + +// Instantiation on -> +template<typename T> +struct X1 { + template<typename U> U& get(); +}; + +template<typename T> struct X2; // expected-note{{here}} + +void test_incomplete_access(X1<int> *x1, X2<int> *x2) { + float &fr = x1->get<float>(); + (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}} +} diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp index 1bdc7a89d4e8..e936640f5e3e 100644 --- a/test/SemaTemplate/nested-name-spec-template.cpp +++ b/test/SemaTemplate/nested-name-spec-template.cpp @@ -28,11 +28,8 @@ N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; } ::N::M::Promote<int>::type *ret_intptr6(int* ip) { return ip; } -N::M::template; // expected-error{{expected template name after 'template' keyword in nested name specifier}} \ - // expected-error{{expected unqualified-id}} - -N::M::template Promote; // expected-error{{expected '<' after 'template Promote' in nested name specifier}} \ -// expected-error{{C++ requires a type specifier for all declarations}} +N::M::template; // expected-error{{expected unqualified-id}} +N::M::template Promote; // expected-error{{expected unqualified-id}} namespace N { template<typename T> struct A; @@ -49,13 +46,9 @@ struct ::N::A<int>::X { int foo; }; -#if 0 -// FIXME: the following crashes the parser, because Sema has no way to -// communicate that the "dependent" template-name N::template B doesn't -// actually refer to a template. template<typename T> struct TestA { - typedef typename N::template B<T>::type type; // xpected-error{{'B' following the 'template' keyword does not refer to a template}} - // FIXME: should show what B *does* refer to. + typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \ + // expected-error{{identifier or template-id}} \ + // expected-error{{expected member name}} }; -#endif diff --git a/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp index 4d948184cee9..e18329c145d0 100644 --- a/test/SemaTemplate/nested-template.cpp +++ b/test/SemaTemplate/nested-template.cpp @@ -108,3 +108,21 @@ struct X1 { template<typename, bool = false> struct B { }; }; template struct X1<int>::B<bool>; + +// Template template parameters +template<typename T> +struct X2 { + template<template<class U, T Value> class> // expected-error{{cannot have type 'float'}} \ + // expected-note{{previous non-type template}} + struct Inner { }; +}; + +template<typename T, + int Value> // expected-note{{template non-type parameter}} + struct X2_arg; + +X2<int>::Inner<X2_arg> x2i1; +X2<float> x2a; // expected-note{{instantiation}} +X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}} + + diff --git a/test/SemaTemplate/operator-template.cpp b/test/SemaTemplate/operator-template.cpp index 7039e0ec83de..dc44d04b6882 100644 --- a/test/SemaTemplate/operator-template.cpp +++ b/test/SemaTemplate/operator-template.cpp @@ -11,6 +11,6 @@ int a0(A<int> x) { return x == 1; } template<class X>struct B{typedef X Y;}; template<class X>bool operator==(B<X>*,typename B<X>::Y); // \ expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \ -expected-note{{in instantiation of member function}} +expected-note{{in instantiation of function template specialization}} int a(B<int> x) { return operator==(&x,1); } diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp index a6611582f170..bde92be93dfb 100644 --- a/test/SemaTemplate/temp_arg_nontype.cpp +++ b/test/SemaTemplate/temp_arg_nontype.cpp @@ -10,8 +10,7 @@ A<int> *a2; // expected-error{{template argument for non-type template parameter A<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++0x}} // C++ [temp.arg.nontype]p5: -A<A> *a4; // expected-error{{must have an integral or enumeration type}} \ - // FIXME: the error message above is a bit lame +A<A> *a4; // expected-error{{must be an expression}} enum E { Enumerator = 17 }; A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}} diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp index f2ee66b3f731..ada244bb5de6 100644 --- a/test/SemaTemplate/temp_arg_template.cpp +++ b/test/SemaTemplate/temp_arg_template.cpp @@ -26,12 +26,9 @@ B<X> *a6; // expected-error{{template template argument has different template p C<Y> *a7; C<Ylong> *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}} -template<typename T> void f(int); // expected-note{{function template}} +template<typename T> void f(int); -// FIXME: we're right to provide an error message, but it should say -// that we need a class template. We won't get this right until name -// lookup of 'f' returns a TemplateDecl. -A<f> *a9; // expected-error{{template argument does not refer to}} +A<f> *a9; // expected-error{{must be a class template}} // FIXME: The code below is ill-formed, because of the evil digraph '<:'. // We should provide a much better error message than we currently do. diff --git a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp index 8bde1277edd5..110c380c9aa2 100644 --- a/test/SemaTemplate/value-dependent-null-pointer-constant.cpp +++ b/test/SemaTemplate/value-dependent-null-pointer-constant.cpp @@ -26,4 +26,4 @@ struct A { }; template <typename T> void f(T *t) { (void)static_cast<void*>(static_cast<A*>(t)); -}
\ No newline at end of file +} |