aboutsummaryrefslogtreecommitdiff
path: root/test/CXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/class.access/class.friend/p1.cpp5
-rw-r--r--test/CXX/class.access/class.friend/p11.cpp11
-rw-r--r--test/CXX/class.access/class.friend/p3-cxx0x.cpp15
-rw-r--r--test/CXX/class.derived/class.abstract/p16.cpp4
-rw-r--r--test/CXX/class/class.friend/p1.cpp4
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp29
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp27
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp13
-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
-rw-r--r--test/CXX/drs/dr13xx.cpp6
-rw-r--r--test/CXX/drs/dr1xx.cpp5
-rw-r--r--test/CXX/drs/dr22xx.cpp11
-rw-r--r--test/CXX/drs/dr2xx.cpp4
-rw-r--r--test/CXX/drs/dr5xx.cpp8
-rw-r--r--test/CXX/drs/dr6xx.cpp54
-rw-r--r--test/CXX/expr/expr.const/p6.cpp39
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp4
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp8
-rw-r--r--test/CXX/special/class.copy/p12-0x.cpp2
-rw-r--r--test/CXX/special/class.copy/p23-cxx11.cpp2
-rw-r--r--test/CXX/special/class.ctor/p5-0x.cpp2
-rw-r--r--test/CXX/special/class.dtor/p5-0x.cpp2
-rw-r--r--test/CXX/special/class.temporary/p6.cpp240
-rw-r--r--test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp61
-rw-r--r--test/CXX/stmt.stmt/stmt.select/p3.cpp9
-rw-r--r--test/CXX/temp/temp.param/p2.cpp9
-rw-r--r--test/CXX/temp/temp.param/p3.cpp4
-rw-r--r--test/CXX/temp/temp.spec/temp.inst/p7.cpp12
30 files changed, 687 insertions, 82 deletions
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index b6a1bcdab926..b335b0a8c884 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -11,12 +11,11 @@
// friends members of the befriending class.
struct S { static void f(); }; // expected-note 2 {{'S' declared here}}
-S* g() { return 0; }
+S* g() { return 0; } // expected-note 2 {{'g' declared here}}
struct X {
friend struct S;
- friend S* g(); // expected-note 2 {{'g' declared here}}
- // FIXME: The above two notes would be better attached to line 11.
+ friend S* g();
};
void test1() {
diff --git a/test/CXX/class.access/class.friend/p11.cpp b/test/CXX/class.access/class.friend/p11.cpp
index 0d25c59c9b62..0deead19a0fb 100644
--- a/test/CXX/class.access/class.friend/p11.cpp
+++ b/test/CXX/class.access/class.friend/p11.cpp
@@ -19,17 +19,16 @@ namespace test1 {
}
namespace test2 {
- void bar(); // expected-note {{'::test2::bar' declared here}}
+ void bar(); // expected-note 3{{'::test2::bar' declared here}}
- void foo() { // expected-note {{'::test2::foo' declared here}}
+ void foo() { // expected-note 2{{'::test2::foo' declared here}}
struct S1 {
friend void foo(); // expected-error {{no matching function 'foo' found in local scope; did you mean '::test2::foo'?}}
};
void foo(); // expected-note {{local declaration nearly matches}}
struct S2 {
- friend void foo(); // expected-note{{'::test2::foo' declared here}}
- // TODO: the above note should go on line 24
+ friend void foo();
};
{
@@ -47,8 +46,6 @@ namespace test2 {
struct S4 {
friend void bar(); // expected-error {{no matching function 'bar' found in local scope; did you mean '::test2::bar'?}}
- // expected-note@-1 {{'::test2::bar' declared here}}
- // TODO: the above note should go on line 22
};
{ void bar(); }
@@ -81,8 +78,6 @@ namespace test2 {
struct S9 {
struct Inner {
friend void baz(); // expected-error {{no matching function 'baz' found in local scope; did you mean 'bar'?}}
- // expected-note@-1 {{'::test2::bar' declared here}}
- // TODO: the above note should go on line 22
};
};
diff --git a/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
index 5a1ab49321d0..9aabdbe540a6 100644
--- a/test/CXX/class.access/class.friend/p3-cxx0x.cpp
+++ b/test/CXX/class.access/class.friend/p3-cxx0x.cpp
@@ -52,14 +52,25 @@ struct {
// Ill-formed
int friend; // expected-error {{'friend' must appear first in a non-function declaration}}
unsigned friend int; // expected-error {{'friend' must appear first in a non-function declaration}}
- const volatile friend int; // expected-error {{'friend' must appear first in a non-function declaration}}
+ const volatile friend int; // expected-error {{'friend' must appear first in a non-function declaration}} \
+ // expected-error {{'const' is invalid in friend declarations}} \
+ // expected-error {{'volatile' is invalid in friend declarations}}
int
friend; // expected-error {{'friend' must appear first in a non-function declaration}}
+ friend const int; // expected-error {{'const' is invalid in friend declarations}}
+ friend volatile int; // expected-error {{'volatile' is invalid in friend declarations}}
+ template <typename T> friend const class X; // expected-error {{'const' is invalid in friend declarations}}
+ // C++ doesn't have restrict and _Atomic, but they're both the same sort
+ // of qualifier.
+ typedef int *PtrToInt;
+ friend __restrict PtrToInt; // expected-error {{'restrict' is invalid in friend declarations}} \
+ // expected-error {{restrict requires a pointer or reference}}
+ friend _Atomic int; // expected-error {{'_Atomic' is invalid in friend declarations}}
// OK
int friend foo(void);
+ const int friend foo2(void);
friend int;
- friend const volatile int;
friend
float;
diff --git a/test/CXX/class.derived/class.abstract/p16.cpp b/test/CXX/class.derived/class.abstract/p16.cpp
index 80396a96d9ec..fe31b7321bd0 100644
--- a/test/CXX/class.derived/class.abstract/p16.cpp
+++ b/test/CXX/class.derived/class.abstract/p16.cpp
@@ -44,8 +44,8 @@ struct G : D {};
// expected-error@-3 {{deleted function 'operator=' cannot override a non-deleted function}}
// expected-note@-4 {{while declaring the implicit move assignment operator for 'G'}}
// expected-note@-5 {{move assignment operator of 'G' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
-struct H : D {
- H &operator=(H&&) = default;
+struct H : D { // expected-note {{deleted because base class 'D' has an inaccessible move assignment}}
+ H &operator=(H&&) = default; // expected-warning {{implicitly deleted}}
// expected-error@-1 {{deleted function 'operator=' cannot override a non-deleted function}}
// expected-note@-3 {{move assignment operator of 'H' is implicitly deleted because base class 'D' has an inaccessible move assignment operator}}
~H();
diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp
index 037fc3dadb96..08498c07330e 100644
--- a/test/CXX/class/class.friend/p1.cpp
+++ b/test/CXX/class/class.friend/p1.cpp
@@ -51,9 +51,9 @@ class A {
friend class A::AInner; // this is okay as an extension
friend class AInner; // okay, refers to ::AInner
- friend void Derived::missing_member(); // expected-error {{no function named 'missing_member' with type 'void ()' was found in the specified scope}}
+ friend void Derived::missing_member(); // expected-error {{friend declaration of 'missing_member' does not match any declaration in 'Derived'}}
- friend void Derived::base_member(); // expected-error {{no function named 'base_member' with type 'void ()' was found in the specified scope}}
+ friend void Derived::base_member(); // expected-error {{friend declaration of 'base_member' does not match any declaration in 'Derived'}}
friend int Base::typedeffed_member(); // okay: should look through typedef
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
index 49c418a68764..43de9343bd4d 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
@@ -32,6 +32,35 @@ void g() {
// OK, warning suppressed.
(void)fp();
}
+
+namespace PR31526 {
+typedef E (*fp1)();
+typedef S (*fp2)();
+
+typedef S S_alias;
+typedef S_alias (*fp3)();
+
+typedef fp2 fp2_alias;
+
+void f() {
+ fp1 one;
+ fp2 two;
+ fp3 three;
+ fp2_alias four;
+
+ one(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ two(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ three(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ four(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // These are all okay because of the explicit cast to void.
+ (void)one();
+ (void)two();
+ (void)three();
+ (void)four();
+}
+} // namespace PR31526
+
#ifdef EXT
// expected-warning@4 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@8 {{use of the 'nodiscard' attribute is a C++17 extension}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index 3986dc9565c3..ffc408cddbf4 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s
-// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions -Werror=c++2a-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y -Werror=c++2a-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++2a -DCXX1Y -DCXX2A %s
namespace N {
typedef char C;
@@ -78,7 +79,12 @@ struct T2 {
};
struct T3 {
constexpr T3 &operator=(const T3&) const = default;
- // expected-error@-1 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
+#ifndef CXX2A
+ // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
+#else
+ // expected-warning@-4 {{explicitly defaulted copy assignment operator is implicitly deleted}}
+ // expected-note@-5 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
+#endif
};
#endif
struct U {
@@ -129,9 +135,22 @@ constexpr int DisallowedStmtsCXX1Y_2() {
x:
return 0;
}
+constexpr int DisallowedStmtsCXX1Y_2_1() {
+ try {
+ return 0;
+ } catch (...) {
+ merp: goto merp; // expected-error {{statement not allowed in constexpr function}}
+ }
+}
constexpr int DisallowedStmtsCXX1Y_3() {
// - a try-block,
- try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}}
+ try {} catch (...) {}
+#ifndef CXX2A
+ // expected-error@-2 {{use of this statement in a constexpr function is a C++2a extension}}
+#ifndef CXX1Y
+ // expected-error@-4 {{use of this statement in a constexpr function is a C++14 extension}}
+#endif
+#endif
return 0;
}
constexpr int DisallowedStmtsCXX1Y_4() {
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index 9c1cab54b617..54aabe6ef376 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions %s
-// RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y %s
+// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions -Werror=c++2a-extensions %s
+// RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y -Werror=c++2a-extensions %s
+// RUN: %clang_cc1 -verify -std=c++2a -fcxx-exceptions -DCXX1Y -DCXX2A %s
namespace N {
typedef char C;
@@ -49,8 +50,14 @@ namespace IndirectVBase {
// - its function-body shall not be a function-try-block;
struct U {
constexpr U()
- try // expected-error {{function try block not allowed in constexpr constructor}}
+ try
+#ifndef CXX2A
+ // expected-error@-2 {{function try block in constexpr constructor is a C++2a extension}}
+#endif
: u() {
+#ifndef CXX1Y
+ // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}
+#endif
} catch (...) {
throw;
}
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}}
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
index f193c8e024fb..208ab8a03b0a 100644
--- a/test/CXX/drs/dr13xx.cpp
+++ b/test/CXX/drs/dr13xx.cpp
@@ -226,10 +226,10 @@ namespace dr1330 { // dr1330: 4 c++11
#endif
void f(D &d) { d = d; } // ok
- // FIXME: In C++11 onwards, we should also note the declaration of 'e' as the
- // line that triggers the use of E::E()'s exception specification.
struct E : C<int> {}; // expected-note {{in instantiation of}}
- E e;
+#if __cplusplus >= 201103L
+ E e; // expected-note {{needed here}}
+#endif
}
namespace dr1346 { // dr1346: 3.5
diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index a92501128b5f..26ab67d54d31 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/test/CXX/drs/dr1xx.cpp
@@ -401,13 +401,12 @@ namespace dr136 { // dr136: 3.4
extern "C" void k(int, int, int, int); // expected-note {{previous declaration is here}}
namespace NSA {
struct A {
- friend void dr136::k(int, int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}} \
- // expected-note {{previous declaration is here}}
+ friend void dr136::k(int, int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}}
};
}
namespace NSB {
struct A {
- friend void dr136::k(int, int, int = 0, int); // expected-error {{friend declaration specifying a default argument must be the only declaration}}
+ friend void dr136::k(int, int, int = 0, int); // expected-error {{missing default argument on parameter}}
};
}
struct B {
diff --git a/test/CXX/drs/dr22xx.cpp b/test/CXX/drs/dr22xx.cpp
index 021707d876b7..70a26db757c3 100644
--- a/test/CXX/drs/dr22xx.cpp
+++ b/test/CXX/drs/dr22xx.cpp
@@ -15,3 +15,14 @@ struct AnonBitfieldQualifiers {
const volatile unsigned i3 : 1;
};
}
+
+#if __cplusplus >= 201103L
+namespace dr2211 { // dr2211: 8
+void f() {
+ int a;
+ auto f = [a](int a) { (void)a; }; // expected-error {{a lambda parameter cannot shadow an explicitly captured entity}}
+ // expected-note@-1{{variable 'a' is explicitly captured here}}
+ auto g = [=](int a) { (void)a; };
+}
+}
+#endif
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index 4e745ef2f4d0..b69c014b587f 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -718,7 +718,7 @@ namespace dr261 { // dr261: no
A() {}
};
- // FIXME: These are ill-formed, with a required diagnostic, for the same
+ // FIXME: This is ill-formed, with a required diagnostic, for the same
// reason.
struct B {
inline void operator delete(void*) __attribute__((unused));
@@ -726,7 +726,7 @@ namespace dr261 { // dr261: no
};
struct C {
inline void operator delete(void*) __attribute__((unused));
- virtual ~C() {}
+ virtual ~C() {} // expected-warning {{'operator delete' was marked unused but was used}}
};
struct D {
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
index c20a873fc1c7..2099612e23f3 100644
--- a/test/CXX/drs/dr5xx.cpp
+++ b/test/CXX/drs/dr5xx.cpp
@@ -740,17 +740,17 @@ namespace dr573 { // dr573: no
namespace dr574 { // dr574: yes
struct A {
- A &operator=(const A&) const; // expected-note {{does not match because it is const}}
+ A &operator=(const A&) const; // expected-note {{different qualifiers}}
};
struct B {
- B &operator=(const B&) volatile; // expected-note {{nearly matches}}
+ B &operator=(const B&) volatile; // expected-note {{different qualifiers}}
};
#if __cplusplus >= 201103L
struct C {
- C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}}
+ C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{candidate}} expected-note {{here}}
};
struct D {
- D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}}
+ D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{candidate}} expected-note {{here}}
};
void test(C c, D d) {
c = c;
diff --git a/test/CXX/drs/dr6xx.cpp b/test/CXX/drs/dr6xx.cpp
index c3c867b7a54d..b4247b22607d 100644
--- a/test/CXX/drs/dr6xx.cpp
+++ b/test/CXX/drs/dr6xx.cpp
@@ -492,7 +492,13 @@ namespace dr647 { // dr647: yes
struct C {
constexpr C(NonLiteral);
constexpr C(NonLiteral, int) {} // expected-error {{not a literal type}}
- constexpr C() try {} catch (...) {} // expected-error {{function try block}}
+ constexpr C() try {} catch (...) {}
+#if __cplusplus <= 201703L
+ // expected-error@-2 {{function try block in constexpr constructor is a C++2a extension}}
+#endif
+#if __cplusplus < 201402L
+ // expected-error@-5 {{use of this statement in a constexpr constructor is a C++14 extension}}
+#endif
};
struct D {
@@ -757,8 +763,8 @@ namespace dr666 { // dr666: yes
#if __cplusplus >= 201103L
namespace dr667 { // dr667: yes
struct A {
- A() = default;
- int &r;
+ A() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}}
+ int &r; // expected-note {{because field 'r' of reference type 'int &' would not be initialized}}
};
static_assert(!__is_trivially_constructible(A), "");
@@ -833,7 +839,7 @@ namespace dr673 { // dr673: yes
F *f; // expected-error {{unknown type name}}
}
-namespace dr674 { // dr674: no
+namespace dr674 { // dr674: 8
template<typename T> int f(T);
int g(int);
@@ -843,22 +849,50 @@ namespace dr674 { // dr674: no
template<typename T> int h(T);
class X {
- // FIXME: This should deduce dr674::f<int>.
- friend int dr674::f(int); // expected-error {{does not match any}}
+ friend int dr674::f(int);
friend int dr674::g(int);
friend int dr674::h<>(int);
- int n;
+ int n; // expected-note 2{{private}}
};
template<typename T> int f(T) { return X().n; }
int g(int) { return X().n; }
- template<typename T> int g(T) { return X().n; }
- int h(int) { return X().n; }
+ template<typename T> int g(T) { return X().n; } // expected-error {{private}}
+ int h(int) { return X().n; } // expected-error {{private}}
template<typename T> int h(T) { return X().n; }
template int f(int);
- template int g(int);
+ template int g(int); // expected-note {{in instantiation of}}
template int h(int);
+
+
+ struct Y {
+ template<typename T> int f(T);
+
+ int g(int);
+ template<typename T> int g(T);
+
+ int h(int);
+ template<typename T> int h(T);
+ };
+
+ class Z {
+ friend int Y::f(int);
+ friend int Y::g(int);
+ friend int Y::h<>(int);
+ int n; // expected-note 2{{private}}
+ };
+
+ template<typename T> int Y::f(T) { return Z().n; }
+ int Y::g(int) { return Z().n; }
+ template<typename T> int Y::g(T) { return Z().n; } // expected-error {{private}}
+ int Y::h(int) { return Z().n; } // expected-error {{private}}
+ template<typename T> int Y::h(T) { return Z().n; }
+
+ // FIXME: Should the <> be required here?
+ template int Y::f<>(int);
+ template int Y::g<>(int); // expected-note {{in instantiation of}}
+ template int Y::h<>(int);
}
namespace dr675 { // dr675: dup 739
diff --git a/test/CXX/expr/expr.const/p6.cpp b/test/CXX/expr/expr.const/p6.cpp
new file mode 100644
index 000000000000..a8fc7754e7db
--- /dev/null
+++ b/test/CXX/expr/expr.const/p6.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+
+template<typename T> int not_constexpr() { return T::error; }
+template<typename T> constexpr int is_constexpr() { return T::error; } // expected-error {{'::'}}
+
+template<typename T> int not_constexpr_var = T::error;
+template<typename T> constexpr int is_constexpr_var = T::error; // expected-error {{'::'}}
+template<typename T> const int is_const_var = T::error; // expected-error {{'::'}}
+template<typename T> const volatile int is_const_volatile_var = T::error;
+template<typename T> T is_dependent_var = T::error; // expected-error {{'::'}}
+template<typename T> int &is_reference_var = T::error; // expected-error {{'::'}}
+template<typename T> float is_float_var = T::error;
+
+void test() {
+ // Do not instantiate functions referenced in unevaluated operands...
+ (void)sizeof(not_constexpr<long>());
+ (void)sizeof(is_constexpr<long>());
+ (void)sizeof(not_constexpr_var<long>);
+ (void)sizeof(is_constexpr_var<long>);
+ (void)sizeof(is_const_var<long>);
+ (void)sizeof(is_const_volatile_var<long>);
+ (void)sizeof(is_dependent_var<long>);
+ (void)sizeof(is_dependent_var<const long>);
+ (void)sizeof(is_reference_var<long>);
+ (void)sizeof(is_float_var<long>);
+
+ // ... but do if they are potentially constant evaluated, and refer to
+ // constexpr functions or to variables usable in constant expressions.
+ (void)sizeof(int{not_constexpr<int>()});
+ (void)sizeof(int{is_constexpr<int>()}); // expected-note {{instantiation of}}
+ (void)sizeof(int{not_constexpr_var<int>});
+ (void)sizeof(int{is_constexpr_var<int>}); // expected-note {{instantiation of}}
+ (void)sizeof(int{is_const_var<int>}); // expected-note {{instantiation of}}
+ (void)sizeof(int{is_const_volatile_var<int>});
+ (void)sizeof(int{is_dependent_var<int>});
+ (void)sizeof(int{is_dependent_var<const int>}); // expected-note {{instantiation of}}
+ (void)sizeof(int{is_reference_var<int>}); // expected-note {{instantiation of}}
+ (void)sizeof(int{is_float_var<int>}); // expected-error {{cannot be narrowed}} expected-note {{cast}}
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
index 551c100ff7af..7fc86e810927 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
@@ -15,8 +15,8 @@ public:
void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) {
(void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}}
- (void)[=] {
- ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
+ (void)[=] { // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}}
+ ncr.foo();
}();
[nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
index 31213c9ebc33..2bb75df7ac6a 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
@@ -88,8 +88,8 @@ namespace p2 {
template<typename R, typename T>
void odr_used2(R &r, Boom<T> boom) {
const std::type_info &ti
- = typeid([=,&r] () -> R& {
- boom.tickle(); // expected-note{{in instantiation of member function}}
+ = typeid([=,&r] () -> R& { // expected-note{{in instantiation of member function 'p2::Boom<float>::Boom' requested here}}
+ boom.tickle();
return r;
}());
}
@@ -139,11 +139,11 @@ namespace NonLocalLambdaInstantation {
}
template<typename T>
- struct X2 {
+ struct X2 { // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantation::X2<int *>::x'}}
int x = []{ return T(); }(); // expected-error{{cannot initialize a member subobject of type 'int' with an rvalue of type 'int *'}}
};
X2<int> x2i;
X2<float> x2f;
- X2<int*> x2ip; // expected-note{{in instantiation of default member initializer 'NonLocalLambdaInstantation::X2<int *>::x'}}
+ X2<int*> x2ip; // expected-note {{in evaluation of exception spec}}
}
diff --git a/test/CXX/special/class.copy/p12-0x.cpp b/test/CXX/special/class.copy/p12-0x.cpp
index 1b23b5a4b179..a0ef49d9b64d 100644
--- a/test/CXX/special/class.copy/p12-0x.cpp
+++ b/test/CXX/special/class.copy/p12-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-defaulted-function-deleted
// expected-no-diagnostics
diff --git a/test/CXX/special/class.copy/p23-cxx11.cpp b/test/CXX/special/class.copy/p23-cxx11.cpp
index ac21cc61a2c5..0b9652b50fcf 100644
--- a/test/CXX/special/class.copy/p23-cxx11.cpp
+++ b/test/CXX/special/class.copy/p23-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify %s -std=c++11
+// RUN: %clang_cc1 -verify %s -std=c++11 -Wno-defaulted-function-deleted
struct Trivial {};
diff --git a/test/CXX/special/class.ctor/p5-0x.cpp b/test/CXX/special/class.ctor/p5-0x.cpp
index 061a3d1f0738..5fa61008e8b7 100644
--- a/test/CXX/special/class.ctor/p5-0x.cpp
+++ b/test/CXX/special/class.ctor/p5-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-defaulted-function-deleted
struct DefaultedDefCtor1 {};
struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; };
diff --git a/test/CXX/special/class.dtor/p5-0x.cpp b/test/CXX/special/class.dtor/p5-0x.cpp
index 595784f0d5f9..f69baca53bf3 100644
--- a/test/CXX/special/class.dtor/p5-0x.cpp
+++ b/test/CXX/special/class.dtor/p5-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: %clang_cc1 -verify -std=c++11 %s -Wno-defaulted-function-deleted
struct NonTrivDtor {
~NonTrivDtor();
diff --git a/test/CXX/special/class.temporary/p6.cpp b/test/CXX/special/class.temporary/p6.cpp
new file mode 100644
index 000000000000..077385fb7aaa
--- /dev/null
+++ b/test/CXX/special/class.temporary/p6.cpp
@@ -0,0 +1,240 @@
+// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor'
+
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+
+ template <class E>
+ struct initializer_list {
+ const E *begin;
+ size_t size;
+ initializer_list() : begin(nullptr), size(0) {}
+ };
+}
+
+void then();
+
+struct dtor {
+ ~dtor();
+};
+
+dtor ctor();
+
+auto &&lambda = [a = {ctor()}] {};
+// CHECK-LABEL: define
+// CHECK: call {{.*}}ctor
+// CHECK: call {{.*}}atexit{{.*}}global_array_dtor
+
+// CHECK-LABEL: define{{.*}}global_array_dtor
+// CHECK: call {{.*}}dtor
+
+// [lifetime extension occurs if the object was obtained by]
+// -- a temporary materialization conversion
+// CHECK-LABEL: ref_binding
+void ref_binding() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = ctor();
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+
+// -- ( expression )
+// CHECK-LABEL: parens
+void parens() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = ctor();
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+
+// -- subscripting of an array
+// CHECK-LABEL: array_subscript_1
+void array_subscript_1() {
+ using T = dtor[1];
+ // CHECK: call {{.*}}ctor
+ auto &&x = T{ctor()}[0];
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: array_subscript_2
+void array_subscript_2() {
+ using T = dtor[1];
+ // CHECK: call {{.*}}ctor
+ auto &&x = ((dtor*)T{ctor()})[0];
+ // CHECK: call {{.*}}dtor
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: }
+}
+
+struct with_member { dtor d; ~with_member(); };
+struct with_ref_member { dtor &&d; ~with_ref_member(); };
+
+// -- a class member access using the . operator [...]
+// CHECK-LABEL: member_access_1
+void member_access_1() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = with_member{ctor()}.d;
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}with_member
+ // CHECK: }
+}
+// CHECK-LABEL: member_access_2
+void member_access_2() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = with_ref_member{ctor()}.d;
+ // CHECK: call {{.*}}with_ref_member
+ // CHECK: call {{.*}}dtor
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: }
+}
+// CHECK-LABEL: member_access_3
+void member_access_3() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = (&(const with_member&)with_member{ctor()})->d;
+ // CHECK: call {{.*}}with_member
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: }
+}
+
+// -- a pointer-to-member operation using the .* operator [...]
+// CHECK-LABEL: member_ptr_access_1
+void member_ptr_access_1() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = with_member{ctor()}.*&with_member::d;
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}with_member
+ // CHECK: }
+}
+// CHECK-LABEL: member_ptr_access_2
+void member_ptr_access_2() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = (&(const with_member&)with_member{ctor()})->*&with_member::d;
+ // CHECK: call {{.*}}with_member
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: }
+}
+
+// -- a [named] cast [...]
+// CHECK-LABEL: static_cast
+void test_static_cast() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = static_cast<dtor&&>(ctor());
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: const_cast
+void test_const_cast() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = const_cast<dtor&&>(ctor());
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: reinterpret_cast
+void test_reinterpret_cast() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = reinterpret_cast<dtor&&>(static_cast<dtor&&>(ctor()));
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: dynamic_cast
+void test_dynamic_cast() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = dynamic_cast<dtor&&>(ctor());
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+
+// -- [explicit cast notation is defined in terms of the above]
+// CHECK-LABEL: c_style_cast
+void c_style_cast() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = (dtor&&)ctor();
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: function_style_cast
+void function_style_cast() {
+ // CHECK: call {{.*}}ctor
+ using R = dtor&&;
+ auto &&x = R(ctor());
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+
+// -- a conditional operator
+// CHECK-LABEL: conditional
+void conditional(bool b) {
+ // CHECK: call {{.*}}ctor
+ // CHECK: call {{.*}}ctor
+ auto &&x = b ? (dtor&&)ctor() : (dtor&&)ctor();
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+
+// -- a comma expression
+// CHECK-LABEL: comma
+void comma() {
+ // CHECK: call {{.*}}ctor
+ auto &&x = (true, (dtor&&)ctor());
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+
+
+// This applies recursively: if an object is lifetime-extended and contains a
+// reference, the referent is also extended.
+// CHECK-LABEL: init_capture_ref
+void init_capture_ref() {
+ // CHECK: call {{.*}}ctor
+ auto x = [&a = (const dtor&)ctor()] {};
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: init_capture_ref_indirect
+void init_capture_ref_indirect() {
+ // CHECK: call {{.*}}ctor
+ auto x = [&a = (const dtor&)ctor()] {};
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
+// CHECK-LABEL: init_capture_init_list
+void init_capture_init_list() {
+ // CHECK: call {{.*}}ctor
+ auto x = [a = {ctor()}] {};
+ // CHECK: call {{.*}}then
+ then();
+ // CHECK: call {{.*}}dtor
+ // CHECK: }
+}
diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
index 34202494c0d8..f42fc9b6e5aa 100644
--- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
+++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
@@ -108,7 +108,7 @@ void g() {
extern int incomplete[];
for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}}
;
- extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}}
+ extern struct Incomplete also_incomplete[2]; // expected-note 2{{forward declaration}}
for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}}
;
@@ -150,9 +150,9 @@ void g() {
struct NoEnd {
null_t begin();
};
- for (auto u : NoBegin()) { // expected-error {{range type 'NoBegin' has 'end' member but no 'begin' member}}
+ for (auto u : NoBegin()) { // expected-error {{no viable 'begin' function available}}
}
- for (auto u : NoEnd()) { // expected-error {{range type 'NoEnd' has 'begin' member but no 'end' member}}
+ for (auto u : NoEnd()) { // expected-error {{no viable 'end' function available}}
}
struct NoIncr {
@@ -271,3 +271,58 @@ namespace rdar13712739 {
template void foo(const int&); // expected-note{{in instantiation of function template specialization}}
}
+
+namespace p0962r1 {
+ namespace NA {
+ struct A {
+ void begin();
+ };
+ int *begin(A);
+ int *end(A);
+ }
+
+ namespace NB {
+ struct B {
+ void end();
+ };
+ int *begin(B);
+ int *end(B);
+ }
+
+ namespace NC {
+ struct C {
+ void begin();
+ };
+ int *begin(C);
+ }
+
+ namespace ND {
+ struct D {
+ void end();
+ };
+ int *end(D);
+ }
+
+ namespace NE {
+ struct E {
+ void begin(); // expected-note {{member is not a candidate because range type 'p0962r1::NE::E' has no 'end' member}}
+ };
+ int *end(E);
+ }
+
+ namespace NF {
+ struct F {
+ void end(); // expected-note {{member is not a candidate because range type 'p0962r1::NF::F' has no 'begin' member}}
+ };
+ int *begin(F);
+ }
+
+ void use(NA::A a, NB::B b, NC::C c, ND::D d, NE::E e, NF::F f) {
+ for (auto x : a) {}
+ for (auto x : b) {}
+ for (auto x : c) {} // expected-error {{no viable 'end' function}}
+ for (auto x : d) {} // expected-error {{no viable 'begin' function}}
+ for (auto x : e) {} // expected-error {{no viable 'begin' function}}
+ for (auto x : f) {} // expected-error {{no viable 'end' function}}
+ }
+}
diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp
index 7a6a408ec955..4804cc559d00 100644
--- a/test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -std=c++1z -Wc++14-compat -verify %s -DCPP17
int f();
@@ -71,7 +71,6 @@ void whileInitStatement() {
// last loop above. It would be nice to remove this.
void whileInitStatement2() {
while (; false) {} // expected-error {{expected expression}}
- // expected-warning@-1 {{expression result unused}}
- // expected-error@-2 {{expected ';' after expression}}
- // expected-error@-3 {{expected expression}}
+ // expected-error@-1 {{expected ';' after expression}}
+ // expected-error@-2 {{expected expression}}
}
diff --git a/test/CXX/temp/temp.param/p2.cpp b/test/CXX/temp/temp.param/p2.cpp
index 656bd26ff08d..c70b1d354f7c 100644
--- a/test/CXX/temp/temp.param/p2.cpp
+++ b/test/CXX/temp/temp.param/p2.cpp
@@ -8,14 +8,17 @@
template<class T> struct X;
template<typename T> struct X;
-// typename followed by aqualified-id denotes the type in a non-type
+// typename followed by a qualified-id denotes the type in a non-type
// parameter-declaration.
template<typename T, typename T::type Value> struct Y0;
template<typename T, typename X<T>::type Value> struct Y1;
+template<typename T typename U> struct Y2; // expected-error{{expected ',' or '>'}}
+template<typename T U> struct Y3; // expected-error{{expected a qualified name after 'typename'}} expected-error{{expected ',' or '>'}}
+template<typedef T typename U> struct Y4; // expected-error{{expected template parameter}} expected-note {{did you mean to use 'typename'?}} expected-error{{expected ',' or '>'}}
// A storage class shall not be specified in a template-parameter declaration.
template<static int Value> struct Z; //expected-error{{invalid declaration specifier}}
-template<typedef int Value> struct Z0; //expected-error{{expected template parameter}} expected-error{{expected identifier}} expected-error{{extraneous 'template<>' in declaration of struct 'Z0'}} expected-note{{did you mean to use 'typename'?}}
+template<typedef int Value> struct Z0; //expected-error{{invalid declaration specifier}}
template<extern inline int Value> struct Z1; //expected-error2{{invalid declaration specifier}}
template<virtual int Value> struct Z2; //expected-error{{invalid declaration specifier}}
template<explicit int Value> struct Z3; //expected-error{{invalid declaration specifier}}
@@ -43,6 +46,6 @@ template<auto> struct Z13; // OK
// Make sure that we properly disambiguate non-type template parameters that
// start with 'class'.
class X1 { };
-template<class X1 *xptr> struct Y2 { };
+template<class X1 *xptr> struct X2 { };
// FIXME: add the example from p2
diff --git a/test/CXX/temp/temp.param/p3.cpp b/test/CXX/temp/temp.param/p3.cpp
index c3c93396cb13..f709630504cd 100644
--- a/test/CXX/temp/temp.param/p3.cpp
+++ b/test/CXX/temp/temp.param/p3.cpp
@@ -16,7 +16,7 @@ template<template<class T> class Y> struct X1 {
// [Note: because of the name lookup rules, a template-parameter that
// could be interpreted as either a non-type template-parameter or a
// type-parameter (because its identifier is the name of an already
-// existing class) is taken as a type-parameter. For example,
+// existing class) is taken as a type-parameter. For example,
class T { /* ... */ }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
#if __cplusplus >= 201103L // C++11 or later
// expected-note@-2 {{candidate constructor (the implicit move constructor) not viable}}
@@ -27,7 +27,7 @@ int i;
template<class T, T i> struct X2 {
void f(T t)
{
- T t1 = i; //template-parameters T and i
+ T t1 = i; // template-parameters T and i
::T t2 = ::i; // global namespace members T and i \
// expected-error{{no viable conversion}}
}
diff --git a/test/CXX/temp/temp.spec/temp.inst/p7.cpp b/test/CXX/temp/temp.spec/temp.inst/p7.cpp
new file mode 100644
index 000000000000..5145dafdc5b4
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.inst/p7.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -verify -std=c++17 %s
+
+template<typename T> constexpr int f() { return T::value; } // expected-error {{'::'}}
+template<bool B, typename T> void g(decltype(B ? f<T>() : 0));
+template<bool B, typename T> void g(...);
+template<bool B, typename T> void h(decltype(int{B ? f<T>() : 0})); // expected-note {{instantiation of}}
+template<bool B, typename T> void h(...);
+void x() {
+ g<false, int>(0); // ok
+ g<true, int>(0); // ok
+ h<false, int>(0); // expected-note {{while substituting}}
+}