[PATCH] D103380: [C++20] Support for lambdas in unevaluated context
Corentin Jabot via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 1 09:58:23 PDT 2021
cor3ntin updated this revision to Diff 349000.
cor3ntin added a comment.
Typos, add more tests
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103380/new/
https://reviews.llvm.org/D103380
Files:
clang/lib/Sema/SemaConcept.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-unevaluated.cpp
clang/test/SemaCXX/anonymous-struct.cpp
clang/www/cxx_status.html
Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1011,7 +1011,7 @@
<tr>
<td>Lambdas in unevaluated contexts</td>
<td><a href="https://wg21.link/p0315r4">P0315R4</a></td>
- <td class="none" align="center">No</td>
+ <td class="partial" align="center">Clang 13</td>
</tr>
<!-- Jacksonville papers -->
<tr>
Index: clang/test/SemaCXX/anonymous-struct.cpp
===================================================================
--- clang/test/SemaCXX/anonymous-struct.cpp
+++ clang/test/SemaCXX/anonymous-struct.cpp
@@ -49,7 +49,7 @@
: 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}}
Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-unevaluated.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/p2-unevaluated.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+
+
+template <auto> struct Nothing {};
+Nothing<[]() { return 0; }()> nothing;
+
+template <typename> struct NothingT {};
+Nothing<[]() { return 0; }> nothingT;
+
+template <typename T>
+concept True = [] { return true; }();
+static_assert(True<int>);
+
+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 <auto T>
+int unique_test1();
+static_assert(&unique_test1<[](){}> != &unique_test1<[](){}>);
+
+template <class T>
+auto g(T) -> decltype([]() { T::invalid; } ());
+auto e = g(0); // expected-error{{no matching function for call}}
+// expected-note at -2 {{substitution failure}}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16657,8 +16657,10 @@
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:
Index: clang/lib/Sema/SemaConcept.cpp
===================================================================
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -41,9 +41,12 @@
LHS = BO->getLHS();
RHS = BO->getRHS();
} else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(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);
+ }
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103380.349000.patch
Type: text/x-patch
Size: 3885 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210601/497eaa61/attachment.bin>
More information about the cfe-commits
mailing list