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 | |