1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // expected-no-diagnostics
3 
4 // This test creates cases where implicit instantiations of various entities
5 // would cause a diagnostic, but provides expliict specializations for those
6 // entities that avoid the diagnostic. The intent is to verify that
7 // implicit instantiations do not occur (because the explicit specialization
8 // is used instead).
9 struct NonDefaultConstructible {
10   NonDefaultConstructible(int);
11 };
12 
13 
14 // C++ [temp.expl.spec]p1:
15 //   An explicit specialization of any of the following:
16 
17 //     -- function template
18 template<typename T> void f0(T) {
19   T t;
20 }
21 
22 template<> void f0(NonDefaultConstructible) { }
23 
24 void test_f0(NonDefaultConstructible NDC) {
25   f0(NDC);
26 }
27 
28 //     -- class template
29 template<typename T>
30 struct X0 {
31   static T member;
32 
33   void f1(T t) {
34     t = 17;
35   }
36 
37   struct Inner : public T { };
38 
39   template<typename U>
40   struct InnerTemplate : public T { };
41 
42   template<typename U>
43   void ft1(T t, U u);
44 };
45 
46 template<typename T>
47 template<typename U>
48 void X0<T>::ft1(T t, U u) {
49   t = u;
50 }
51 
52 template<typename T> T X0<T>::member;
53 
54 template<> struct X0<void> { };
55 X0<void> test_X0;
56 
57 
58 //     -- member function of a class template
59 template<> void X0<void*>::f1(void *) { }
60 
61 void test_spec(X0<void*> xvp, void *vp) {
62   xvp.f1(vp);
63 }
64 
65 //     -- static data member of a class template
66 template<>
67 NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
68 
69 NonDefaultConstructible &get_static_member() {
70   return X0<NonDefaultConstructible>::member;
71 }
72 
73 //    -- member class of a class template
74 template<>
75 struct X0<void*>::Inner { };
76 
77 X0<void*>::Inner inner0;
78 
79 //    -- member class template of a class template
80 template<>
81 template<>
82 struct X0<void*>::InnerTemplate<int> { };
83 
84 X0<void*>::InnerTemplate<int> inner_template0;
85 
86 //    -- member function template of a class template
87 template<>
88 template<>
89 void X0<void*>::ft1(void*, const void*) { }
90 
91 void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
92   xvp.ft1(vp, cvp);
93 }
94 
95 // example from the standard:
96 template<class T> class stream;
97 template<> class stream<char> { /* ... */ };
98 template<class T> class Array { /* ... */ };
99 template<class T> void sort(Array<T>& v) { /* ... */ }
100 template<> void sort<char*>(Array<char*>&) ;
101