diff options
Diffstat (limited to 'test/CXX/dcl.decl')
| -rw-r--r-- | test/CXX/dcl.decl/dcl.decomp/p3.cpp | 77 | ||||
| -rw-r--r-- | test/CXX/dcl.decl/dcl.decomp/p4.cpp | 51 | ||||
| -rw-r--r-- | test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp | 51 |
3 files changed, 166 insertions, 13 deletions
diff --git a/test/CXX/dcl.decl/dcl.decomp/p3.cpp b/test/CXX/dcl.decl/dcl.decomp/p3.cpp index b7092e3af023..b3f0cf187446 100644 --- a/test/CXX/dcl.decl/dcl.decomp/p3.cpp +++ b/test/CXX/dcl.decl/dcl.decomp/p3.cpp @@ -36,7 +36,7 @@ void no_get_2() { auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}} } -template<int> float &get(A); +template<int> float &get(A); // expected-note 2 {{no known conversion}} void no_tuple_element_1() { auto [a0, a1, a2] = A(); // expected-error-re {{'std::tuple_element<0U{{L*}}, A>::type' does not name a type}} expected-note {{in implicit}} @@ -57,7 +57,7 @@ void no_tuple_element_3() { template<> struct std::tuple_element<1, A> { typedef float &type; }; template<> struct std::tuple_element<2, A> { typedef const float &type; }; -template<int N> auto get(B) -> int (&)[N + 1]; +template<int N> auto get(B) -> int (&)[N + 1]; // expected-note 2 {{no known conversion}} template<int N> struct std::tuple_element<N, B> { typedef int type[N +1 ]; }; template<typename T> struct std::tuple_size<const T> : std::tuple_size<T> {}; @@ -138,19 +138,25 @@ int member_get() { return c; } -struct D { template<int> struct get {}; }; // expected-note {{declared here}} +struct D { + // FIXME: Emit a note here explaining why this was ignored. + template<int> struct get {}; +}; template<> struct std::tuple_size<D> { static const int value = 1; }; template<> struct std::tuple_element<0, D> { typedef D::get<0> type; }; void member_get_class_template() { - auto [d] = D(); // expected-error {{cannot refer to member 'get' in 'D' with '.'}} expected-note {{in implicit init}} + auto [d] = D(); // expected-error {{no matching function for call to 'get'}} expected-note {{in implicit init}} } -struct E { int get(); }; +struct E { + // FIXME: Emit a note here explaining why this was ignored. + int get(); +}; template<> struct std::tuple_size<E> { static const int value = 1; }; template<> struct std::tuple_element<0, E> { typedef int type; }; void member_get_non_template() { // FIXME: This diagnostic is not very good. - auto [e] = E(); // expected-error {{no member named 'get'}} expected-note {{in implicit init}} + auto [e] = E(); // expected-error {{no matching function for call to 'get'}} expected-note {{in implicit init}} } namespace ADL { @@ -230,3 +236,62 @@ namespace constant { } static_assert(g() == 4); // expected-error {{constant}} expected-note {{in call to 'g()'}} } + +// P0961R1 +struct InvalidMemberGet { + int get(); + template <class T> int get(); + struct get {}; +}; +template <> struct std::tuple_size<InvalidMemberGet> { static constexpr size_t value = 1; }; +template <> struct std::tuple_element<0, InvalidMemberGet> { typedef float type; }; +template <size_t> float get(InvalidMemberGet) { return 0; } +int f() { + InvalidMemberGet img; + auto [x] = img; + typedef decltype(x) same_as_float; + typedef float same_as_float; +} + +struct ValidMemberGet { + int get(); + template <class T> int get() { return 0; } + template <size_t N> float get() { return 0; } +}; +template <> struct std::tuple_size<ValidMemberGet> { static constexpr size_t value = 1; }; +template <> struct std::tuple_element<0, ValidMemberGet> { typedef float type; }; +// Don't use this one; we should use the member get. +template <size_t N> int get(ValidMemberGet) { static_assert(N && false, ""); } +int f2() { + ValidMemberGet img; + auto [x] = img; + typedef decltype(x) same_as_float; + typedef float same_as_float; +} + +struct Base1 { + int get(); // expected-note{{member found by ambiguous name lookup}} +}; +struct Base2 { + template<int> int get(); // expected-note{{member found by ambiguous name lookup}} +}; +struct Derived : Base1, Base2 {}; + +template <> struct std::tuple_size<Derived> { static constexpr size_t value = 1; }; +template <> struct std::tuple_element<0, Derived> { typedef int type; }; + +auto [x] = Derived(); // expected-error{{member 'get' found in multiple base classes of different types}} + +struct Base { + template<int> int get(); +}; +struct UsingGet : Base { + using Base::get; +}; + +template <> struct std::tuple_size<UsingGet> { + static constexpr size_t value = 1; +}; +template <> struct std::tuple_element<0, UsingGet> { typedef int type; }; + +auto [y] = UsingGet(); diff --git a/test/CXX/dcl.decl/dcl.decomp/p4.cpp b/test/CXX/dcl.decl/dcl.decomp/p4.cpp index c461eb6f54b7..f14c0d02c16e 100644 --- a/test/CXX/dcl.decl/dcl.decomp/p4.cpp +++ b/test/CXX/dcl.decl/dcl.decomp/p4.cpp @@ -20,15 +20,15 @@ namespace NonPublicMembers { int a; // expected-note 2{{declared private here}} }; - struct NonPublic3 : private A {}; // expected-note {{constrained by private inheritance}} + struct NonPublic3 : private A {}; // expected-note {{declared private here}} struct NonPublic4 : NonPublic2 {}; void test() { - auto [a1] = NonPublic1(); // expected-error {{cannot decompose non-public member 'a' of 'NonPublicMembers::NonPublic1'}} - auto [a2] = NonPublic2(); // expected-error {{cannot decompose non-public member 'a' of 'NonPublicMembers::NonPublic2'}} - auto [a3] = NonPublic3(); // expected-error {{cannot decompose members of non-public base class 'A' of 'NonPublic3'}} - auto [a4] = NonPublic4(); // expected-error {{cannot decompose non-public member 'a' of 'NonPublicMembers::NonPublic4'}} + auto [a1] = NonPublic1(); // expected-error {{cannot decompose protected member 'a' of 'NonPublicMembers::NonPublic1'}} + auto [a2] = NonPublic2(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}} + auto [a3] = NonPublic3(); // expected-error {{cannot decompose members of inaccessible base class 'A' of 'NonPublicMembers::NonPublic3'}} + auto [a4] = NonPublic4(); // expected-error {{cannot decompose private member 'a' of 'NonPublicMembers::NonPublic2'}} } } @@ -198,3 +198,44 @@ namespace std_example { same<decltype((x)), const int&> same1; same<decltype((y)), const volatile double&> same2; } + +namespace p0969r0 { + struct A { + int x; + int y; + }; + struct B : private A { // expected-note {{declared private here}} + void test_member() { + auto &[x, y] = *this; + } + friend void test_friend(B); + }; + void test_friend(B b) { + auto &[x, y] = b; + } + void test_external(B b) { + auto &[x, y] = b; // expected-error {{cannot decompose members of inaccessible base class 'p0969r0::A' of 'p0969r0::B'}} + } + + struct C { + int x; + protected: + int y; // expected-note {{declared protected here}} expected-note {{can only access this member on an object of type 'p0969r0::D'}} + void test_member() { + auto &[x, y] = *this; + } + friend void test_friend(struct D); + }; + struct D : C { + static void test_member(D d, C c) { + auto &[x1, y1] = d; + auto &[x2, y2] = c; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}} + } + }; + void test_friend(D d) { + auto &[x, y] = d; + } + void test_external(D d) { + auto &[x, y] = d; // expected-error {{cannot decompose protected member 'y' of 'p0969r0::C'}} + } +} diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp index 51993307cfff..3f2bc569edf6 100644 --- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp +++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp @@ -1,15 +1,30 @@ // RUN: %clang_cc1 -verify %s -std=c++11 +// RUN: %clang_cc1 -verify %s -std=c++17 +// RUN: %clang_cc1 -verify %s -std=c++2a // A function that is explicitly defaulted shall struct A { // -- be a special member function, A(int) = default; // expected-error {{only special member functions may be defaulted}} + A(A) = default; // expected-error {{must pass its first argument by reference}} // -- have the same declared function type as if it had been implicitly // declared void operator=(const A &) = default; // expected-error {{must return 'A &'}} - A(...) = default; // expected-error {{cannot be variadic}} - A(const A &, ...) = default; // expected-error {{cannot be variadic}} + A(...) = default; + A(const A &, ...) = default; + A &operator=(const A&) const = default; + A &operator=(A) const = default; // expected-error {{must be an lvalue refe}} +#if __cplusplus <= 201703L + // expected-error@-5 {{cannot be variadic}} + // expected-error@-5 {{cannot be variadic}} + // expected-error@-5 {{may not have 'const'}} + // expected-error@-5 {{may not have 'const'}} +#else + // expected-warning@-10 {{implicitly deleted}} expected-note@-10 {{declared type does not match the type of an implicit default constructor}} + // expected-warning@-10 {{implicitly deleted}} expected-note@-10 {{declared type does not match the type of an implicit copy constructor}} + // expected-warning@-10 {{implicitly deleted}} expected-note@-10 {{declared type does not match the type of an implicit copy assignment}} +#endif // (except for possibly differing ref-qualifiers A &operator=(A &&) & = default; @@ -23,3 +38,35 @@ struct A { A(double = 0.0) = default; // expected-error {{cannot have default arguments}} A(const A & = 0) = default; // expected-error {{cannot have default arguments}} }; + +struct A2 { + A2(...); + A2(const A2 &, ...); + A2 &operator=(const A2&) const; +}; +A2::A2(...) = default; // expected-error {{cannot be variadic}} +A2::A2(const A2&, ...) = default; // expected-error {{cannot be variadic}} +A2 &A2::operator=(const A2&) const = default; // expected-error {{may not have 'const'}} + +struct B { + B(B&); + B &operator=(B&); +}; +struct C : B { + C(const C&) = default; + C &operator=(const C&) = default; +#if __cplusplus <= 201703L + // expected-error@-3 {{is const, but a member or base requires it to be non-const}} + // expected-error@-3 {{is const, but a member or base requires it to be non-const}} +#else + // expected-warning@-6 {{implicitly deleted}} expected-note@-6 {{type does not match}} + // expected-warning@-6 {{implicitly deleted}} expected-note@-6 {{type does not match}} +#endif +}; + +struct D : B { // expected-note 2{{base class}} + D(const D&); + D &operator=(const D&); +}; +D::D(const D&) = default; // expected-error {{would delete}} expected-error {{is const, but}} +D &D::operator=(const D&) = default; // expected-error {{would delete}} expected-error {{is const, but}} |
