r276514 - [cxx1z-constexpr-lambda] Make a lambda's closure type eligible as a literal-type in C++1z

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed May 16 17:39:01 PDT 2018


On 17 February 2017 at 18:03, Richard Smith <richard at metafoo.co.uk> wrote:

> On 22 July 2016 at 21:05, Faisal Vali via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: faisalv
>> Date: Fri Jul 22 23:05:19 2016
>> New Revision: 276514
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=276514&view=rev
>> Log:
>> [cxx1z-constexpr-lambda] Make a lambda's closure type eligible as a
>> literal-type in C++1z
>>
>>
>> Additionally, for pre-C++1z, instead of forbidding a lambda's closure
>> type from being a literal type through circumlocutorily setting
>> HasNonLiteralTypeFieldsOrBases falsely to true -- handle lambda's more
>> directly in CXXRecordDecl::isLiteral().
>>
>> One additional small step towards implementing constexpr-lambdas.
>>
>
> I don't know if this problem started with this change, but we now accept
> this invalid code in C++14 mode:
>
> constexpr auto a = [] {};
>

This was a result of two separate bugs. I've fixed one of them, but another
remains, and can be observed in this example:

constexpr int f() { return ([]{}, 0); }
constexpr int n = f();

This is ill-formed before C++17, and yet we accept it in C++11 mode.


> Thanks to Richard Smith for his review!
>> https://reviews.llvm.org/D22662
>>
>>
>> Modified:
>>     cfe/trunk/include/clang/AST/DeclCXX.h
>>     cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
>>
>> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> AST/DeclCXX.h?rev=276514&r1=276513&r2=276514&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
>> +++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jul 22 23:05:19 2016
>> @@ -535,11 +535,10 @@ class CXXRecordDecl : public RecordDecl
>>          MethodTyInfo(Info) {
>>        IsLambda = true;
>>
>> -      // C++11 [expr.prim.lambda]p3:
>> -      //   This class type is neither an aggregate nor a literal type.
>> +      // C++1z [expr.prim.lambda]p4:
>> +      //   This class type is not an aggregate type.
>>        Aggregate = false;
>>        PlainOldData = false;
>> -      HasNonLiteralTypeFieldsOrBases = true;
>>      }
>>
>>      /// \brief Whether this lambda is known to be dependent, even if its
>> @@ -1338,11 +1337,15 @@ public:
>>    ///
>>    /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452
>> by
>>    /// treating types with trivial default constructors as literal types.
>> +  ///
>> +  /// Only in C++1z and beyond, are lambdas literal types.
>>    bool isLiteral() const {
>>      return hasTrivialDestructor() &&
>> -           (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
>> -            hasTrivialDefaultConstructor()) &&
>> -           !hasNonLiteralTypeFieldsOrBases();
>> +           (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) &&
>> +           !hasNonLiteralTypeFieldsOrBases() &&
>> +           (isAggregate() || isLambda() ||
>> +            hasConstexprNonCopyMoveConstructor() ||
>> +            hasTrivialDefaultConstructor());
>>    }
>>
>>    /// \brief If this record is an instantiation of a member class,
>>
>> Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
>> cxx1z-constexpr-lambdas.cpp?rev=276514&r1=276513&r2=276514&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Fri Jul 22
>> 23:05:19 2016
>> @@ -1,8 +1,8 @@
>>  // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s
>>  // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks
>> -fdelayed-template-parsing %s
>> -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks
>> -fms-extensions %s
>> -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks
>> -fdelayed-template-parsing -fms-extensions %s
>> +// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s
>> -DCPP14_AND_EARLIER
>>
>> +#ifndef CPP14_AND_EARLIER
>>  namespace test_constexpr_checking {
>>
>>  namespace ns1 {
>> @@ -33,4 +33,16 @@ namespace ns3 {
>>        L(3); //expected-note{{non-constexpr function}}
>>  }
>>
>> -} // end ns test_constexpr_call
>> \ No newline at end of file
>> +} // end ns test_constexpr_call
>> +
>> +#endif
>> +
>> +namespace test_lambda_is_literal {
>> +#ifdef CPP14_AND_EARLIER
>> +//expected-error at +4{{not a literal type}}
>> +//expected-note at +2{{not an aggregate and has no constexpr constructors}}
>> +#endif
>> +auto L = [] { };
>> +constexpr int foo(decltype(L) l) { return 0; }
>> +
>> +}
>> \ No newline at end of file
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180516/558bd987/attachment.html>


More information about the cfe-commits mailing list