1 // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s 2 3 // C++20 [temp.spec] 13.9/6: 4 // The usual access checking rules do not apply to names in a declaration 5 // of an explicit instantiation or explicit specialization, with the 6 // exception of names appearing in a function body, default argument, 7 // base-clause, member-specification, enumerator-list, or static data member 8 // or variable template initializer. 9 // [Note : In particular, the template arguments and names used in the 10 // function declarator(including parameter types, return types and exception 11 // specifications) may be private types or objects that would normally not be 12 // accessible. � end note] 13 14 class A { 15 // expected-note@+1 17{{implicitly declared private here}} 16 template <typename T> class B {}; 17 // expected-note@+1 3{{implicitly declared private here}} 18 static constexpr int num1 = 42; 19 20 protected: 21 // expected-note@+1 13{{declared protected here}} 22 class C {}; 23 // expected-note@+1 2{{declared protected here}} 24 static constexpr int num2 = 43; 25 static int num4; 26 27 public: 28 template <typename T> class D {}; 29 static constexpr int num3 = 44; 30 }; 31 int A::num4 = 44; 32 33 class E : public A { 34 35 // Declarations 36 37 // expected-error@+1 {{is a private member of}} 38 template <typename T = A::B<int>> void func1(); 39 template <typename T = A::C> void func2(); 40 template <typename T = class A::D<int>> void func3(); 41 // expected-error@+1 {{is a private member of}} 42 template <typename T> A::B<int> func4(); 43 // expected-error@+1 {{is a private member of}} 44 template <typename T> A::B<T> func5(); 45 template <typename T> class A::C func6(); 46 template <typename T> class A::D<int> func7(); 47 // expected-error@+1 2{{is a private member of}} 48 template <typename T> void func8(class A::B<T>, int x = A::num1); 49 template <typename T> void func9(A::C, A::D<T>, int = A::num3); 50 51 // Specializations inside class declaration 52 template <> void func1<A::B<char>>() {} 53 template <> void func2<class A::D<char>>() { 54 } template <> void func3<class A::C>() { 55 } 56 template <> class A::B<int> func4<A::B<char>>() { return {}; } template <> A::B<A::D<int>> func5<A::D<int>>() { 57 return {}; 58 } 59 template <> class A::C func6<A::C>() { return {}; } template <> A::D<int> func7<char>() { 60 return {}; 61 } 62 template <> void func8<char>(class A::B<char>, int) {} 63 template <> void func9<A::B<char>>(A::C, A::D<A::B<char>>, int) {} 64 65 // FIXME: Instantiations inside class declaration. 66 // don't work correctly. 67 }; 68 69 // Definitions 70 71 template <typename T> void E::func1() {} 72 template <typename T> void E::func2() {} 73 template <typename T> void E::func3() {} 74 // expected-error@+1 {{is a private member of}} 75 template <typename T> A::B<int> E::func4() { return {}; } 76 // expected-error@+1 {{is a private member of}} 77 template <typename T> A::B<T> E::func5() { return {}; } 78 template <typename T> A::C E::func6() { return {}; } 79 template <typename T> A::D<int> E::func7() { return {}; } 80 // expected-error@+1 {{is a private member of}} 81 template <typename T> void E::func8(A::B<T>, int) {} 82 template <typename T> void E::func9(A::C, A::D<T>, int) {} 83 84 // Specializations 85 86 template <> void E::func1<A::B<int>>() {} 87 template <> void E::func2<class A::C>() {} 88 template <> void E::func3<class A::D<int>>() { 89 } template <> class A::B<int> E::func4<A::B<int>>() { 90 return {}; 91 } template <> A::B<A::C> E::func5<A::C>() { 92 return {}; 93 } 94 template <> class A::C E::func6<A::D<int>>() { return {}; } template <> A::D<int> E::func7<int>() { 95 return {}; 96 } 97 template <> void E::func8<int>(class A::B<int>, int) {} 98 template <> void E::func9<A::C>(A::C, A::D<A::C>, int) {} 99 100 // Instantiations 101 102 template <> void E::func1<A::B<int>>(); 103 template <> void E::func2<class A::C>(); 104 template <> void E::func3<class A::D<int>>(); 105 template <> class A::B<int> E::func4<A::B<int>>(); 106 template <> A::B<A::C> E::func5<A::C>(); 107 template <> class A::C E::func6<A::D<int>>(); 108 template <> A::D<int> E::func7<int>(); 109 template <> void E::func8<int>(class A::B<int>, int); 110 template <> void E::func9<A::C>(A::C, A::D<A::C>, int); 111 112 //----------------------------------------------------------// 113 114 // forward declarations 115 116 // expected-error@+1 {{is a protected member of}} 117 template <typename T> class A::C func1(); 118 // expected-error@+1 {{is a private member of}} 119 template <typename T> A::B<T> func2(); 120 template <typename T> A::D<T> func3(); 121 // expected-error@+1 {{is a private member of}} 122 template <typename T> class A::B<int> func4(); 123 template <typename T> void func5(); 124 // expected-error@+1 {{is a private member of}} 125 template <int x = A::num1> void func6(); 126 // expected-error@+1 {{is a protected member of}} 127 template <int x = A::num2> void func7(); 128 // expected-error@+1 {{is a protected member of}} 129 template <typename T> void func8(int x = sizeof(A::C)); 130 // expected-error@+1 {{is a private member of}} 131 template <typename T> void func9(int x = A::num1); 132 // expected-error@+2 {{is a private member of}} 133 // expected-error@+1 {{is a protected member of}} 134 template <typename T> void func10(class A::B<T>, int x = A::num2); 135 // expected-error@+1 {{is a protected member of}} 136 template <typename T> void func11(class A::C, A::D<T>, int = A::num3); 137 template <typename T> void func12(); 138 template <int x> void func13(); 139 template <typename T, int x> void func14(); 140 template <template <typename> typename T> void func15(); 141 // expected-error@+1 {{is a protected member of}} 142 template <typename T = A::C> void func16(); 143 // expected-error@+1 {{is a private member of}} 144 template <typename T = A::B<int>> void func17(); 145 // expected-error@+1 {{is a protected member of}} 146 template <typename T> auto func18() -> A::C; 147 template <typename T> T func19(); 148 149 //----------------------------------------------------------// 150 151 // definitions 152 153 // expected-error@+1 2{{is a protected member of}} 154 template <typename T> A::C func1() { A::C x; } 155 // expected-error@+2 {{is a private member of}} 156 // expected-error@+1 {{is a protected member of}} 157 template <typename T> A::B<T> func2() { A::D<A::C> x; } 158 template <typename T> A::D<T> func3() { A::D<int> x; } 159 // expected-error@+2 2{{is a private member of}} 160 // expected-error@+1 {{is a protected member of}} 161 template <typename T> class A::B<int> func4() { A::B<A::C> x; } 162 163 template <typename T> 164 void func5() { 165 // expected-error@+2 {{is a private member of}} 166 // expected-error@+1 {{is a protected member of}} 167 A::B<A::D<A::C>> x; 168 // expected-error@+1 {{is a private member of}} 169 A::B<int> x2; 170 } 171 template <typename T> void func8(int x) {} 172 template <typename T> void func9(int x) {} 173 // expected-error@+1 {{is a private member of}} 174 template <typename T> void func10(A::B<T>, int x) {} 175 // expected-error@+1 {{is a protected member of}} 176 template <typename T> void func11(A::C, A::D<T>, int) {} 177 template <typename T> void func12() {} 178 template <int x> void func13() {} 179 template <typename T, int x> void func14() {} 180 template <template <typename> typename T> void func15() {} 181 template <typename T> void func16() {} 182 template <typename T> void func17() {} 183 // expected-error@+1 {{is a protected member of}} 184 template <typename T> auto func18() -> A::C { 185 // expected-error@+1 {{is a protected member of}} 186 return A::C{}; 187 } 188 template <typename T> T func19() { 189 return T{}; 190 } 191 192 //----------------------------------------------------------// 193 194 // explicit specializations 195 196 template <> A::C func1<A::C>(); 197 template <> A::B<A::C> func2<A::C>(); 198 template <> A::D<A::C> func3<A::C>(); 199 template <> class A::B<int> func4<A::C>(); 200 template <> void func5<A::C>(); 201 template <> void func5<A::B<int>>(); 202 template <> void func5<A::D<A::C>>(); 203 template <> void func5<int>(); 204 template <> void func8<A::C>(int x); 205 template <> void func9<decltype(A::num1)>(int); 206 template <> void func10<A::D<int>>(A::B<A::D<int>>, int); 207 template <> void func11<A::C>(A::C, A::D<A::C>, int); 208 template <> void func12<class A::B<char>>() { 209 } template <> void func13<A::num1>() { 210 } 211 template <> void func14<A::B<int>, A::num2>() {} 212 template <> void func15<A::D>() {} 213 template <> void func16<class A::B<char>>() { 214 } template <> void func17<A::B<class A::C>>() { 215 } 216 template <> auto func18<int>() -> class A::C; 217 template <> A::B<int> func19<class A::B<int>>(); 218 219 //----------------------------------------------------------// 220 221 // explicit instantiations 222 223 template void func10<A::C>(A::B<A::C>, decltype(A::num1)); 224 template void func11<A::B<int>>(A::C, A::D<A::B<int>>, decltype(A::num2)); 225 template void func12<A::C>(); 226 template void func13<A::num2>(); 227 template void func13<A::num3>(); 228 template void func14<A::C, A::num1>(); 229 template void func15<A::B>(); 230 template void func17(); 231 template auto func18<char>() -> A::C; 232 template class A::C func19<A::C>(); 233 234 //----------------------------------------------------------// 235 236 // Other cases 237 238 template <int *x> class StealClass { 239 friend int stealFunc() { return *x; } 240 }; 241 242 template class StealClass<&A::num4>; 243 int stealFunc(); 244 245 int stealFunc2() { 246 return stealFunc(); 247 } 248