From: Richard Smith Date: Wed, 10 Dec 2014 20:04:48 +0000 (+0000) Subject: DR1891, PR21787: a lambda closure type has no default constructor, rather than X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=851e89831f9cb57e037fe3050f19ae6f82117723;p=clang DR1891, PR21787: a lambda closure type has no default constructor, rather than having a deleted default constructor. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223953 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 062c1527d7..027b41e27d 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -826,7 +826,11 @@ public: /// This value is used for lazy creation of default constructors. bool needsImplicitDefaultConstructor() const { return !data().UserDeclaredConstructor && - !(data().DeclaredSpecialMembers & SMF_DefaultConstructor); + !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) && + // C++14 [expr.prim.lambda]p20: + // The closure type associated with a lambda-expression has no + // default constructor. + !isLambda(); } /// \brief Determine whether this class has any user-declared constructors. diff --git a/test/CXX/drs/dr18xx.cpp b/test/CXX/drs/dr18xx.cpp new file mode 100644 index 0000000000..d81ab82e74 --- /dev/null +++ b/test/CXX/drs/dr18xx.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +#if __cplusplus < 201103L +// expected-no-diagnostics +#endif + +void dr1891() { // dr1891: yes +#if __cplusplus >= 201103L + int n; + auto a = []{}; // expected-note 2{{candidate}} + auto b = [=]{ return n; }; // expected-note 2{{candidate}} + typedef decltype(a) A; + typedef decltype(b) B; + + static_assert(!__has_trivial_constructor(A), ""); + static_assert(!__has_trivial_constructor(B), ""); + + A x; // expected-error {{no matching constructor}} + B y; // expected-error {{no matching constructor}} +#endif +} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp index 35b77896c8..40360e4069 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp @@ -7,10 +7,10 @@ struct MoveOnly { template T &&move(T&); void test_special_member_functions(MoveOnly mo, int i) { - auto lambda1 = [i]() { }; // expected-note 2 {{lambda expression begins here}} + auto lambda1 = [i]() { }; // expected-note {{lambda expression begins here}} expected-note 2{{candidate}} // Default constructor - decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '(lambda}} + decltype(lambda1) lambda2; // expected-error{{no matching constructor}} // Copy assignment operator lambda1 = lambda1; // expected-error{{copy assignment operator is implicitly deleted}} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp index c0fa72ba42..80771d7a22 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify void test_nonaggregate(int i) { - auto lambda = [i]() -> void {}; // expected-note 3{{candidate constructor}} + auto lambda = [i]() -> void {}; // expected-note 2{{candidate constructor}} decltype(lambda) foo = { 1 }; // expected-error{{no matching constructor}} static_assert(!__is_literal(decltype(lambda)), ""); - auto lambda2 = []{}; // expected-note {{lambda}} - decltype(lambda2) bar = {}; // expected-error{{call to implicitly-deleted default constructor}} + auto lambda2 = []{}; // expected-note 2{{candidate constructor}} + decltype(lambda2) bar = {}; // expected-error{{no matching constructor}} static_assert(!__is_literal(decltype(lambda2)), ""); }