Fznamznon updated this revision to Diff 546837.
Fznamznon added a comment.

Rebase, apply feedback


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
@@ -132,6 +132,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

Reply via email to