summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp4
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp114
-rw-r--r--clang/test/SemaTemplate/class-template-spec.cpp4
-rw-r--r--clang/test/SemaTemplate/temp_class_spec_neg.cpp4
4 files changed, 121 insertions, 5 deletions
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
index f3d0709ef82..239b8aeb04e 100644
--- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
@@ -1,8 +1,10 @@
-// RUN: clang-cc -fsyntax-only %s
+// RUN: clang-cc -fsyntax-only -verify %s
// This test creates cases where implicit instantiations of various entities
// would cause a diagnostic, but provides expliict specializations for those
// entities that avoid the diagnostic. The intent is to verify that
+// implicit instantiations do not occur (because the explicit specialization
+// is used instead).
struct NonDefaultConstructible {
NonDefaultConstructible(int);
};
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
new file mode 100644
index 00000000000..3bc0a07c96e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
@@ -0,0 +1,114 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// This test creates cases where implicit instantiations of various entities
+// would cause a diagnostic, but provides expliict specializations for those
+// entities that avoid the diagnostic. The specializations are alternately
+// declarations and definitions, and the intent of this test is to verify
+// that we allow specializations only in the appropriate namespaces (and
+// nowhere else).
+struct NonDefaultConstructible {
+ NonDefaultConstructible(int);
+};
+
+
+// C++ [temp.expl.spec]p1:
+// An explicit specialization of any of the following:
+
+// -- function template
+namespace N0 {
+ template<typename T> void f0(T) { // expected-note{{here}}
+ T t;
+ }
+
+ template<> void f0(NonDefaultConstructible) { }
+
+ void test_f0(NonDefaultConstructible NDC) {
+ f0(NDC);
+ }
+
+ template<> void f0(int);
+ template<> void f0(long);
+}
+
+template<> void N0::f0(int) { } // okay
+
+namespace N1 {
+ template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}}
+}
+
+template<> void N0::f0(double) { } // expected-error{{originally be declared}}
+
+// FIXME: update the remainder of this test to check for scopes properly.
+// -- class template
+template<typename T>
+struct X0 {
+ static T member;
+
+ void f1(T t) {
+ t = 17;
+ }
+
+ struct Inner : public T { };
+
+ template<typename U>
+ struct InnerTemplate : public T { };
+
+ template<typename U>
+ void ft1(T t, U u);
+};
+
+template<typename T>
+template<typename U>
+void X0<T>::ft1(T t, U u) {
+ t = u;
+}
+
+template<typename T> T X0<T>::member;
+
+template<> struct X0<void> { };
+X0<void> test_X0;
+
+
+// -- member function of a class template
+template<> void X0<void*>::f1(void *) { }
+
+void test_spec(X0<void*> xvp, void *vp) {
+ xvp.f1(vp);
+}
+
+// -- static data member of a class template
+template<>
+NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
+
+NonDefaultConstructible &get_static_member() {
+ return X0<NonDefaultConstructible>::member;
+}
+
+// -- member class of a class template
+template<>
+struct X0<void*>::Inner { };
+
+X0<void*>::Inner inner0;
+
+// -- member class template of a class template
+template<>
+template<>
+struct X0<void*>::InnerTemplate<int> { };
+
+X0<void*>::InnerTemplate<int> inner_template0;
+
+// -- member function template of a class template
+template<>
+template<>
+void X0<void*>::ft1(void*, const void*) { }
+
+void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
+ xvp.ft1(vp, cvp);
+}
+
+// example from the standard:
+template<class T> class stream;
+template<> class stream<char> { /* ... */ };
+template<class T> class Array { /* ... */ };
+template<class T> void sort(Array<T>& v) { /* ... */ }
+template<> void sort<char*>(Array<char*>&) ;
diff --git a/clang/test/SemaTemplate/class-template-spec.cpp b/clang/test/SemaTemplate/class-template-spec.cpp
index 34c616cc2f4..e4d917f7756 100644
--- a/clang/test/SemaTemplate/class-template-spec.cpp
+++ b/clang/test/SemaTemplate/class-template-spec.cpp
@@ -85,12 +85,12 @@ namespace N {
template<> struct N::B<int> { }; // okay
-template<> struct N::B<float> { }; // expected-error{{class template specialization of 'B' not in namespace 'N'}}
+template<> struct N::B<float> { }; // expected-error{{originally}}
namespace M {
template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
- template<> struct ::A<long double>; // expected-error{{class template specialization of 'A' must occur in the global scope}}
+ template<> struct ::A<long double>; // expected-error{{originally}}
}
template<> struct N::B<char> {
diff --git a/clang/test/SemaTemplate/temp_class_spec_neg.cpp b/clang/test/SemaTemplate/temp_class_spec_neg.cpp
index b50bd8f634a..a029f474fc5 100644
--- a/clang/test/SemaTemplate/temp_class_spec_neg.cpp
+++ b/clang/test/SemaTemplate/temp_class_spec_neg.cpp
@@ -9,7 +9,7 @@ namespace N {
}
template<typename T>
-struct N::M::A<T*> { }; // expected-error{{not in namespace}}
+struct N::M::A<T*> { }; // expected-error{{originally}}
// C++ [temp.class.spec]p9
// bullet 1
@@ -25,7 +25,7 @@ template <class T, T* t> struct C<T*, t>; // okay
template< int X, int (*array_ptr)[X] > class A2 {}; // expected-note{{here}}
int array[5];
-template< int X > class A2<X,&array> { }; // expected-error{{specializes}}
+template< int X > class A2<X, &array> { }; // expected-error{{specializes}}
template<typename T, int N, template<typename X> class TT>
struct Test0;
OpenPOWER on IntegriCloud