forked from OSchip/llvm-project
[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. Thanks to Richard Smith for his review! https://reviews.llvm.org/D22662 llvm-svn: 276514
This commit is contained in:
parent
a653927e8b
commit
c6b9be29f2
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
} // end ns test_constexpr_call
|
||||
|
||||
#endif
|
||||
|
||||
namespace test_lambda_is_literal {
|
||||
#ifdef CPP14_AND_EARLIER
|
||||
//expected-error@+4{{not a literal type}}
|
||||
//expected-note@+2{{not an aggregate and has no constexpr constructors}}
|
||||
#endif
|
||||
auto L = [] { };
|
||||
constexpr int foo(decltype(L) l) { return 0; }
|
||||
|
||||
}
|
Loading…
Reference in New Issue