forked from OSchip/llvm-project
[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.
This commit is contained in:
parent
5cf27532fa
commit
22aa3680ea
|
@ -43,9 +43,12 @@ public:
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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@-2 {{substitution failure}}
|
|
@ -1011,7 +1011,7 @@ code. This issue is expected to be rectified soon.
|
|||
<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>
|
||||
|
|
Loading…
Reference in New Issue