summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/class-template-id.cpp4
-rw-r--r--test/SemaTemplate/crash-8204126.cpp6
-rw-r--r--test/SemaTemplate/current-instantiation.cpp35
-rw-r--r--test/SemaTemplate/deduction-crash.cpp2
-rw-r--r--test/SemaTemplate/deduction.cpp29
-rw-r--r--test/SemaTemplate/dependent-base-member-init.cpp9
-rw-r--r--test/SemaTemplate/dependent-class-member-operator.cpp11
-rw-r--r--test/SemaTemplate/dependent-expr.cpp5
-rw-r--r--test/SemaTemplate/inject-templated-friend-post.cpp72
-rw-r--r--test/SemaTemplate/inject-templated-friend.cpp48
-rw-r--r--test/SemaTemplate/instantiate-anonymous-union.cpp19
-rw-r--r--test/SemaTemplate/instantiate-attr.cpp13
-rw-r--r--test/SemaTemplate/instantiate-clang.cpp2
-rw-r--r--test/SemaTemplate/instantiate-declref.cpp10
-rw-r--r--test/SemaTemplate/instantiate-expr-3.cpp10
-rw-r--r--test/SemaTemplate/instantiate-expr-4.cpp2
-rw-r--r--test/SemaTemplate/instantiate-function-1.cpp6
-rw-r--r--test/SemaTemplate/instantiate-member-template.cpp14
-rw-r--r--test/SemaTemplate/member-access-expr.cpp11
-rw-r--r--test/SemaTemplate/member-template-access-expr.cpp19
-rw-r--r--test/SemaTemplate/nested-name-spec-template.cpp11
-rw-r--r--test/SemaTemplate/recovery-crash.cpp19
-rw-r--r--test/SemaTemplate/temp.cpp18
-rw-r--r--test/SemaTemplate/temp_arg_nontype.cpp40
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp18
-rw-r--r--test/SemaTemplate/temp_arg_type.cpp4
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 {
OpenPOWER on IntegriCloud