aboutsummaryrefslogtreecommitdiff
path: root/test/CXX/dcl.decl
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/dcl.decl')
-rw-r--r--test/CXX/dcl.decl/dcl.decomp/p3.cpp77
-rw-r--r--test/CXX/dcl.decl/dcl.decomp/p4.cpp51
-rw-r--r--test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp51
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}}