brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · 1c830b8 Raw
248 lines · cpp
1// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s2 3// C++20 [temp.spec] 13.9/6:4//   The usual access checking rules do not apply to names in a declaration5//   of an explicit instantiation or explicit specialization, with the6//   exception of names appearing in a function body, default argument,7//   base-clause, member-specification, enumerator-list, or static data member8//   or variable template initializer.9//   [Note : In particular, the template arguments and names used in the10//   function declarator(including parameter types, return types and exception11//   specifications) may be private types or objects that would normally not be12//   accessible. � end note]13 14class 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 20protected: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 27public:28  template <typename T> class D {};29  static constexpr int num3 = 44;30};31int A::num4 = 44;32 33class E : public A {34 35  // Declarations36 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 declaration52  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// Definitions70 71template <typename T> void E::func1() {}72template <typename T> void E::func2() {}73template <typename T> void E::func3() {}74// expected-error@+1 {{is a private member of}}75template <typename T> A::B<int> E::func4() { return {}; }76// expected-error@+1 {{is a private member of}}77template <typename T> A::B<T> E::func5() { return {}; }78template <typename T> A::C E::func6() { return {}; }79template <typename T> A::D<int> E::func7() { return {}; }80// expected-error@+1 {{is a private member of}}81template <typename T> void E::func8(A::B<T>, int) {}82template <typename T> void E::func9(A::C, A::D<T>, int) {}83 84// Specializations85 86template <> void E::func1<A::B<int>>() {}87template <> void E::func2<class A::C>() {}88template <> 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}94template <> class A::C E::func6<A::D<int>>() { return {}; } template <> A::D<int> E::func7<int>() {95  return {};96}97template <> void E::func8<int>(class A::B<int>, int) {}98template <> void E::func9<A::C>(A::C, A::D<A::C>, int) {}99 100// Instantiations101 102template <> void E::func1<A::B<int>>();103template <> void E::func2<class A::C>();104template <> void E::func3<class A::D<int>>();105template <> class A::B<int> E::func4<A::B<int>>();106template <> A::B<A::C> E::func5<A::C>();107template <> class A::C E::func6<A::D<int>>();108template <> A::D<int> E::func7<int>();109template <> void E::func8<int>(class A::B<int>, int);110template <> void E::func9<A::C>(A::C, A::D<A::C>, int);111 112//----------------------------------------------------------//113 114// forward declarations115 116// expected-error@+1 {{is a protected member of}}117template <typename T> class A::C func1();118// expected-error@+1 {{is a private member of}}119template <typename T> A::B<T> func2();120template <typename T> A::D<T> func3();121// expected-error@+1 {{is a private member of}}122template <typename T> class A::B<int> func4();123template <typename T> void func5();124// expected-error@+1 {{is a private member of}}125template <int x = A::num1> void func6();126// expected-error@+1 {{is a protected member of}}127template <int x = A::num2> void func7();128// expected-error@+1 {{is a protected member of}}129template <typename T> void func8(int x = sizeof(A::C));130// expected-error@+1 {{is a private member of}}131template <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}}134template <typename T> void func10(class A::B<T>, int x = A::num2);135// expected-error@+1 {{is a protected member of}}136template <typename T> void func11(class A::C, A::D<T>, int = A::num3);137template <typename T> void func12();138template <int x> void func13();139template <typename T, int x> void func14();140template <template <typename> typename T> void func15();141// expected-error@+1 {{is a protected member of}}142template <typename T = A::C> void func16();143// expected-error@+1 {{is a private member of}}144template <typename T = A::B<int>> void func17();145// expected-error@+1 {{is a protected member of}}146template <typename T> auto func18() -> A::C;147template <typename T> T func19();148 149//----------------------------------------------------------//150 151// definitions152 153// expected-error@+1 2{{is a protected member of}}154template <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}}157template <typename T> A::B<T> func2() { A::D<A::C> x; }158template <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}}161template <typename T> class A::B<int> func4() { A::B<A::C> x; }162 163template <typename T>164void 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}171template <typename T> void func8(int x) {}172template <typename T> void func9(int x) {}173// expected-error@+1 {{is a private member of}}174template <typename T> void func10(A::B<T>, int x) {}175// expected-error@+1 {{is a protected member of}}176template <typename T> void func11(A::C, A::D<T>, int) {}177template <typename T> void func12() {}178template <int x> void func13() {}179template <typename T, int x> void func14() {}180template <template <typename> typename T> void func15() {}181template <typename T> void func16() {}182template <typename T> void func17() {}183// expected-error@+1 {{is a protected member of}}184template <typename T> auto func18() -> A::C {185  // expected-error@+1 {{is a protected member of}}186  return A::C{};187}188template <typename T> T func19() {189  return T{};190}191 192//----------------------------------------------------------//193 194// explicit specializations195 196template <> A::C func1<A::C>();197template <> A::B<A::C> func2<A::C>();198template <> A::D<A::C> func3<A::C>();199template <> class A::B<int> func4<A::C>();200template <> void func5<A::C>();201template <> void func5<A::B<int>>();202template <> void func5<A::D<A::C>>();203template <> void func5<int>();204template <> void func8<A::C>(int x);205template <> void func9<decltype(A::num1)>(int);206template <> void func10<A::D<int>>(A::B<A::D<int>>, int);207template <> void func11<A::C>(A::C, A::D<A::C>, int);208template <> void func12<class A::B<char>>() {209} template <> void func13<A::num1>() {210}211template <> void func14<A::B<int>, A::num2>() {}212template <> void func15<A::D>() {}213template <> void func16<class A::B<char>>() {214} template <> void func17<A::B<class A::C>>() {215}216template <> auto func18<int>() -> class A::C;217template <> A::B<int> func19<class A::B<int>>();218 219//----------------------------------------------------------//220 221// explicit instantiations222 223template void func10<A::C>(A::B<A::C>, decltype(A::num1));224template void func11<A::B<int>>(A::C, A::D<A::B<int>>, decltype(A::num2));225template void func12<A::C>();226template void func13<A::num2>();227template void func13<A::num3>();228template void func14<A::C, A::num1>();229template void func15<A::B>();230template void func17();231template auto func18<char>() -> A::C;232template class A::C func19<A::C>();233 234//----------------------------------------------------------//235 236// Other cases237 238template <int *x> class StealClass {239  friend int stealFunc() { return *x; }240};241 242template class StealClass<&A::num4>;243int stealFunc();244 245int stealFunc2() {246  return stealFunc();247}248