summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/attributes.cpp8
-rw-r--r--test/SemaTemplate/current-instantiation.cpp13
-rw-r--r--test/SemaTemplate/dependent-base-classes.cpp2
-rw-r--r--test/SemaTemplate/dependent-expr.cpp16
-rw-r--r--test/SemaTemplate/dependent-template-recover.cpp18
-rw-r--r--test/SemaTemplate/dependent-type-identity.cpp16
-rw-r--r--test/SemaTemplate/enum-argument.cpp13
-rw-r--r--test/SemaTemplate/instantiate-anonymous-union.cpp18
-rw-r--r--test/SemaTemplate/instantiate-attr.cpp6
-rw-r--r--test/SemaTemplate/instantiate-complete.cpp29
-rw-r--r--test/SemaTemplate/instantiate-declref-ice.cpp3
-rw-r--r--test/SemaTemplate/instantiate-expr-2.cpp31
-rw-r--r--test/SemaTemplate/instantiate-expr-3.cpp2
-rw-r--r--test/SemaTemplate/instantiate-field.cpp55
-rw-r--r--test/SemaTemplate/instantiate-function-2.cpp10
-rw-r--r--test/SemaTemplate/instantiate-member-pointers.cpp12
-rw-r--r--test/SemaTemplate/instantiate-non-dependent-types.cpp14
-rw-r--r--test/SemaTemplate/instantiate-overload-candidates.cpp21
-rw-r--r--test/SemaTemplate/nested-name-spec-template.cpp7
-rw-r--r--test/SemaTemplate/overload-candidates.cpp40
-rw-r--r--test/SemaTemplate/partial-spec-instantiate.cpp20
-rw-r--r--test/SemaTemplate/temp_explicit.cpp26
-rw-r--r--test/SemaTemplate/template-id-expr.cpp38
-rw-r--r--test/SemaTemplate/unused-variables.cpp21
-rw-r--r--test/SemaTemplate/virtual-member-functions.cpp39
25 files changed, 469 insertions, 9 deletions
diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp
new file mode 100644
index 0000000..b696c5c
--- /dev/null
+++ b/test/SemaTemplate/attributes.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int N>
+struct X {
+ struct __attribute__((__aligned__((N)))) Aligned { }; // expected-error{{'aligned' attribute requires integer constant}}
+
+ int __attribute__((__address_space__(N))) *ptr; // expected-error{{attribute requires 1 argument(s)}}
+};
diff --git a/test/SemaTemplate/current-instantiation.cpp b/test/SemaTemplate/current-instantiation.cpp
index 4563748..c631dd7 100644
--- a/test/SemaTemplate/current-instantiation.cpp
+++ b/test/SemaTemplate/current-instantiation.cpp
@@ -151,3 +151,16 @@ struct X1 {
X1<T*>::a = b;
}
};
+
+namespace ConstantInCurrentInstantiation {
+ template<typename T>
+ struct X {
+ static const int value = 2;
+ static int array[value];
+ };
+
+ template<typename T> const int X<T>::value;
+
+ template<typename T>
+ int X<T>::array[X<T>::value] = { 1, 2 };
+}
diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp
index d0dd9c9..e64d623 100644
--- a/test/SemaTemplate/dependent-base-classes.cpp
+++ b/test/SemaTemplate/dependent-base-classes.cpp
@@ -6,7 +6,7 @@ struct X0 : T::template apply<U> {
};
template<typename T, typename U>
-struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}}
+struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
template<typename T>
struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
diff --git a/test/SemaTemplate/dependent-expr.cpp b/test/SemaTemplate/dependent-expr.cpp
index 3f481b5..9fa7571 100644
--- a/test/SemaTemplate/dependent-expr.cpp
+++ b/test/SemaTemplate/dependent-expr.cpp
@@ -24,3 +24,19 @@ namespace PR6045 {
(void)(k % member);
}
}
+
+namespace PR7198 {
+ struct A
+ {
+ ~A() { }
+ };
+
+ template<typename T>
+ struct B {
+ struct C : A {};
+ void f()
+ {
+ C c = C();
+ }
+ };
+}
diff --git a/test/SemaTemplate/dependent-template-recover.cpp b/test/SemaTemplate/dependent-template-recover.cpp
new file mode 100644
index 0000000..e91ffb5
--- /dev/null
+++ b/test/SemaTemplate/dependent-template-recover.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U, int N>
+struct X {
+ void f(T* t) {
+ t->f0<U>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
+ t->f0<int>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
+
+ t->operator+<U const, 1>(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
+ t->f1<int const, 2>(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
+
+ T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+ t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+
+ // FIXME: We can't recover from these yet
+ (*t).f2<N>(); // expected-error{{expected expression}}
+ (*t).f2<0>(); // expected-error{{expected expression}}
+ }
+};
diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp
index e095812..feffdcf 100644
--- a/test/SemaTemplate/dependent-type-identity.cpp
+++ b/test/SemaTemplate/dependent-type-identity.cpp
@@ -70,3 +70,19 @@ struct X1 {
void f8(typename N::X2<U>::template apply<T> *);
void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
};
+
+namespace PR6851 {
+ template <bool v>
+ struct S;
+
+ struct N {
+ template <bool w>
+ S< S<w>::cond && 1 > foo();
+ };
+
+ struct Alien;
+ bool operator&&(const Alien&, const Alien&);
+
+ template <bool w>
+ S< S<w>::cond && 1 > N::foo() { }
+}
diff --git a/test/SemaTemplate/enum-argument.cpp b/test/SemaTemplate/enum-argument.cpp
index de89487..7d23757 100644
--- a/test/SemaTemplate/enum-argument.cpp
+++ b/test/SemaTemplate/enum-argument.cpp
@@ -21,3 +21,16 @@ struct X0 {
};
X0<int> x0i;
+
+namespace rdar8020920 {
+ template<typename T>
+ struct X {
+ enum { e0 = 32 };
+
+ unsigned long long bitfield : e0;
+
+ void f(int j) {
+ bitfield + j;
+ }
+ };
+}
diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp
index 7c75885..255454b 100644
--- a/test/SemaTemplate/instantiate-anonymous-union.cpp
+++ b/test/SemaTemplate/instantiate-anonymous-union.cpp
@@ -29,3 +29,21 @@ template <typename T> struct C {
};
C<int> c0(0);
+
+namespace PR7088 {
+ template<typename T>
+ void f() {
+ union {
+ int a;
+ union {
+ float real;
+ T d;
+ };
+ };
+
+ a = 17;
+ d = 3.14;
+ }
+
+ template void f<double>();
+}
diff --git a/test/SemaTemplate/instantiate-attr.cpp b/test/SemaTemplate/instantiate-attr.cpp
index 7fb1736..e8291ed 100644
--- a/test/SemaTemplate/instantiate-attr.cpp
+++ b/test/SemaTemplate/instantiate-attr.cpp
@@ -2,6 +2,12 @@
template <typename T>
struct A {
char a __attribute__((aligned(16)));
+
+ struct B {
+ typedef T __attribute__((aligned(16))) i16;
+ i16 x;
+ };
};
int a[sizeof(A<int>) == 16 ? 1 : -1];
+int a2[sizeof(A<int>::B) == 16 ? 1 : -1];
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
index d854c9e..c13930d 100644
--- a/test/SemaTemplate/instantiate-complete.cpp
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -99,3 +99,32 @@ namespace TemporaryObjectCopy {
template void f(int);
}
+
+namespace PR7080 {
+ template <class T, class U>
+ class X
+ {
+ typedef char true_t;
+ class false_t { char dummy[2]; };
+ static true_t dispatch(U);
+ static false_t dispatch(...);
+ static T trigger();
+ public:
+ enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+ };
+
+ template <class T>
+ class rv : public T
+ { };
+
+ bool x = X<int, rv<int>&>::value;
+}
+
+namespace pr7199 {
+ template <class T> class A; // expected-note {{template is declared here}}
+ template <class T> class B {
+ class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
+ };
+
+ template class B<int>; // expected-note {{in instantiation}}
+}
diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp
index e88b494..0f3c08b 100644
--- a/test/SemaTemplate/instantiate-declref-ice.cpp
+++ b/test/SemaTemplate/instantiate-declref-ice.cpp
@@ -31,5 +31,4 @@ struct X1 {
template<typename T>
const unsigned X1<T>::value = sizeof(T);
-int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length arrays are not permitted in C++}} \
-// expected-error{{variable length array declaration not allowed at file scope}}
+int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length array declaration not allowed at file scope}}
diff --git a/test/SemaTemplate/instantiate-expr-2.cpp b/test/SemaTemplate/instantiate-expr-2.cpp
index b91b398..eaa68dd 100644
--- a/test/SemaTemplate/instantiate-expr-2.cpp
+++ b/test/SemaTemplate/instantiate-expr-2.cpp
@@ -194,6 +194,37 @@ namespace N12 {
void f0(int **a) { C::f0(a); }
}
+namespace PR7202 {
+ template<typename U, typename T>
+ struct meta {
+ typedef T type;
+ };
+
+ struct X {
+ struct dummy;
+
+ template<typename T>
+ X(T, typename meta<T, dummy*>::type = 0);
+
+ template<typename T, typename A>
+ X(T, A);
+ };
+
+ template<typename T>
+ struct Z { };
+
+ template<typename T> Z<T> g(T);
+
+ struct Y {
+ template<typename T>
+ void f(T t) {
+ new X(g(*this));
+ }
+ };
+
+ template void Y::f(int);
+}
+
namespace N13 {
class A{
A(const A&);
diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp
index 41a96a3..d506b19 100644
--- a/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/test/SemaTemplate/instantiate-expr-3.cpp
@@ -63,7 +63,7 @@ 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{{invalid}}
+ (void)({ if (t) t = t + 17; t + 12;}); // expected-error{{contextually convertible}}
}
};
diff --git a/test/SemaTemplate/instantiate-field.cpp b/test/SemaTemplate/instantiate-field.cpp
index 60d4b21..a260635 100644
--- a/test/SemaTemplate/instantiate-field.cpp
+++ b/test/SemaTemplate/instantiate-field.cpp
@@ -26,3 +26,58 @@ void test2(const X<float> *xf) {
void test3(const X<int(int)> *xf) {
(void)xf->x; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
}
+
+namespace PR7123 {
+ template <class > struct requirement_;
+
+ template <void(*)()> struct instantiate
+ { };
+
+ template <class > struct requirement ;
+ struct failed ;
+
+ template <class Model> struct requirement<failed *Model::*>
+ {
+ static void failed()
+ {
+ ((Model*)0)->~Model(); // expected-note{{in instantiation of}}
+ }
+ };
+
+ template <class Model> struct requirement_<void(*)(Model)> : requirement<failed *Model::*>
+ { };
+
+ template <int> struct Requires_
+ { typedef void type; };
+
+ template <class Model> struct usage_requirements
+ {
+ ~usage_requirements()
+ {((Model*)0)->~Model(); } // expected-note{{in instantiation of}}
+ };
+
+ template < typename TT > struct BidirectionalIterator
+ {
+ enum
+ { value = 0 };
+
+ instantiate< requirement_<void(*)(usage_requirements<BidirectionalIterator>)>::failed> int534; // expected-note{{in instantiation of}}
+
+ ~BidirectionalIterator()
+ { i--; } // expected-error{{cannot decrement value of type 'PR7123::X'}}
+
+ TT i;
+ };
+
+ struct X
+ { };
+
+ template<typename RanIter>
+ typename Requires_< BidirectionalIterator<RanIter>::value >::type sort(RanIter,RanIter){}
+
+ void f()
+ {
+ X x;
+ sort(x,x);
+ }
+}
diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp
index 6318fac..afca358 100644
--- a/test/SemaTemplate/instantiate-function-2.cpp
+++ b/test/SemaTemplate/instantiate-function-2.cpp
@@ -10,3 +10,13 @@ void f() {
S<int> s1;
S<int> s2(10);
}
+
+namespace PR7184 {
+ template<typename T>
+ void f() {
+ typedef T type;
+ void g(int array[sizeof(type)]);
+ }
+
+ template void f<int>();
+}
diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp
index 2308ac5..dca0f62 100644
--- a/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -53,3 +53,15 @@ void accept_X4(X4<Member>);
void test_accept_X4(X4<&Y::x> x4) {
accept_X4(x4);
}
+
+namespace ValueDepMemberPointer {
+ template <void (*)()> struct instantiate_function {};
+ template <typename T> struct S {
+ static void instantiate();
+ typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}}
+ };
+ template <typename T> void S<T>::instantiate() {
+ int a[(int)sizeof(T)-42]; // expected-error{{array size is negative}}
+ }
+ S<int> s;
+}
diff --git a/test/SemaTemplate/instantiate-non-dependent-types.cpp b/test/SemaTemplate/instantiate-non-dependent-types.cpp
new file mode 100644
index 0000000..a0005c5
--- /dev/null
+++ b/test/SemaTemplate/instantiate-non-dependent-types.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X1 {
+ static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+};
+
+template<void(*)()> struct instantiate { };
+
+template<typename T>
+struct X2 {
+ typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}}
+};
+
+X2<int> x;
diff --git a/test/SemaTemplate/instantiate-overload-candidates.cpp b/test/SemaTemplate/instantiate-overload-candidates.cpp
new file mode 100644
index 0000000..5b7e60d
--- /dev/null
+++ b/test/SemaTemplate/instantiate-overload-candidates.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This is the function actually selected during overload resolution, and the
+// only one defined.
+template <typename T> void f(T*, int) {}
+
+template <typename T> struct S;
+template <typename T> struct S_ : S<T> { typedef int type; }; // expected-note{{in instantiation}}
+template <typename T> struct S {
+ // Force T to have a complete type here so we can observe instantiations with
+ // incomplete types.
+ T t; // expected-error{{field has incomplete type}}
+};
+
+// Provide a bad class and an overload that instantiates templates with it.
+class NoDefinition; // expected-note{{forward declaration}}
+template <typename T> S_<NoDefinition>::type f(T*, NoDefinition*); // expected-note{{in instantiation}}
+
+void test(int x) {
+ f(&x, 0);
+}
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
index 9d25a05..54e615b 100644
--- a/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -64,3 +64,10 @@ namespace test1 {
template <class T>
T pair<T>::* const pair<T>::mem_array[2] = { &pair<T>::x, &pair<T>::y };
}
+
+typedef int T;
+namespace N1 {
+ template<typename T> T f0();
+}
+
+template<typename T> T N1::f0() { }
diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp
new file mode 100644
index 0000000..8762cc8
--- /dev/null
+++ b/test/SemaTemplate/overload-candidates.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+
+void test_min() {
+ (void)min(1, 2l); // expected-error{{no matching function for call to 'min'}}
+}
+
+template<typename R, typename T>
+R *dyn_cast(const T&); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
+
+void test_dyn_cast(int* ptr) {
+ (void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
+}
+
+template<int I, typename T>
+ void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
+template<template<class T> class, typename T>
+ void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+
+void test_get(void *ptr) {
+ get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
+}
+
+template<typename T>
+ typename T::type get_type(const T&); // expected-note{{candidate template ignored: substitution failure [with T = int *]}}
+
+void test_get_type(int *ptr) {
+ (void)get_type(ptr); // expected-error{{no matching function for call to 'get_type'}}
+}
+
+struct X {
+ template<typename T>
+ const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+};
+
+void test_X_min(X x) {
+ (void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}}
+}
diff --git a/test/SemaTemplate/partial-spec-instantiate.cpp b/test/SemaTemplate/partial-spec-instantiate.cpp
index 3156892..68b4964 100644
--- a/test/SemaTemplate/partial-spec-instantiate.cpp
+++ b/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -18,3 +18,23 @@ struct X2<U*> {
};
void a(char *a, char *b) {X2<char*>::f();}
+
+namespace WonkyAccess {
+ template<typename T>
+ struct X {
+ int m;
+ };
+
+ template<typename U>
+ class Y;
+
+ template<typename U>
+ struct Y<U*> : X<U> { };
+
+ template<>
+ struct Y<float*> : X<float> { };
+
+ int f(Y<int*> y, Y<float*> y2) {
+ return y.m + y2.m;
+ }
+}
diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp
index fbb41ff..76244c2 100644
--- a/test/SemaTemplate/temp_explicit.cpp
+++ b/test/SemaTemplate/temp_explicit.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++0x-compat %s
//
// Tests explicit instantiation of templates.
template<typename T, typename U = T> class X0 { };
@@ -125,3 +125,27 @@ template <> // expected-warning{{extraneous template parameter list}}
template <>
struct Foo<int>::Bar<void>
{};
+
+namespace N1 {
+
+ template<typename T> struct X7 { }; // expected-note{{here}}
+
+ namespace Inner {
+ template<typename T> struct X8 { };
+ }
+
+ template struct X7<int>;
+ template struct Inner::X8<int>;
+}
+
+template<typename T> struct X9 { }; // expected-note{{here}}
+
+template struct ::N1::Inner::X8<float>;
+
+namespace N2 {
+ using namespace N1;
+
+ template struct X7<double>; // expected-warning{{must occur in namespace}}
+
+ template struct X9<float>; // expected-warning{{must occur in the global}}
+}
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
index b3f41be..de8d7f6 100644
--- a/test/SemaTemplate/template-id-expr.cpp
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -44,3 +44,41 @@ struct X {
};
template struct X<3>;
+
+// 'template' as a disambiguator.
+// PR7030
+struct Y0 {
+ template<typename U>
+ void f1(U);
+
+ template<typename U>
+ static void f2(U);
+
+ void f3(int);
+
+ static int f4(int);
+ template<typename U>
+ static void f4(U);
+
+ template<typename U>
+ void f() {
+ Y0::template f1<U>(0);
+ Y0::template f1(0);
+ this->template f1(0);
+
+ Y0::template f2<U>(0);
+ Y0::template f2(0);
+
+ Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+ Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+
+ int x;
+ x = Y0::f4(0);
+ x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+
+ x = this->f4(0);
+ x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ }
+};
diff --git a/test/SemaTemplate/unused-variables.cpp b/test/SemaTemplate/unused-variables.cpp
new file mode 100644
index 0000000..1b9350b
--- /dev/null
+++ b/test/SemaTemplate/unused-variables.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -verify %s
+
+struct X0 {
+ ~X0();
+};
+
+struct X1 { };
+
+template<typename T>
+void f() {
+ X0 x0;
+ X1 x1; // expected-warning{{unused variable 'x1'}}
+}
+
+template<typename T, typename U>
+void g() {
+ T t;
+ U u; // expected-warning{{unused variable 'u'}}
+}
+
+template void g<X0, X1>(); // expected-note{{in instantiation of}}
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index 59df3c2..974f664 100644
--- a/test/SemaTemplate/virtual-member-functions.cpp
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -3,7 +3,7 @@
namespace PR5557 {
template <class T> struct A {
A();
- virtual void anchor(); // expected-note{{instantiation}}
+ virtual void anchor();
virtual int a(T x);
};
template<class T> A<T>::A() {}
@@ -14,7 +14,7 @@ template<class T> int A<T>::a(T x) {
}
void f(A<int> x) {
- x.anchor();
+ x.anchor(); // expected-note{{instantiation}}
}
template<typename T>
@@ -43,7 +43,7 @@ template struct Derived<int>; // expected-note {{in instantiation of member func
template<typename T>
struct HasOutOfLineKey {
- HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+ HasOutOfLineKey() { }
virtual T *f(float *fp);
};
@@ -52,4 +52,35 @@ T *HasOutOfLineKey<T>::f(float *fp) {
return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
}
-HasOutOfLineKey<int> out_of_line;
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+
+namespace std {
+ class type_info;
+}
+
+namespace PR7114 {
+ class A { virtual ~A(); }; // expected-note{{declared private here}}
+
+ template<typename T>
+ class B {
+ public:
+ class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
+ static Inner i;
+ static const unsigned value = sizeof(i) == 4;
+ };
+
+ int f() { return B<int>::value; }
+
+ void test_typeid(B<float>::Inner bfi) {
+ (void)typeid(bfi); // expected-note{{implicit default destructor}}
+ }
+
+ template<typename T>
+ struct X : A {
+ void f() { }
+ };
+
+ void test_X(X<int> xi, X<float> xf) {
+ xi.f();
+ }
+}
OpenPOWER on IntegriCloud