From 22aa3680eaccb9b77ca224711c4da3a354aa2d45 Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Mon, 28 Jun 2021 09:00:45 -0400 Subject: [PATCH] [C++20] Support for lambdas in unevaluated context Partially implement P0315R4. This patch allow lambda in unevaluated context. It does not implement temp.deduct/9. --- clang/lib/Sema/SemaConcept.cpp | 9 ++++++--- clang/lib/Sema/SemaExpr.cpp | 6 ++++-- clang/test/SemaCXX/anonymous-struct.cpp | 2 +- clang/test/SemaCXX/lambda-unevaluated.cpp | 31 +++++++++++++++++++++++++++++++ clang/www/cxx_status.html | 2 +- 5 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 clang/test/SemaCXX/lambda-unevaluated.cpp diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 5525348..f2c70d0 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -43,9 +43,12 @@ public: LHS = BO->getLHS(); RHS = BO->getRHS(); } else if (auto *OO = dyn_cast(E)) { - Op = OO->getOperator(); - LHS = OO->getArg(0); - RHS = OO->getArg(1); + // If OO is not || or && it might not have exactly 2 arguments. + if (OO->getNumArgs() == 2) { + Op = OO->getOperator(); + LHS = OO->getArg(0); + RHS = OO->getArg(1); + } } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2d0f314..728d7b6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -16722,8 +16722,10 @@ void Sema::PopExpressionEvaluationContext() { if (!Rec.Lambdas.empty()) { using ExpressionKind = ExpressionEvaluationContextRecord::ExpressionKind; - if (Rec.ExprContext == ExpressionKind::EK_TemplateArgument || Rec.isUnevaluated() || - (Rec.isConstantEvaluated() && !getLangOpts().CPlusPlus17)) { + if (!getLangOpts().CPlusPlus20 && + (Rec.ExprContext == ExpressionKind::EK_TemplateArgument || + Rec.isUnevaluated() || + (Rec.isConstantEvaluated() && !getLangOpts().CPlusPlus17))) { unsigned D; if (Rec.isUnevaluated()) { // C++11 [expr.prim.lambda]p2: diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp index 1b6207d..0a5395e 100644 --- a/clang/test/SemaCXX/anonymous-struct.cpp +++ b/clang/test/SemaCXX/anonymous-struct.cpp @@ -49,7 +49,7 @@ typedef struct // expected-warning {{anonymous non-C-compatible type given name : B { // expected-note {{type is not C-compatible due to this base class}} } C; // expected-note {{type is given name 'C' for linkage purposes by this typedef declaration}} -#if __cplusplus > 201703L +#if __cplusplus > 201703L && __cplusplus < 202002L typedef struct { // expected-warning {{anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here}} static_assert([]{ return true; }()); // expected-note {{type is not C-compatible due to this lambda expression}} } Lambda1; // expected-note {{type is given name 'Lambda1' for linkage purposes by this typedef declaration}} diff --git a/clang/test/SemaCXX/lambda-unevaluated.cpp b/clang/test/SemaCXX/lambda-unevaluated.cpp new file mode 100644 index 0000000..07fa0d94 --- /dev/null +++ b/clang/test/SemaCXX/lambda-unevaluated.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++20 %s -verify + + +template struct Nothing {}; +Nothing<[]() { return 0; }()> nothing; + +template struct NothingT {}; +Nothing<[]() { return 0; }> nothingT; + +template +concept True = [] { return true; }(); +static_assert(True); + +static_assert(sizeof([] { return 0; })); +static_assert(sizeof([] { return 0; }())); + +void f() noexcept(noexcept([] { return 0; }())); + +using a = decltype([] { return 0; }); +using b = decltype([] { return 0; }()); +using c = decltype([]() noexcept(noexcept([] { return 0; }())) { return 0; }); +using d = decltype(sizeof([] { return 0; })); + +template +int unique_test1(); +static_assert(&unique_test1<[](){}> != &unique_test1<[](){}>); + +template +auto g(T) -> decltype([]() { T::invalid; } ()); +auto e = g(0); // expected-error{{no matching function for call}} +// expected-note@-2 {{substitution failure}} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index a478a44..b7f2501 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -1011,7 +1011,7 @@ code. This issue is expected to be rectified soon. Lambdas in unevaluated contexts P0315R4 - No + Clang 13 -- 2.7.4