diff options
Diffstat (limited to 'test/SemaTemplate')
26 files changed, 424 insertions, 13 deletions
diff --git a/test/SemaTemplate/class-template-id.cpp b/test/SemaTemplate/class-template-id.cpp index df5ef55..50e0b00 100644 --- a/test/SemaTemplate/class-template-id.cpp +++ b/test/SemaTemplate/class-template-id.cpp @@ -41,3 +41,7 @@ typedef N::C<float> c2; template<typename T> struct Foo { }; // expected-note{{template is declared here}} void f(void) { Foo bar; } // expected-error{{without a template argument list}} + +// rdar://problem/8254267 +template <typename T> class Party; +template <> class Party<T> { friend struct Party<>; }; // expected-error {{use of undeclared identifier 'T'}} diff --git a/test/SemaTemplate/crash-8204126.cpp b/test/SemaTemplate/crash-8204126.cpp new file mode 100644 index 0000000..eb96560 --- /dev/null +++ b/test/SemaTemplate/crash-8204126.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A +{ + template<int> template<typename T> friend void foo(T) {} // expected-error{{extraneous template parameter list}} + void bar() { foo(0); } // expected-error{{use of undeclared identifier 'foo'}} +}; diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp index c631dd7..8caac93 100644 --- a/test/SemaTemplate/current-instantiation.cpp +++ b/test/SemaTemplate/current-instantiation.cpp @@ -164,3 +164,38 @@ namespace ConstantInCurrentInstantiation { template<typename T> int X<T>::array[X<T>::value] = { 1, 2 }; } + +namespace Expressions { + template <bool b> + struct Bool { + enum anonymous_enum { value = b }; + }; + struct True : public Bool<true> {}; + struct False : public Bool<false> {}; + + template <typename T1, typename T2> + struct Is_Same : public False {}; + template <typename T> + struct Is_Same<T, T> : public True {}; + + template <bool b, typename T = void> + struct Enable_If {}; + template <typename T> + struct Enable_If<true, T> { + typedef T type; + }; + + template <typename T> + class Class { + public: + template <typename U> + typename Enable_If<Is_Same<U, Class>::value, void>::type + foo(); + }; + + + template <typename T> + template <typename U> + typename Enable_If<Is_Same<U, Class<T> >::value, void>::type + Class<T>::foo() {} +} diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp index 1860c75..8f4b728 100644 --- a/test/SemaTemplate/deduction-crash.cpp +++ b/test/SemaTemplate/deduction-crash.cpp @@ -4,7 +4,7 @@ // Note that the error count below doesn't matter. We just want to // make sure that the parser doesn't crash. -// CHECK: 16 errors +// CHECK: 15 errors template<a> struct int_; diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp index e8ff8d3..9400a0a 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -105,3 +105,32 @@ namespace PR7463 { template <typename T_> void g (T_&); // expected-note{{T_ = int}} void h (void) { g(f()); } // expected-error{{no matching function for call}} } + +namespace test0 { + template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'T const' equal 'char'}} + char *char_maker(); + void test() { + make(char_maker); // expected-error {{no matching function for call to 'make'}} + } +} + +namespace test1 { + template<typename T> void foo(const T a[3][3]); + void test() { + int a[3][3]; + foo(a); + } +} + +// PR7708 +namespace test2 { + template<typename T> struct Const { typedef void const type; }; + + template<typename T> void f(T, typename Const<T>::type*); + template<typename T> void f(T, void const *); + + void test() { + void *p = 0; + f(0, p); + } +} diff --git a/test/SemaTemplate/dependent-base-member-init.cpp b/test/SemaTemplate/dependent-base-member-init.cpp index 1f13149..1d4fed3 100644 --- a/test/SemaTemplate/dependent-base-member-init.cpp +++ b/test/SemaTemplate/dependent-base-member-init.cpp @@ -57,3 +57,12 @@ template<typename T, typename U> struct X0 : T::template apply<U> { X0(int i) : T::template apply<U>(i) { } }; + +// PR7698 +namespace PR7698 { + template<typename Type> + class A { + char mA[sizeof(Type *)]; + A(): mA() {} + }; +} diff --git a/test/SemaTemplate/dependent-class-member-operator.cpp b/test/SemaTemplate/dependent-class-member-operator.cpp new file mode 100644 index 0000000..d70a60c --- /dev/null +++ b/test/SemaTemplate/dependent-class-member-operator.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// PR7837 + +template<class T> struct C1 { void operator()(T); }; +template<class T> struct C2; // expected-note {{template is declared here}} +template<class T> void foo(T); +void wrap() { + foo(&C1<int>::operator()); + foo(&C1<int>::operator+); // expected-error {{no member named 'operator+' in 'C1<int>'}} + foo(&C2<int>::operator+); // expected-error {{implicit instantiation of undefined template 'C2<int>'}} +} diff --git a/test/SemaTemplate/dependent-expr.cpp b/test/SemaTemplate/dependent-expr.cpp index 9fa7571..e25afce 100644 --- a/test/SemaTemplate/dependent-expr.cpp +++ b/test/SemaTemplate/dependent-expr.cpp @@ -40,3 +40,8 @@ namespace PR7198 { } }; } + +namespace PR7724 { + template<typename OT> int myMethod() + { return 2 && sizeof(OT); } +} diff --git a/test/SemaTemplate/inject-templated-friend-post.cpp b/test/SemaTemplate/inject-templated-friend-post.cpp new file mode 100644 index 0000000..98ac38e --- /dev/null +++ b/test/SemaTemplate/inject-templated-friend-post.cpp @@ -0,0 +1,72 @@ +// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE" +// RUN: %clang %s -S -emit-llvm -o - -DPROTOTYPE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE" +// RUN: %clang %s -S -emit-llvm -o - -DINSTANTIATE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE" +// RUN: %clang %s -S -emit-llvm -o - -DPROTOTYPE -DINSTANTIATE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE" +// RUN: %clang -cc1 %s -DREDEFINE -verify +// RUN: %clang -cc1 %s -DPROTOTYPE -DREDEFINE -verify +// PR8007: friend function not instantiated, reordered version. +// Corresponds to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38392 + +struct std_ostream +{ + int dummy; +}; + +std_ostream cout; + +template <typename STRUCT_TYPE> +struct Streamer; + +typedef struct Foo {} Foo; + +std_ostream& operator << (std_ostream&, const Streamer<Foo>&); + +void test(const Streamer<Foo>& foo) +{ + cout << foo; +} + +template <typename STRUCT_TYPE> +struct Streamer +{ + friend std_ostream& operator << (std_ostream& o, const Streamer& f) // expected-error{{redefinition of 'operator<<'}} + { + Streamer s(f); + s(o); + return o; + } + + Streamer(const STRUCT_TYPE& s) : s(s) {} + + const STRUCT_TYPE& s; + void operator () (std_ostream&) const; +}; + +#ifdef PROTOTYPE +std_ostream& operator << (std_ostream&, const Streamer<Foo>&); +#endif + +#ifdef INSTANTIATE +template struct Streamer<Foo>; +#endif + +#ifdef REDEFINE +std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}} +{ + return o; +} +#endif + +#ifndef INSTANTIATE +template <> +void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}} +{ +} +#endif + +int main(void) +{ + Foo foo; + test(foo); +} + diff --git a/test/SemaTemplate/inject-templated-friend.cpp b/test/SemaTemplate/inject-templated-friend.cpp new file mode 100644 index 0000000..fbe86d9 --- /dev/null +++ b/test/SemaTemplate/inject-templated-friend.cpp @@ -0,0 +1,48 @@ +// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE" +// RUN: %clang -cc1 %s -DREDEFINE -verify +// PR8007: friend function not instantiated. + +struct std_ostream +{ + int dummy; +}; + +std_ostream cout; + +template <typename STRUCT_TYPE> +struct Streamer +{ + friend std_ostream& operator << (std_ostream& o, const Streamer& f) // expected-error{{redefinition of 'operator<<'}} + { + Streamer s(f); + s(o); + return o; + } + + Streamer(const STRUCT_TYPE& s) : s(s) {} + + const STRUCT_TYPE& s; + void operator () (std_ostream&) const; +}; + +typedef struct Foo {} Foo; + +std_ostream& operator << (std_ostream&, const Streamer<Foo>&); +#ifdef REDEFINE +std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}} +{ + // Sema should flag this as a redefinition + return o; +} +#endif + +template <> +void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}} +{ +} + +int main(void) +{ + Foo foo; + cout << foo; +} diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp index 255454b..f2862db 100644 --- a/test/SemaTemplate/instantiate-anonymous-union.cpp +++ b/test/SemaTemplate/instantiate-anonymous-union.cpp @@ -47,3 +47,22 @@ namespace PR7088 { template void f<double>(); } + +// Check for problems related to PR7402 that occur when template instantiation +// instantiates implicit initializers. +namespace PR7402 { + struct X { + union { + struct { + int x; + int y; + }; + int v[2]; + }; + + // Check that this requirement survives instantiation. + template <typename T> X(const T& t) : x(t), y(t) {} + }; + + X x(42.0); +} diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp index e8291ed..bbadb63 100644 --- a/test/SemaTemplate/instantiate-attr.cpp +++ b/test/SemaTemplate/instantiate-attr.cpp @@ -11,3 +11,16 @@ struct A { int a[sizeof(A<int>) == 16 ? 1 : -1]; int a2[sizeof(A<int>::B) == 16 ? 1 : -1]; +// rdar://problem/8243419 +namespace test1 { + template <typename T> struct A { + int a; + T b[0]; + } __attribute__((packed)); + + typedef A<unsigned long> type; + + int test0[sizeof(type) == 4 ? 1 : -1]; + int test1[__builtin_offsetof(type, a) == 0 ? 1 : -1]; + int test2[__builtin_offsetof(type, b) == 4 ? 1 : -1]; +} diff --git a/test/SemaTemplate/instantiate-clang.cpp b/test/SemaTemplate/instantiate-clang.cpp index cef2b70..34d68c4 100644 --- a/test/SemaTemplate/instantiate-clang.cpp +++ b/test/SemaTemplate/instantiate-clang.cpp @@ -24,7 +24,7 @@ template<typename T, typename U, int N, int M> struct ShuffleVector0 { void f(T t, U u, double2 a, double2 b) { (void)__builtin_shufflevector(t, u, N, M); // expected-error{{index}} - (void)__builtin_shufflevector(a, b, N, M); + (void)__builtin_shufflevector(a, b, N, M); // expected-error{{index}} (void)__builtin_shufflevector(a, b, 2, 1); } }; diff --git a/test/SemaTemplate/instantiate-declref.cpp b/test/SemaTemplate/instantiate-declref.cpp index 2d27075..ced56df 100644 --- a/test/SemaTemplate/instantiate-declref.cpp +++ b/test/SemaTemplate/instantiate-declref.cpp @@ -95,3 +95,13 @@ namespace test0 { }; void g() { X<2>(); } } + +// <rdar://problem/8302161> +namespace test1 { + template <typename T> void f(T const &t) { + union { char c; T t_; }; + c = 'a'; // <- this shouldn't silently fail to instantiate + T::foo(); // expected-error {{has no members}} + } + template void f(int const &); // expected-note {{requested here}} +} diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp index d506b19..ca88b003 100644 --- a/test/SemaTemplate/instantiate-expr-3.cpp +++ b/test/SemaTemplate/instantiate-expr-3.cpp @@ -63,7 +63,11 @@ template struct Conditional0<int, int, int>; template<typename T> struct StatementExpr0 { void f(T t) { - (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{contextually convertible}} + (void)({ + if (t) // expected-error{{contextually convertible}} + t = t + 17; + t + 12; // expected-error{{invalid operands}} + }); } }; @@ -106,8 +110,8 @@ struct VaArg1 { VaList va; __builtin_va_start(va, n); // expected-error{{int}} for (int i = 0; i != n; ++i) - (void)__builtin_va_arg(va, ArgType); - __builtin_va_end(va); + (void)__builtin_va_arg(va, ArgType); // expected-error{{int}} + __builtin_va_end(va); // expected-error{{int}} } }; diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp index 8cd7342..adae1da 100644 --- a/test/SemaTemplate/instantiate-expr-4.cpp +++ b/test/SemaTemplate/instantiate-expr-4.cpp @@ -115,7 +115,7 @@ template<typename T> struct Delete0 { void f(T t) { delete t; // expected-error{{cannot delete}} - ::delete [] t; + ::delete [] t; // expected-error{{cannot delete}} } }; diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index a293e9a..651c02c 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -72,7 +72,7 @@ template<typename T, typename U, typename V> struct X6 { if (T x = t) { t = x; } - return v; + return v; // expected-error{{cannot initialize return object of type}} } }; @@ -178,10 +178,10 @@ template<typename T> struct IndirectGoto0 { prior: T prior_label; - prior_label = &&prior; + prior_label = &&prior; // expected-error{{assigning to 'int'}} T later_label; - later_label = &&later; + later_label = &&later; // expected-error{{assigning to 'int'}} later: (void)(1+1); diff --git a/test/SemaTemplate/instantiate-member-template.cpp b/test/SemaTemplate/instantiate-member-template.cpp index 24a3f31..8f4063b 100644 --- a/test/SemaTemplate/instantiate-member-template.cpp +++ b/test/SemaTemplate/instantiate-member-template.cpp @@ -189,3 +189,17 @@ namespace PR7587 { }; } + +namespace PR7669 { + template<class> struct X { + template<class> struct Y { + template<int,class> struct Z; + template<int Dummy> struct Z<Dummy,int> {}; + }; + }; + + void a() + { + X<int>::Y<int>::Z<0,int>(); + } +} diff --git a/test/SemaTemplate/member-access-expr.cpp b/test/SemaTemplate/member-access-expr.cpp index 24db791..16b9515 100644 --- a/test/SemaTemplate/member-access-expr.cpp +++ b/test/SemaTemplate/member-access-expr.cpp @@ -121,3 +121,14 @@ namespace test4 { } }; } + +namespace test5 { + template<typename T> + struct X { + using T::value; + + T &getValue() { + return &value; + } + }; +} diff --git a/test/SemaTemplate/member-template-access-expr.cpp b/test/SemaTemplate/member-template-access-expr.cpp index ea17cdb..dbd27c4 100644 --- a/test/SemaTemplate/member-template-access-expr.cpp +++ b/test/SemaTemplate/member-template-access-expr.cpp @@ -123,3 +123,22 @@ namespace PR6021 { }; }; } + +namespace rdar8198511 { + template<int, typename U> + struct Base { + void f(); + }; + + template<typename T> + struct X0 : Base<1, T> { }; + + template<typename T> + struct X1 { + X0<int> x0; + + void f() { + this->x0.Base<1, int>::f(); + } + }; +} diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp index 12ab486..9c72845 100644 --- a/test/SemaTemplate/nested-name-spec-template.cpp +++ b/test/SemaTemplate/nested-name-spec-template.cpp @@ -88,3 +88,14 @@ namespace PR7385 { has_xxx0<int>::type t; // expected-note{{instantiation of}} } + +namespace PR7725 { + template<class ignored> struct TypedefProvider; + template<typename T> + struct TemplateClass : public TypedefProvider<T> + { + void PrintSelf() { + TemplateClass::Test::PrintSelf(); + } + }; +} diff --git a/test/SemaTemplate/recovery-crash.cpp b/test/SemaTemplate/recovery-crash.cpp new file mode 100644 index 0000000..0ed3258 --- /dev/null +++ b/test/SemaTemplate/recovery-crash.cpp @@ -0,0 +1,19 @@ +// 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); + +template <typename> struct A { + static void Work(int); // expected-note{{must qualify identifier}} +}; + +template <typename T> struct B : public A<T> { + template <typename T2> B(T2 x) { + Work(x); // expected-error{{use of undeclared identifier}} + } +}; + +void Test() { + B<int> b(0); // expected-note{{in instantiation of function template}} +} + diff --git a/test/SemaTemplate/temp.cpp b/test/SemaTemplate/temp.cpp index 961b9c8..e037f0f 100644 --- a/test/SemaTemplate/temp.cpp +++ b/test/SemaTemplate/temp.cpp @@ -1,5 +1,19 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// p3 -template<typename T> int foo(T), bar(T, T); // expected-error{{single entity}} +namespace test0 { + // p3 + template<typename T> int foo(T), bar(T, T); // expected-error{{single entity}} +} + +// PR7252 +namespace test1 { + namespace A { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}} + namespace B { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}} + + template<typename T> struct Derived : A::Base<char>, B::Base<int> { + // FIXME: the syntax error here is unfortunate + typename Derived::Base<float>::t x; // expected-error {{found in multiple base classes of different types}} \ + // expected-error {{expected member name or ';'}} + }; +} diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp index d351eb4..6f51591 100644 --- a/test/SemaTemplate/temp_arg_nontype.cpp +++ b/test/SemaTemplate/temp_arg_nontype.cpp @@ -203,3 +203,43 @@ namespace PR6964 { struct as_nview<Sequence, I0> // expected-note{{while checking a default template argument used here}} { }; } + +// rdar://problem/8302138 +namespace test8 { + template <int* ip> struct A { + int* p; + A() : p(ip) {} + }; + + void test0() { + extern int i00; + A<&i00> a00; + } + + extern int i01; + void test1() { + A<&i01> a01; + } + + + struct C { + int x; + char y; + double z; + }; + + template <C* cp> struct B { + C* p; + B() : p(cp) {} + }; + + void test2() { + extern C c02; + B<&c02> b02; + } + + extern C c03; + void test3() { + B<&c03> b03; + } +} diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp index 6671225..944acac 100644 --- a/test/SemaTemplate/temp_arg_template.cpp +++ b/test/SemaTemplate/temp_arg_template.cpp @@ -33,3 +33,21 @@ 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. // A<::N::Z> *a10; + +// PR7807 +namespace N { + template <typename, typename = int> + struct X + { }; + + template <typename ,int> + struct Y + { X<int> const_ref(); }; + + template <template<typename,int> class TT, typename T, int N> + int operator<<(int, TT<T, N> a) { // expected-note{{candidate template ignored}} + 0 << a.const_ref(); // expected-error{{invalid operands to binary expression ('int' and 'X<int>')}} + } + + void f0( Y<int,1> y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<<Y, int, 1>' requested here}} +} diff --git a/test/SemaTemplate/temp_arg_type.cpp b/test/SemaTemplate/temp_arg_type.cpp index 3876c25..3970942 100644 --- a/test/SemaTemplate/temp_arg_type.cpp +++ b/test/SemaTemplate/temp_arg_type.cpp @@ -24,11 +24,11 @@ A<ns::B> a8; // expected-error{{use of class template ns::B requires template ar // [temp.arg.type]p2 void f() { class X { }; - A<X> * a = 0; // expected-error{{template argument uses local type 'X'}} + A<X> * a = 0; // expected-warning{{template argument uses local type 'X'}} } struct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}} -A<__typeof__(Unnamed)> *a9; // expected-error{{template argument uses unnamed type}} +A<__typeof__(Unnamed)> *a9; // expected-warning{{template argument uses unnamed type}} template<typename T, unsigned N> struct Array { |