cor3ntin updated this revision to Diff 348759. cor3ntin added a comment. 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,27 @@ +// RUN: %clang_cc1 -std=c++20 %s -verify + +template <auto> struct Nothing {}; + +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; })); + + +Nothing<[]() { return 0; }()> nothing; + + +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}} \ No newline at end of file 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); + } } }
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,27 @@ +// RUN: %clang_cc1 -std=c++20 %s -verify + +template <auto> struct Nothing {}; + +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; })); + + +Nothing<[]() { return 0; }()> nothing; + + +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}} \ No newline at end of file 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); + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits