diff options
Diffstat (limited to 'test/SemaTemplate')
23 files changed, 461 insertions, 22 deletions
diff --git a/test/SemaTemplate/alias-templates.cpp b/test/SemaTemplate/alias-templates.cpp index 75615ee29517e..20ba6e0cb7bc4 100644 --- a/test/SemaTemplate/alias-templates.cpp +++ b/test/SemaTemplate/alias-templates.cpp @@ -73,19 +73,38 @@ namespace PR11848 { template<typename T> using U = int; template<typename T, typename ...Ts> - void f(U<T> i, U<Ts> ...is) { // expected-error {{type 'U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}} - return i + f<Ts...>(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} + void f1(U<T> i, U<Ts> ...is) { // expected-note 2{{couldn't infer template argument 'T'}} + return i + f1<Ts...>(is...); + } + + // FIXME: This note is technically correct, but could be better. We + // should really say that we couldn't infer template argument 'Ts'. + template<typename ...Ts> + void f2(U<Ts> ...is) { } // expected-note {{requires 0 arguments, but 1 was provided}} + + template<typename...> struct type_tuple {}; + template<typename ...Ts> + void f3(type_tuple<Ts...>, U<Ts> ...is) {} // expected-note {{requires 4 arguments, but 3 were provided}} + + void g() { + f1(U<void>()); // expected-error {{no match}} + f1(1, 2, 3, 4, 5); // expected-error {{no match}} + f2(); // ok + f2(1); // expected-error {{no match}} + f3(type_tuple<>()); + f3(type_tuple<void, void, void>(), 1, 2); // expected-error {{no match}} + f3(type_tuple<void, void, void>(), 1, 2, 3); } template<typename ...Ts> struct S { - S(U<Ts>...ts); // expected-error {{does not contain any unexpanded parameter packs}} + S(U<Ts>...ts); }; template<typename T> struct Hidden1 { template<typename ...Ts> - Hidden1(typename T::template U<Ts> ...ts); // expected-error{{type 'typename Hide::U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}} + Hidden1(typename T::template U<Ts> ...ts); }; template<typename T, typename ...Ts> @@ -97,6 +116,53 @@ namespace PR11848 { template<typename T> using U = int; }; - Hidden1<Hide> h1; // expected-note{{in instantiation of template class 'PR11848::Hidden1<PR11848::Hide>' requested here}} + Hidden1<Hide> h1; Hidden2<Hide, double, char> h2(1, 2); } + +namespace Core22036 { + struct X {}; + void h(...); + template<typename T> using Y = X; + template<typename T, typename ...Ts> struct S { + // An expression can contain an unexpanded pack without being type or + // value dependent. This is true even if the expression's type is a pack + // expansion type. + void f1(Y<T> a) { h(g(a)); } // expected-error {{undeclared identifier 'g'}} + void f2(Y<Ts>...as) { h(g(as)...); } // expected-error {{undeclared identifier 'g'}} + void f3(Y<Ts>...as) { g(as...); } // ok + void f4(Ts ...ts) { h(g(sizeof(ts))...); } // expected-error {{undeclared identifier 'g'}} + // FIXME: We can reject this, since it has no valid instantiations because + // 'g' never has any associated namespaces. + void f5(Ts ...ts) { g(sizeof(ts)...); } // ok + }; +} + +namespace PR13243 { + template<typename A> struct X {}; + template<int I> struct C {}; + template<int I> using Ci = C<I>; + + template<typename A, int I> void f(X<A>, Ci<I>) {} + template void f(X<int>, C<0>); +} + +namespace PR13136 { + template <typename T, T... Numbers> + struct NumberTuple { }; + + template <unsigned int... Numbers> + using MyNumberTuple = NumberTuple<unsigned int, Numbers...>; + + template <typename U, unsigned int... Numbers> + void foo(U&&, MyNumberTuple<Numbers...>); + + template <typename U, unsigned int... Numbers> + void bar(U&&, NumberTuple<unsigned int, Numbers...>); + + int main() { + foo(1, NumberTuple<unsigned int, 0, 1>()); + bar(1, NumberTuple<unsigned int, 0, 1>()); + return 0; + } +} diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp index ec4e0163855c3..fe23d92411089 100644 --- a/test/SemaTemplate/class-template-decl.cpp +++ b/test/SemaTemplate/class-template-decl.cpp @@ -95,3 +95,45 @@ namespace rdar9676205 { }; } +namespace redecl { + int A; // expected-note {{here}} + template<typename T> struct A; // expected-error {{different kind of symbol}} + + int B; // expected-note {{here}} + template<typename T> struct B { // expected-error {{different kind of symbol}} + }; + + template<typename T> struct F; + template<typename T> struct K; + + int G, H; // expected-note {{here}} + + struct S { + int C; // expected-note {{here}} + template<typename T> struct C; // expected-error {{different kind of symbol}} + + int D; // expected-note {{here}} + template<typename T> struct D { // expected-error {{different kind of symbol}} + }; + + int E; + template<typename T> friend struct E { // expected-error {{cannot define a type in a friend}} + }; + + int F; + template<typename T> friend struct F; // ok, redecl::F + + template<typename T> struct G; // ok + + template<typename T> friend struct H; // expected-error {{different kind of symbol}} + + int I, J, K; + + struct U { + template<typename T> struct I; // ok + template<typename T> struct J { // ok + }; + template<typename T> friend struct K; // ok, redecl::K + }; + }; +} diff --git a/test/SemaTemplate/delegating-constructors.cpp b/test/SemaTemplate/delegating-constructors.cpp index e177b50375f01..852b89d809fab 100644 --- a/test/SemaTemplate/delegating-constructors.cpp +++ b/test/SemaTemplate/delegating-constructors.cpp @@ -29,3 +29,21 @@ namespace PR10457 { Foo f(1, 1); } } + +namespace PR12890 { + class Document + { + public: + Document() = default; + + template <class T> + explicit + Document(T&& t) : Document() + { + } + }; + void f() + { + Document d(1); + } +} diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp index 895eacc87edd7..1853511bfc8f0 100644 --- a/test/SemaTemplate/dependent-base-classes.cpp +++ b/test/SemaTemplate/dependent-base-classes.cpp @@ -32,8 +32,7 @@ namespace PR6031 { template <class TT> struct FI2 { - C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}} \ - // expected-error{{C++ requires a type specifier for all declarations}} + C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}} }; template<typename T> diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp index 13d76befe289a..e3e77d0828448 100644 --- a/test/SemaTemplate/explicit-instantiation.cpp +++ b/test/SemaTemplate/explicit-instantiation.cpp @@ -14,7 +14,7 @@ struct X0 { T f0(T x) { return x + 1; // expected-error{{invalid operands}} } - T* f0(T*, T*) { return T(); } + T* f0(T*, T*) { return T(); } // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} template<typename U> T f0(T, U) { return T(); } @@ -32,7 +32,7 @@ struct NotDefaultConstructible { // expected-note{{candidate constructor (the im template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}} template int X0<int>::f0(int); -template int* X0<int>::f0(int*, int*); +template int* X0<int>::f0(int*, int*); // expected-note{{in instantiation of member function 'X0<int>::f0' requested here}} template int X0<int>::f0(int, float); template int X0<int>::f0(int) const; // expected-error{{does not refer}} diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp index 9c95fa0151c14..9acbfdcea29a8 100644 --- a/test/SemaTemplate/friend-template.cpp +++ b/test/SemaTemplate/friend-template.cpp @@ -243,3 +243,62 @@ namespace rdar11147355 { A<double>::B<double> ab; } + +namespace RedeclUnrelated { + struct S { + int packaged_task; + template<typename> class future { + template<typename> friend class packaged_task; + }; + future<void> share; + }; +} + +namespace PR12557 { + template <typename> + struct Foo; + + template <typename Foo_> + struct Bar { + typedef Foo_ Foo; // expected-note {{previous}} + + template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}} + }; + + Bar<int> b; +} + +namespace PR12585 { + struct A { }; + template<typename> struct B { + template<typename> friend class A::does_not_exist; // \ + // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}} + }; + + struct C { + template<typename> struct D; + }; + template<typename> class E { + int n; + template<typename> friend struct C::D; + }; + template<typename T> struct C::D { + int f() { + return E<int>().n; + } + }; + int n = C::D<void*>().f(); + + struct F { + template<int> struct G; + }; + template<typename T> struct H { + // FIXME: As with cases above, the note here is on an unhelpful declaration, + // and should point to the declaration of G within F. + template<T> friend struct F::G; // \ + // expected-error {{different type 'char' in template redeclaration}} \ + // expected-note {{previous}} + }; + H<int> h1; // ok + H<char> h2; // expected-note {{instantiation}} +} diff --git a/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp b/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp index 8a6f9efa68eca..c560c6ba2a3b4 100644 --- a/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp +++ b/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp @@ -131,3 +131,17 @@ template<typename T> struct Derived : Base { Derived<Exc1> d1; // ok Derived<Exc2> d2; // expected-note {{in instantiation of}} + +// If the vtable for a derived class is used, the exception specification of +// any member function which ends up in that vtable is needed, even if it was +// declared in a base class. +namespace PR12763 { + template<bool *B> struct T { + virtual void f() noexcept (*B); // expected-error {{constant expression}} expected-note {{read of non-const}} + }; + bool b; // expected-note {{here}} + struct X : public T<&b> { + virtual void g(); + }; + void X::g() {} // expected-note {{in instantiation of}} +} diff --git a/test/SemaTemplate/instantiate-expr-1.cpp b/test/SemaTemplate/instantiate-expr-1.cpp index 9395117e9ce48..e7772435865d3 100644 --- a/test/SemaTemplate/instantiate-expr-1.cpp +++ b/test/SemaTemplate/instantiate-expr-1.cpp @@ -127,7 +127,7 @@ void test_call_operator(CallOperator call_op, int i, double d) { template<typename T> void test_asm(T t) { - asm ("nop" : "=a"(*t) : "r"(*t)); // expected-error {{indirection requires pointer operand ('int' invalid)}} + asm ("nop" : "=r"(*t) : "r"(*t)); // expected-error {{indirection requires pointer operand ('int' invalid)}} } void test_asm() { diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp index f0ca9a5b21e9e..612a0b7f621c7 100644 --- a/test/SemaTemplate/instantiate-init.cpp +++ b/test/SemaTemplate/instantiate-init.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -struct X0 { // expected-note 4{{candidate}} +struct X0 { // expected-note 8{{candidate}} X0(int*, float*); // expected-note 4{{candidate}} }; @@ -107,3 +107,14 @@ namespace PR7985 { array_lengthof(Description<float*>::data); // expected-error{{no matching function for call to 'array_lengthof'}} } } + +namespace PR13064 { + // Ensure that in-class direct-initialization is instantiated as + // direct-initialization and likewise copy-initialization is instantiated as + // copy-initialization. + struct A { explicit A(int); }; // expected-note{{here}} + template<typename T> struct B { T a { 0 }; }; + B<A> b; + template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}} + C<A> c; // expected-note{{here}} +} diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp index bb6427670c3ee..7b42a27d6b2ca 100644 --- a/test/SemaTemplate/instantiate-member-class.cpp +++ b/test/SemaTemplate/instantiate-member-class.cpp @@ -124,19 +124,20 @@ namespace rdar10397846 { { struct B { - struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \ + expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} }; }; template<int N> void foo() { - class A<N>::B::C X; // expected-note{{in instantiation of member function}} + class A<N>::B::C X; // expected-note 2 {{in instantiation of member function}} int A<N+1>::B::C::*member = 0; } void bar() { - foo<0>(); + foo<0>(); // expected-note{{in instantiation of function template}} foo<1>(); // expected-note{{in instantiation of function template}} } } diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index 363115d1844e5..5e9da3f688e8b 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -173,5 +173,12 @@ namespace PR7022 { typedef X2<> X2_type; X2_type c; } +} +namespace SameSignatureAfterInstantiation { + template<typename T> struct S { + void f(T *); // expected-note {{previous}} + void f(const T*); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (const int *)'}} + }; + S<const int> s; // expected-note {{instantiation}} } diff --git a/test/SemaTemplate/instantiate-objc-1.mm b/test/SemaTemplate/instantiate-objc-1.mm index 2780f8e579783..f8b97eb3ef438 100644 --- a/test/SemaTemplate/instantiate-objc-1.mm +++ b/test/SemaTemplate/instantiate-objc-1.mm @@ -46,3 +46,24 @@ template <typename T> struct EncodeTest { template struct EncodeTest<int>; template struct EncodeTest<double>; template struct EncodeTest<wchar_t>; + +// @() boxing expressions. +template <typename T> struct BoxingTest { + static id box(T value) { + return @(value); // expected-error {{illegal type 'int *' used in a boxed expression}} \ + // expected-error {{illegal type 'long double' used in a boxed expression}} + } +}; + +@interface NSNumber ++ (NSNumber *)numberWithInt:(int)value; +@end + +@interface NSString ++ (id)stringWithUTF8String:(const char *)str; +@end + +template struct BoxingTest<int>; +template struct BoxingTest<const char *>; +template struct BoxingTest<int *>; // expected-note {{in instantiation of member function 'BoxingTest<int *>::box' requested here}} +template struct BoxingTest<long double>; // expected-note {{in instantiation of member function 'BoxingTest<long double>::box' requested here}} diff --git a/test/SemaTemplate/instantiation-backtrace.cpp b/test/SemaTemplate/instantiation-backtrace.cpp index 21456e902ae55..f640836b76811 100644 --- a/test/SemaTemplate/instantiation-backtrace.cpp +++ b/test/SemaTemplate/instantiation-backtrace.cpp @@ -30,3 +30,22 @@ struct G : A<T>, // expected-error{{implicit instantiation of undefined template void h() { (void)sizeof(G<int>); // expected-note{{in instantiation of template class 'G<int>' requested here}} } + +namespace PR13365 { + template <class T> class ResultTy { // expected-warning {{does not declare any constructor}} + T t; // expected-note {{reference member 't' will never be initialized}} + }; + + template <class T1, class T2> + typename ResultTy<T2>::error Deduce( void (T1::*member)(T2) ) {} // \ + // expected-note {{instantiation of template class 'PR13365::ResultTy<int &>'}} \ + // expected-note {{substituting deduced template arguments into function template 'Deduce' [with T1 = PR13365::Cls, T2 = int &]}} \ + // expected-note {{substitution failure [with T1 = PR13365::Cls, T2 = int &]}} + + struct Cls { + void method(int&); + }; + void test() { + Deduce(&Cls::method); // expected-error {{no matching function}} + } +} diff --git a/test/SemaTemplate/instantiation-depth-defarg.cpp b/test/SemaTemplate/instantiation-depth-defarg.cpp new file mode 100644 index 0000000000000..6550987de784a --- /dev/null +++ b/test/SemaTemplate/instantiation-depth-defarg.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 128 -ftemplate-backtrace-limit 4 %s + +template<int N> struct S { + typedef typename S<N-1>::type type; + static int f(int n = S<N-1>::f()); // \ +// expected-error{{recursive template instantiation exceeded maximum depth of 128}} \ +// expected-note 3 {{instantiation of default function argument}} \ +// expected-note {{skipping 125 contexts in backtrace}} \ +// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} + +}; +template<> struct S<0> { + typedef int type; +}; + +// Incrementally instantiate up to S<2048>. +template struct S<128>; +template struct S<256>; +template struct S<384>; +template struct S<512>; +template struct S<640>; +template struct S<768>; +template struct S<896>; +template struct S<1024>; +template struct S<1152>; +template struct S<1280>; +template struct S<1408>; +template struct S<1536>; +template struct S<1664>; +template struct S<1792>; +template struct S<1920>; +template struct S<2048>; + +// Check that we actually bail out when we hit the instantiation depth limit for +// the default arguments. +void g() { S<2048>::f(); } // expected-note {{required here}} diff --git a/test/SemaTemplate/instantiation-depth-subst-2.cpp b/test/SemaTemplate/instantiation-depth-subst-2.cpp new file mode 100644 index 0000000000000..a29d6b5a1b4c3 --- /dev/null +++ b/test/SemaTemplate/instantiation-depth-subst-2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify %s -ftemplate-depth 2 + +template<int N> struct S { }; +// FIXME: We produce the same 'instantiation depth' error here many times +// (2^(depth+1) in total), due to additional lookups performed as part of +// error recovery in DiagnoseTwoPhaseOperatorLookup. +template<typename T> S<T() + T()> operator+(T, T); // expected-error 8{{}} expected-note 10{{}} +S<0> s; +int k = s + s; // expected-error {{invalid operands to binary expression}} diff --git a/test/SemaTemplate/instantiation-depth-subst.cpp b/test/SemaTemplate/instantiation-depth-subst.cpp new file mode 100644 index 0000000000000..58e637411c66c --- /dev/null +++ b/test/SemaTemplate/instantiation-depth-subst.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s -ftemplate-depth 2 + +// PR9793 +template<typename T> auto f(T t) -> decltype(f(t)); // \ +// expected-error {{recursive template instantiation exceeded maximum depth of 2}} \ +// expected-note 3 {{while substituting}} \ +// expected-note {{candidate}} + +int k = f(0); // expected-error {{no matching function for call to 'f'}} diff --git a/test/SemaTemplate/instantiation-depth.cpp b/test/SemaTemplate/instantiation-depth.cpp index 8e1b80368d18d..c0b8bb2a12455 100644 --- a/test/SemaTemplate/instantiation-depth.cpp +++ b/test/SemaTemplate/instantiation-depth.cpp @@ -2,12 +2,30 @@ // RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth-5 -ftemplate-backtrace-limit=4 %s // RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth=5 -ftemplate-backtrace-limit=4 %s +#ifndef NOEXCEPT + template<typename T> struct X : X<T*> { }; \ // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ // expected-note 3 {{instantiation of template class}} \ // expected-note {{skipping 2 contexts in backtrace}} \ // expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} -void test() { +void test() { (void)sizeof(X<int>); // expected-note {{instantiation of template class}} } + +#else + +// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s + +template<typename T> struct S { + S() noexcept(noexcept(T())); +}; +struct T : S<T> {}; \ +// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \ +// expected-note 4 {{in instantiation of exception spec}} \ +// expected-note {{skipping 2 contexts in backtrace}} \ +// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}} +T t; // expected-note {{implicit default constructor for 'T' first required here}} + +#endif diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp index c95b57d4b4fdd..f105ba8e84b57 100644 --- a/test/SemaTemplate/member-template-access-expr.cpp +++ b/test/SemaTemplate/member-template-access-expr.cpp @@ -60,7 +60,7 @@ struct X1 { void test_X1(X1 x1) { float *fp1 = x1.f1<>(17); - float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion turns literal floating-point number into integer}} + float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}} int *ip1 = x1.f1(17); float *ip2 = x1.f1(3.14); diff --git a/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/test/SemaTemplate/ms-function-specialization-class-scope.cpp index bda87f99c9a15..131922bbfbaad 100644 --- a/test/SemaTemplate/ms-function-specialization-class-scope.cpp +++ b/test/SemaTemplate/ms-function-specialization-class-scope.cpp @@ -69,3 +69,24 @@ void test2() b.f(100); } + +namespace PR12709 { + +template<class T> +class TemplateClass { + void member_function() { + specialized_member_template<false>(); + } + + template<bool b> + void specialized_member_template() {} + + template<> + void specialized_member_template<false>() {} // expected-warning{{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}} +}; + +void f() { + TemplateClass<int> t; +} + +} diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp index 2c422dc7e3f7e..8f80cb59e8ab5 100644 --- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -143,3 +143,32 @@ public: template class A<C>; } + +namespace PR12701 { + +class A {}; +class B {}; + +template <class T> +class Base { + public: + bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base clas}} + operator T*() const { return 0; } +}; + +template <class T> +class Container : public Base<T> { + public: + template <typename S> + bool operator=(const Container<S>& rhs) { + return base_fun(rhs); // expected-warning {{use of identifier 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} + } +}; + +void f() { + Container<A> text_provider; + Container<B> text_provider2; + text_provider2 = text_provider; // expected-note {{in instantiation of function template specialization}} +} + +} // namespace PR12701 diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp index 8762cc80630a5..dc6d2a51ec2ef 100644 --- a/test/SemaTemplate/overload-candidates.cpp +++ b/test/SemaTemplate/overload-candidates.cpp @@ -24,7 +24,9 @@ void test_get(void *ptr) { } template<typename T> - typename T::type get_type(const T&); // expected-note{{candidate template ignored: substitution failure [with T = int *]}} + typename T::type get_type(const T&); // expected-note{{candidate template ignored: substitution failure [with T = int *]: type 'int *' cannot be used prior to '::'}} +template<typename T> + void get_type(T *, int[(int)sizeof(T) - 9] = 0); // expected-note{{candidate template ignored: substitution failure [with T = int]: array size is negative}} void test_get_type(int *ptr) { (void)get_type(ptr); // expected-error{{no matching function for call to 'get_type'}} @@ -38,3 +40,25 @@ struct X { void test_X_min(X x) { (void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}} } + +namespace boost { + template<bool, typename = void> struct enable_if {}; + template<typename T> struct enable_if<true, T> { typedef T type; }; +} +template<typename T> typename boost::enable_if<sizeof(T) == 4, int>::type if_size_4(); // expected-note{{candidate template ignored: disabled by 'enable_if' [with T = char]}} +int k = if_size_4<char>(); // expected-error{{no matching function}} + +namespace llvm { + template<typename Cond, typename T = void> struct enable_if : boost::enable_if<Cond::value, T> {}; +} +template<typename T> struct is_int { enum { value = false }; }; +template<> struct is_int<int> { enum { value = true }; }; +template<typename T> typename llvm::enable_if<is_int<T> >::type if_int(); // expected-note{{candidate template ignored: disabled by 'enable_if' [with T = char]}} +void test_if_int() { + if_int<char>(); // expected-error{{no matching function}} +} + +template<typename T> struct NonTemplateFunction { + typename boost::enable_if<sizeof(T) == 4, int>::type f(); // expected-error{{no type named 'type' in 'boost::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration}} +}; +NonTemplateFunction<char> NTFC; // expected-note{{here}} diff --git a/test/SemaTemplate/recovery-crash.cpp b/test/SemaTemplate/recovery-crash.cpp index 0ed3258b683ba..61e880bf5b037 100644 --- a/test/SemaTemplate/recovery-crash.cpp +++ b/test/SemaTemplate/recovery-crash.cpp @@ -1,7 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// We don't expect a fix-it to be applied in this case. Clang used to crash -// trying to recover while adding 'this->' before Work(x); +// Clang used to crash trying to recover while adding 'this->' before Work(x); template <typename> struct A { static void Work(int); // expected-note{{must qualify identifier}} diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp index 9eb4f33de0b95..733dc7fa184ed 100644 --- a/test/SemaTemplate/typename-specifier.cpp +++ b/test/SemaTemplate/typename-specifier.cpp @@ -22,8 +22,8 @@ typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to n // expected-warning{{'typename' occurs outside of a template}} void test(double d) { - typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}} \ - // expected-warning 2{{'typename' occurs outside of a template}} + typename N::A::type f(typename N::A::type(a)); // expected-warning{{disambiguated as a function declaration}} \ + // expected-note{{add a pair of parentheses}} expected-warning 2{{'typename' occurs outside of a template}} int five = f(5); using namespace N; @@ -115,3 +115,40 @@ namespace PR10925 { using typename BasicGeometry<mydim, int>::operator[]; // expected-error {{typename is allowed for identifiers only}} }; } + + +namespace missing_typename { +template <class T1, class T2> struct pair {}; // expected-note 7 {{template parameter is declared here}} + +template <class T1, class T2> +struct map { + typedef T1* iterator; +}; + +template <class T> +class ExampleClass1 { + struct ExampleItem; + + + struct ExampleItemSet { + typedef ExampleItem* iterator; + ExampleItem* operator[](unsigned); + }; + + void foo() { + pair<ExampleItemSet::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}} + pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type$}} + pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type$}} + } + pair<ExampleItemSet::iterator, int> elt; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}} + + + typedef map<int, ExampleItem*> ExampleItemMap; + + static void bar() { + pair<ExampleItemMap::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}} + } + pair<ExampleItemMap::iterator, int> entry; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}} + pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}} +}; +} // namespace missing_typename |