Re: r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are

2018-10-01 Thread David Blaikie via cfe-commits
Excellent, excellent - thanks!

On Mon, Oct 1, 2018 at 10:22 AM Richard Smith  wrote:

> On Mon, 1 Oct 2018, 09:55 David Blaikie via cfe-commits, <
> cfe-commits@lists.llvm.org> wrote:
>
>> Awesome - should/does this mean stateless lambdas can be used in
>> uninitialized contexts?
>>
>> std::set> })> s;
>>
>> Would be kind of neat/handy (so you didn't have to pass in the comparator
>> on construction, etc)
>>
>
> Not quite: that also needs p0315r4, but that's coming in C++20 too.
>
> On Thu, Sep 27, 2018 at 3:48 PM Richard Smith via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Author: rsmith
>>> Date: Thu Sep 27 15:47:04 2018
>>> New Revision: 343279
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=343279=rev
>>> Log:
>>> [cxx2a] P0624R2: Lambdas with no capture-default are
>>> default-constructible and assignable.
>>>
>>> Added:
>>> cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp
>>> Modified:
>>> cfe/trunk/include/clang/AST/DeclCXX.h
>>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> cfe/trunk/lib/AST/DeclCXX.cpp
>>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>>> cfe/trunk/lib/Sema/SemaExpr.cpp
>>> cfe/trunk/test/SemaCXX/cxx17-compat.cpp
>>> cfe/trunk/www/cxx_status.html
>>>
>>> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=343279=343278=343279=diff
>>>
>>> ==
>>> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
>>> +++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 27 15:47:04 2018
>>> @@ -974,10 +974,7 @@ public:
>>>bool needsImplicitDefaultConstructor() const {
>>>  return !data().UserDeclaredConstructor &&
>>> !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
>>> -   // C++14 [expr.prim.lambda]p20:
>>> -   //   The closure type associated with a lambda-expression
>>> has no
>>> -   //   default constructor.
>>> -   !isLambda();
>>> +   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
>>>}
>>>
>>>/// Determine whether this class has any user-declared constructors.
>>> @@ -1167,10 +1164,7 @@ public:
>>> !hasUserDeclaredCopyAssignment() &&
>>> !hasUserDeclaredMoveConstructor() &&
>>> !hasUserDeclaredDestructor() &&
>>> -   // C++1z [expr.prim.lambda]p21: "the closure type has a
>>> deleted copy
>>> -   // assignment operator". The intent is that this counts as a
>>> user
>>> -   // declared copy assignment, but we do not model it that way.
>>> -   !isLambda();
>>> +   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
>>>}
>>>
>>>/// Determine whether we need to eagerly declare a move assignment
>>> @@ -1210,6 +1204,10 @@ public:
>>>/// a template).
>>>bool isGenericLambda() const;
>>>
>>> +  /// Determine whether this lambda should have an implicit default
>>> constructor
>>> +  /// and copy and move assignment operators.
>>> +  bool lambdaIsDefaultConstructibleAndAssignable() const;
>>> +
>>>/// Retrieve the lambda call operator of the closure type
>>>/// if this is a closure type.
>>>CXXMethodDecl *getLambdaCallOperator() const;
>>>
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=343279=343278=343279=diff
>>>
>>> ==
>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 27
>>> 15:47:04 2018
>>> @@ -6633,6 +6633,11 @@ let CategoryName = "Lambda Issue" in {
>>>  InGroup, DefaultIgnore;
>>>def note_deprecated_this_capture : Note<
>>>  "add an explicit capture of 'this' to capture '*this' by
>>> reference">;
>>> +
>>> +  // C++2a default constructible / assignable lambdas.
>>> +  def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
>>> +"%select{default construction|assignment}0 of lambda is
>>> incompatible with "
>>> +"C++ standards before C++2a">, InGroup,
>>> DefaultIgnore;
>>>  }
>>>
>>>  def err_return_in_captured_stmt : Error<
>>>
>>> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=343279=343278=343279=diff
>>>
>>> ==
>>> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
>>> +++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Sep 27 15:47:04 2018
>>> @@ -628,6 +628,24 @@ bool CXXRecordDecl::hasSubobjectAtOffset
>>>return false;
>>>  }
>>>
>>> +bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
>>> +  assert(isLambda() && "not a lambda");
>>> +
>>> +  // C++2a [expr.prim.lambda.capture]p11:
>>> +  //   

Re: r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are

2018-10-01 Thread Richard Smith via cfe-commits
On Mon, 1 Oct 2018, 09:55 David Blaikie via cfe-commits, <
cfe-commits@lists.llvm.org> wrote:

> Awesome - should/does this mean stateless lambdas can be used in
> uninitialized contexts?
>
> std::set })> s;
>
> Would be kind of neat/handy (so you didn't have to pass in the comparator
> on construction, etc)
>

Not quite: that also needs p0315r4, but that's coming in C++20 too.

On Thu, Sep 27, 2018 at 3:48 PM Richard Smith via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Author: rsmith
>> Date: Thu Sep 27 15:47:04 2018
>> New Revision: 343279
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=343279=rev
>> Log:
>> [cxx2a] P0624R2: Lambdas with no capture-default are
>> default-constructible and assignable.
>>
>> Added:
>> cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp
>> Modified:
>> cfe/trunk/include/clang/AST/DeclCXX.h
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/lib/AST/DeclCXX.cpp
>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>> cfe/trunk/lib/Sema/SemaExpr.cpp
>> cfe/trunk/test/SemaCXX/cxx17-compat.cpp
>> cfe/trunk/www/cxx_status.html
>>
>> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=343279=343278=343279=diff
>>
>> ==
>> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
>> +++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 27 15:47:04 2018
>> @@ -974,10 +974,7 @@ public:
>>bool needsImplicitDefaultConstructor() const {
>>  return !data().UserDeclaredConstructor &&
>> !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
>> -   // C++14 [expr.prim.lambda]p20:
>> -   //   The closure type associated with a lambda-expression has
>> no
>> -   //   default constructor.
>> -   !isLambda();
>> +   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
>>}
>>
>>/// Determine whether this class has any user-declared constructors.
>> @@ -1167,10 +1164,7 @@ public:
>> !hasUserDeclaredCopyAssignment() &&
>> !hasUserDeclaredMoveConstructor() &&
>> !hasUserDeclaredDestructor() &&
>> -   // C++1z [expr.prim.lambda]p21: "the closure type has a
>> deleted copy
>> -   // assignment operator". The intent is that this counts as a
>> user
>> -   // declared copy assignment, but we do not model it that way.
>> -   !isLambda();
>> +   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
>>}
>>
>>/// Determine whether we need to eagerly declare a move assignment
>> @@ -1210,6 +1204,10 @@ public:
>>/// a template).
>>bool isGenericLambda() const;
>>
>> +  /// Determine whether this lambda should have an implicit default
>> constructor
>> +  /// and copy and move assignment operators.
>> +  bool lambdaIsDefaultConstructibleAndAssignable() const;
>> +
>>/// Retrieve the lambda call operator of the closure type
>>/// if this is a closure type.
>>CXXMethodDecl *getLambdaCallOperator() const;
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=343279=343278=343279=diff
>>
>> ==
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 27
>> 15:47:04 2018
>> @@ -6633,6 +6633,11 @@ let CategoryName = "Lambda Issue" in {
>>  InGroup, DefaultIgnore;
>>def note_deprecated_this_capture : Note<
>>  "add an explicit capture of 'this' to capture '*this' by reference">;
>> +
>> +  // C++2a default constructible / assignable lambdas.
>> +  def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
>> +"%select{default construction|assignment}0 of lambda is incompatible
>> with "
>> +"C++ standards before C++2a">, InGroup,
>> DefaultIgnore;
>>  }
>>
>>  def err_return_in_captured_stmt : Error<
>>
>> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=343279=343278=343279=diff
>>
>> ==
>> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
>> +++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Sep 27 15:47:04 2018
>> @@ -628,6 +628,24 @@ bool CXXRecordDecl::hasSubobjectAtOffset
>>return false;
>>  }
>>
>> +bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
>> +  assert(isLambda() && "not a lambda");
>> +
>> +  // C++2a [expr.prim.lambda.capture]p11:
>> +  //   The closure type associated with a lambda-expression has no
>> default
>> +  //   constructor if the lambda-expression has a lambda-capture and a
>> +  //   defaulted default constructor otherwise. It has a deleted copy

Re: r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are

2018-10-01 Thread David Blaikie via cfe-commits
Awesome - should/does this mean stateless lambdas can be used in
uninitialized contexts?

std::set
s;

Would be kind of neat/handy (so you didn't have to pass in the comparator
on construction, etc)

On Thu, Sep 27, 2018 at 3:48 PM Richard Smith via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: rsmith
> Date: Thu Sep 27 15:47:04 2018
> New Revision: 343279
>
> URL: http://llvm.org/viewvc/llvm-project?rev=343279=rev
> Log:
> [cxx2a] P0624R2: Lambdas with no capture-default are
> default-constructible and assignable.
>
> Added:
> cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp
> Modified:
> cfe/trunk/include/clang/AST/DeclCXX.h
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/lib/AST/DeclCXX.cpp
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/test/SemaCXX/cxx17-compat.cpp
> cfe/trunk/www/cxx_status.html
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=343279=343278=343279=diff
>
> ==
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 27 15:47:04 2018
> @@ -974,10 +974,7 @@ public:
>bool needsImplicitDefaultConstructor() const {
>  return !data().UserDeclaredConstructor &&
> !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
> -   // C++14 [expr.prim.lambda]p20:
> -   //   The closure type associated with a lambda-expression has
> no
> -   //   default constructor.
> -   !isLambda();
> +   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
>}
>
>/// Determine whether this class has any user-declared constructors.
> @@ -1167,10 +1164,7 @@ public:
> !hasUserDeclaredCopyAssignment() &&
> !hasUserDeclaredMoveConstructor() &&
> !hasUserDeclaredDestructor() &&
> -   // C++1z [expr.prim.lambda]p21: "the closure type has a
> deleted copy
> -   // assignment operator". The intent is that this counts as a
> user
> -   // declared copy assignment, but we do not model it that way.
> -   !isLambda();
> +   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
>}
>
>/// Determine whether we need to eagerly declare a move assignment
> @@ -1210,6 +1204,10 @@ public:
>/// a template).
>bool isGenericLambda() const;
>
> +  /// Determine whether this lambda should have an implicit default
> constructor
> +  /// and copy and move assignment operators.
> +  bool lambdaIsDefaultConstructibleAndAssignable() const;
> +
>/// Retrieve the lambda call operator of the closure type
>/// if this is a closure type.
>CXXMethodDecl *getLambdaCallOperator() const;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=343279=343278=343279=diff
>
> ==
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 27
> 15:47:04 2018
> @@ -6633,6 +6633,11 @@ let CategoryName = "Lambda Issue" in {
>  InGroup, DefaultIgnore;
>def note_deprecated_this_capture : Note<
>  "add an explicit capture of 'this' to capture '*this' by reference">;
> +
> +  // C++2a default constructible / assignable lambdas.
> +  def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
> +"%select{default construction|assignment}0 of lambda is incompatible
> with "
> +"C++ standards before C++2a">, InGroup, DefaultIgnore;
>  }
>
>  def err_return_in_captured_stmt : Error<
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=343279=343278=343279=diff
>
> ==
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Sep 27 15:47:04 2018
> @@ -628,6 +628,24 @@ bool CXXRecordDecl::hasSubobjectAtOffset
>return false;
>  }
>
> +bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
> +  assert(isLambda() && "not a lambda");
> +
> +  // C++2a [expr.prim.lambda.capture]p11:
> +  //   The closure type associated with a lambda-expression has no default
> +  //   constructor if the lambda-expression has a lambda-capture and a
> +  //   defaulted default constructor otherwise. It has a deleted copy
> +  //   assignment operator if the lambda-expression has a lambda-capture
> and
> +  //   defaulted copy and move assignment operators otherwise.
> +  //
> +  // C++17 [expr.prim.lambda]p21:
> +  //   The closure type associated with a lambda-expression has no default
> +  //   constructor and a 

r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are

2018-09-27 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Thu Sep 27 15:47:04 2018
New Revision: 343279

URL: http://llvm.org/viewvc/llvm-project?rev=343279=rev
Log:
[cxx2a] P0624R2: Lambdas with no capture-default are
default-constructible and assignable.

Added:
cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaCXX/cxx17-compat.cpp
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=343279=343278=343279=diff
==
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 27 15:47:04 2018
@@ -974,10 +974,7 @@ public:
   bool needsImplicitDefaultConstructor() const {
 return !data().UserDeclaredConstructor &&
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
-   // C++14 [expr.prim.lambda]p20:
-   //   The closure type associated with a lambda-expression has no
-   //   default constructor.
-   !isLambda();
+   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
   }
 
   /// Determine whether this class has any user-declared constructors.
@@ -1167,10 +1164,7 @@ public:
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
!hasUserDeclaredDestructor() &&
-   // C++1z [expr.prim.lambda]p21: "the closure type has a deleted copy
-   // assignment operator". The intent is that this counts as a user
-   // declared copy assignment, but we do not model it that way.
-   !isLambda();
+   (!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
   }
 
   /// Determine whether we need to eagerly declare a move assignment
@@ -1210,6 +1204,10 @@ public:
   /// a template).
   bool isGenericLambda() const;
 
+  /// Determine whether this lambda should have an implicit default constructor
+  /// and copy and move assignment operators.
+  bool lambdaIsDefaultConstructibleAndAssignable() const;
+
   /// Retrieve the lambda call operator of the closure type
   /// if this is a closure type.
   CXXMethodDecl *getLambdaCallOperator() const;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=343279=343278=343279=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 27 15:47:04 
2018
@@ -6633,6 +6633,11 @@ let CategoryName = "Lambda Issue" in {
 InGroup, DefaultIgnore;
   def note_deprecated_this_capture : Note<
 "add an explicit capture of 'this' to capture '*this' by reference">;
+
+  // C++2a default constructible / assignable lambdas.
+  def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
+"%select{default construction|assignment}0 of lambda is incompatible with "
+"C++ standards before C++2a">, InGroup, DefaultIgnore;
 }
 
 def err_return_in_captured_stmt : Error<

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=343279=343278=343279=diff
==
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Sep 27 15:47:04 2018
@@ -628,6 +628,24 @@ bool CXXRecordDecl::hasSubobjectAtOffset
   return false;
 }
 
+bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
+  assert(isLambda() && "not a lambda");
+
+  // C++2a [expr.prim.lambda.capture]p11:
+  //   The closure type associated with a lambda-expression has no default
+  //   constructor if the lambda-expression has a lambda-capture and a
+  //   defaulted default constructor otherwise. It has a deleted copy
+  //   assignment operator if the lambda-expression has a lambda-capture and
+  //   defaulted copy and move assignment operators otherwise.
+  //
+  // C++17 [expr.prim.lambda]p21:
+  //   The closure type associated with a lambda-expression has no default
+  //   constructor and a deleted copy assignment operator.
+  if (getLambdaCaptureDefault() != LCD_None)
+return false;
+  return getASTContext().getLangOpts().CPlusPlus2a;
+}
+
 void CXXRecordDecl::addedMember(Decl *D) {
   if (!D->isImplicit() &&
   !isa(D) &&

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=343279=343278=343279=diff
==
---