Richard Smith | 762bb9d | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 2 | |
| 3 | // Tests related to constructor inheriting, but not specified in [class.inhctor] |
| 4 | |
| 5 | // [namespace.udecl]p8: |
| 6 | // A using-declaration for a class member shall be a member-declaration. |
| 7 | |
| 8 | struct B1 { |
| 9 | B1(int); |
| 10 | }; |
| 11 | |
Stephen Hines | 651f13c | 2014-04-23 16:59:28 -0700 | [diff] [blame^] | 12 | using B1::B1; // expected-error {{using declaration cannot refer to class member}} |
Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 13 | |
Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 14 | // C++11 [namespace.udecl]p10: |
Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 15 | // A using-declaration is a declaration and can therefore be used repeatedly |
| 16 | // where (and only where) multiple declarations are allowed. |
| 17 | |
| 18 | struct I1 : B1 { |
Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 19 | using B1::B1; // expected-note {{previous using declaration}} |
| 20 | using B1::B1; // expected-error {{redeclaration of using decl}} |
Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 21 | }; |
| 22 | |
Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 23 | // C++11 [namespace.udecl]p3: |
Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 24 | // In a using declaration used as a member-declaration, the nested-name- |
| 25 | // specifier shall name a base class of the class being defined. |
| 26 | // If such a using-declaration names a constructor, the nested-name-specifier |
| 27 | // shall name a direct base class of the class being defined. |
| 28 | |
| 29 | struct D1 : I1 { |
Stephen Hines | 651f13c | 2014-04-23 16:59:28 -0700 | [diff] [blame^] | 30 | using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', cannot inherit constructors}} |
Sebastian Redl | f677ea3 | 2011-02-05 19:23:19 +0000 | [diff] [blame] | 31 | }; |
Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 32 | |
| 33 | template<typename T> struct A {}; |
| 34 | |
| 35 | template<typename T> struct B : A<bool>, A<char> { |
Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 36 | using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}} |
Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 37 | }; |
| 38 | B<bool> bb; |
| 39 | B<char> bc; |
| 40 | B<double> bd; // expected-note {{here}} |
| 41 | |
| 42 | template<typename T> struct C : A<T> { |
Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 43 | using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}} |
Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 44 | }; |
| 45 | C<bool> cb; |
| 46 | C<char> cc; // expected-note {{here}} |
| 47 | |
| 48 | template<typename T> struct D : A<T> {}; |
| 49 | template<typename T> struct E : D<T> { |
Stephen Hines | 651f13c | 2014-04-23 16:59:28 -0700 | [diff] [blame^] | 50 | using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', cannot inherit}} |
Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 51 | }; |
| 52 | E<bool> eb; // expected-note {{here}} |
| 53 | |
| 54 | template<typename T> struct F : D<bool> { |
Richard Smith | 07b0fdc | 2013-03-18 21:12:30 +0000 | [diff] [blame] | 55 | using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} |
Richard Smith | c5a89a1 | 2012-04-02 01:30:27 +0000 | [diff] [blame] | 56 | }; |
| 57 | F<bool> fb; // expected-note {{here}} |
Richard Smith | 4841ca5 | 2013-04-10 05:48:59 +0000 | [diff] [blame] | 58 | |
| 59 | template<typename T> |
| 60 | struct G : T { |
| 61 | using T::T; |
| 62 | G(int &) : G(0) {} |
| 63 | }; |
| 64 | G<B1> g(123); |