| 1 | // RUN: %clang_cc1 -std=c++11 -verify %s |
| 2 | // |
| 3 | // Note: [class.inhctor] was removed by P0136R1. This tests the new behavior |
| 4 | // for the wording that used to be there. |
| 5 | |
| 6 | template<int> struct X {}; |
| 7 | |
| 8 | // A[n inheriting] constructor [...] has the same access as the corresponding |
| 9 | // constructor [in the base class]. |
| 10 | struct A { |
| 11 | public: |
| 12 | A(X<0>) {} |
| 13 | protected: |
| 14 | A(X<1>) {} // expected-note 2{{declared protected here}} |
| 15 | private: |
| 16 | A(X<2>) {} // expected-note 2{{declared private here}} |
| 17 | friend class FA; |
| 18 | }; |
| 19 | |
| 20 | struct B : A { |
| 21 | using A::A; |
| 22 | friend class FB; |
| 23 | }; |
| 24 | |
| 25 | B b0{X<0>{}}; |
| 26 | B b1{X<1>{}}; // expected-error {{calling a protected constructor}} |
| 27 | B b2{X<2>{}}; // expected-error {{calling a private constructor}} |
| 28 | |
| 29 | struct C : B { |
| 30 | C(X<0> x) : B(x) {} |
| 31 | C(X<1> x) : B(x) {} |
| 32 | }; |
| 33 | |
| 34 | struct FB { |
| 35 | B b0{X<0>{}}; |
| 36 | B b1{X<1>{}}; |
| 37 | }; |
| 38 | |
| 39 | struct FA : A { |
| 40 | using A::A; |
| 41 | }; |
| 42 | FA fa0{X<0>{}}; |
| 43 | FA fa1{X<1>{}}; // expected-error {{calling a protected constructor}} |
| 44 | FA fa2{X<2>{}}; // expected-error {{calling a private constructor}} |
| 45 | |
| 46 | |
| 47 | // It is deleted if the corresponding constructor [...] is deleted. |
| 48 | struct G { |
| 49 | G(int) = delete; // expected-note {{'G' has been explicitly marked deleted here}} |
| 50 | template<typename T> G(T*) = delete; // expected-note {{'G<const char>' has been explicitly marked deleted here}} |
| 51 | }; |
| 52 | struct H : G { |
| 53 | using G::G; |
| 54 | }; |
| 55 | H h1(5); // expected-error {{call to deleted constructor of 'H'}} |
| 56 | H h2("foo"); // expected-error {{call to deleted constructor of 'H'}} |
| 57 | |
| 58 | |
| 59 | // Core defect: It is also deleted if multiple base constructors generate the |
| 60 | // same signature. |
| 61 | namespace DRnnnn { |
| 62 | struct A { |
| 63 | constexpr A(int, float = 0) {} // expected-note {{candidate}} |
| 64 | explicit A(int, int = 0) {} // expected-note {{candidate}} |
| 65 | |
| 66 | A(int, int, int = 0) = delete; // expected-note {{deleted}} |
| 67 | }; |
| 68 | struct B : A { |
| 69 | using A::A; // expected-note 3{{inherited here}} |
| 70 | }; |
| 71 | |
| 72 | constexpr B b0(0, 0.0f); // ok, constexpr |
| 73 | B b1(0, 1); // expected-error {{call to constructor of 'DRnnnn::B' is ambiguous}} |
| 74 | } |
| 75 | |