[PATCH] D45194: [Sema] Defer checking constexpr lambda until after we've finished the lambda class.
Erik Pilkington via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 4 11:10:50 PDT 2018
erik.pilkington updated this revision to Diff 141001.
erik.pilkington marked an inline comment as done.
erik.pilkington added a comment.
Handle this in ExprConstant instead of in Sema.
https://reviews.llvm.org/D45194
Files:
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
Index: clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===================================================================
--- clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -270,4 +270,37 @@
} // end ns test_lambda_is_cce
+namespace PR36054 {
+constexpr int fn() {
+ int Capture = 42;
+ return [=]() constexpr { return Capture; }();
+}
+
+static_assert(fn() == 42, "");
+
+template <class T>
+constexpr int tfn() {
+ int Capture = 42;
+ return [=]() constexpr { return Capture; }();
+}
+
+static_assert(tfn<int>() == 42, "");
+
+constexpr int gfn() {
+ int Capture = 42;
+ return [=](auto P) constexpr { return Capture + P; }(58);
+}
+
+static_assert(gfn() == 100, "");
+
+constexpr bool OtherCaptures() {
+ int Capture = 42;
+ constexpr auto Outer = [](auto P) constexpr { return 42 + P; };
+ auto Inner = [&](auto O) constexpr { return O(58) + Capture; };
+ return Inner(Outer) == 142;
+}
+
+static_assert(OtherCaptures(), "");
+} // namespace PR36054
+
#endif // ndef CPP14_AND_EARLIER
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -4308,7 +4308,8 @@
return false;
This->moveInto(Result);
return true;
- } else if (MD && isLambdaCallOperator(MD)) {
+ } else if (MD && isLambdaCallOperator(MD)
+ && !Info.checkingPotentialConstantExpression()) {
// We're in a lambda; determine the lambda capture field maps.
MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
Frame.LambdaThisCaptureField);
@@ -5202,9 +5203,11 @@
// data-member/field within the closure object, and if so, evaluate to the
// field or what the field refers to.
if (Info.CurrentCall && isLambdaCallOperator(Info.CurrentCall->Callee)) {
+ // We don't track the lambda's captures in a potential constant expression.
+ if (Info.checkingPotentialConstantExpression())
+ return false;
+
if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
- if (Info.checkingPotentialConstantExpression())
- return false;
// Start with 'Result' referring to the complete closure object...
Result = *Info.CurrentCall->This;
// ... then update it to refer to the field of the closure object
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45194.141001.patch
Type: text/x-patch
Size: 2400 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180404/2b9eb0e5/attachment.bin>
More information about the cfe-commits
mailing list