This revision was automatically updated to reflect the committed changes. Closed by commit rG38cf47f037b2: [clang] Error on substitution failure within lambda body inside a requires… (authored by Fznamznon).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D156993/new/ https://reviews.llvm.org/D156993 Files: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/CXX/drs/dr26xx.cpp clang/test/SemaCXX/lambda-unevaluated.cpp clang/www/cxx_dr_status.html
Index: clang/www/cxx_dr_status.html =================================================================== --- clang/www/cxx_dr_status.html +++ clang/www/cxx_dr_status.html @@ -15839,7 +15839,7 @@ <td><a href="https://cplusplus.github.io/CWG/issues/2672.html">2672</a></td> <td>open</td> <td>Lambda body SFINAE is still required, contrary to intent and note</td> - <td align="center">Not resolved</td> + <td class="unreleased" align="center">Clang 18</td> </tr> <tr id="2673"> <td><a href="https://cplusplus.github.io/CWG/issues/2673.html">2673</a></td> Index: clang/test/SemaCXX/lambda-unevaluated.cpp =================================================================== --- clang/test/SemaCXX/lambda-unevaluated.cpp +++ clang/test/SemaCXX/lambda-unevaluated.cpp @@ -155,17 +155,24 @@ template <class T> concept lambda_works = requires { - []() { T::foo(); }; + []() { T::foo(); }; // expected-error{{type 'int' cannot be used prior to '::'}} + // expected-note@-1{{while substituting into a lambda expression here}} + // expected-note@-2{{in instantiation of requirement here}} + // expected-note@-4{{while substituting template arguments into constraint expression here}} }; -static_assert(!lambda_works<int>); +static_assert(!lambda_works<int>); // expected-note {{while checking the satisfaction of concept 'lambda_works<int>' requested here}} static_assert(lambda_works<WithFoo>); template <class T> -int* func(T) requires requires { []() { T::foo(); }; }; +int* func(T) requires requires { []() { T::foo(); }; }; // expected-error{{type 'int' cannot be used prior to '::'}} + // expected-note@-1{{while substituting into a lambda expression here}} + // expected-note@-2{{in instantiation of requirement here}} + // expected-note@-3{{while substituting template arguments into constraint expression here}} double* func(...); -static_assert(__is_same(decltype(func(0)), double*)); +static_assert(__is_same(decltype(func(0)), double*)); // expected-note {{while checking constraint satisfaction for template 'func<int>' required here}} + // expected-note@-1 {{in instantiation of function template specialization 'lambda_in_constraints::func<int>'}} static_assert(__is_same(decltype(func(WithFoo())), int*)); template <class T> Index: clang/test/CXX/drs/dr26xx.cpp =================================================================== --- clang/test/CXX/drs/dr26xx.cpp +++ clang/test/CXX/drs/dr26xx.cpp @@ -150,3 +150,24 @@ J j = { "ghi" }; // expected-error {{no viable constructor or deduction guide}} } + +namespace dr2672 { // dr2672: 18 open +template <class T> +void f(T) requires requires { []() { T::invalid; } (); }; // expected-error{{type 'int' cannot be used prior to '::'}} + // expected-note@-1{{while substituting into a lambda expression here}} + // expected-note@-2{{in instantiation of requirement here}} + // expected-note@-3{{while substituting template arguments into constraint expression here}} +void f(...); + +template <class T> +void bar(T) requires requires { + decltype([]() -> T {})::foo(); +}; +void bar(...); + +void m() { + f(0); // expected-note {{while checking constraint satisfaction for template 'f<int>' required here}} + // expected-note@-1 {{in instantiation of function template specialization}} + bar(0); +} +} Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1074,7 +1074,6 @@ if (InNonInstantiationSFINAEContext) return std::optional<TemplateDeductionInfo *>(nullptr); - bool SawLambdaSubstitution = false; for (SmallVectorImpl<CodeSynthesisContext>::const_reverse_iterator Active = CodeSynthesisContexts.rbegin(), ActiveEnd = CodeSynthesisContexts.rend(); @@ -1101,10 +1100,8 @@ // A lambda-expression appearing in a function type or a template // parameter is not considered part of the immediate context for the // purposes of template argument deduction. - - // We need to check parents. - SawLambdaSubstitution = true; - break; + // CWG2672: A lambda-expression body is never in the immediate context. + return std::nullopt; case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: case CodeSynthesisContext::PriorTemplateArgumentSubstitution: @@ -1120,8 +1117,6 @@ // We're either substituting explicitly-specified template arguments, // deduced template arguments. SFINAE applies unless we are in a lambda // expression, see [temp.deduct]p9. - if (SawLambdaSubstitution) - return std::nullopt; [[fallthrough]]; case CodeSynthesisContext::ConstraintSubstitution: case CodeSynthesisContext::RequirementInstantiation: Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -157,6 +157,10 @@ (`#35574 <https://github.com/llvm/llvm-project/issues/35574>_`) and (`#27224 <https://github.com/llvm/llvm-project/issues/27224>_`). +- Clang emits an error on substitution failure within lambda body inside a + requires-expression. This fixes: + (`#64138 <https://github.com/llvm/llvm-project/issues/64138>_`). + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits