[clang] 3e69e5a - [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (#83420)

via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 15 21:56:15 PDT 2024


Author: Younan Zhang
Date: 2024-03-16T12:56:11+08:00
New Revision: 3e69e5a15782a5776a3245170aeb5d97ef746fa5

URL: https://github.com/llvm/llvm-project/commit/3e69e5a15782a5776a3245170aeb5d97ef746fa5
DIFF: https://github.com/llvm/llvm-project/commit/3e69e5a15782a5776a3245170aeb5d97ef746fa5.diff

LOG: [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (#83420)

This fixes the case shown by
https://github.com/llvm/llvm-project/issues/64808#issuecomment-1929131611.

Similar to
https://github.com/llvm/llvm-project/commit/f9caa12328b265b77221fe7a310d4504673d814a,
we have some calls to constraint checking for a lambda's conversion
function while determining the conversion sequence.

This patch addresses the problem where the requires-expression within
such a lambda references to a Decl outside of the lambda by adding these
Decls to the current instantiation scope.

I'm abusing the flag `ForOverloadResolution` of
CheckFunctionConstraints, which is actually meant to consider the Decls
from parent DeclContexts.

---------

Co-authored-by: cor3ntin <corentinjabot at gmail.com>

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaConcept.cpp
    clang/test/SemaTemplate/concepts.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1ae35e6881d2f8..93cc5291e2391f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -387,6 +387,8 @@ Bug Fixes to C++ Support
   Fixes (#GH80997)
 - Fix an issue where missing set friend declaration in template class instantiation.
   Fixes (#GH84368).
+- Fixed a crash while checking constraints of a trailing requires-expression of a lambda, that the
+  expression references to an entity declared outside of the lambda. (#GH64808)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index a8e387e35fb4c9..1c546e9f5894f0 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -692,11 +692,15 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
   // A lambda conversion operator has the same constraints as the call operator
   // and constraints checking relies on whether we are in a lambda call operator
   // (and may refer to its parameters), so check the call operator instead.
+  // Note that the declarations outside of the lambda should also be
+  // considered. Turning on the 'ForOverloadResolution' flag results in the
+  // LocalInstantiationScope not looking into its parents, but we can still
+  // access Decls from the parents while building a lambda RAII scope later.
   if (const auto *MD = dyn_cast<CXXConversionDecl>(FD);
       MD && isLambdaConversionOperator(const_cast<CXXConversionDecl *>(MD)))
     return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(),
                                     Satisfaction, UsageLoc,
-                                    ForOverloadResolution);
+                                    /*ShouldAddDeclsFromParentScope=*/true);
 
   DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD);
 

diff  --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index bac209a28da912..b7ea0d003a52d7 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1085,3 +1085,32 @@ template void Struct<void>::bar<>();
 template int Struct<void>::field<1, 2>;
 
 }
+
+namespace GH64808 {
+
+template <class T> struct basic_sender {
+  T func;
+  basic_sender(T) : func(T()) {}
+};
+
+auto a = basic_sender{[](auto... __captures) {
+  return []() // #note-a-1
+    requires((__captures, ...), false) // #note-a-2
+  {};
+}()};
+
+auto b = basic_sender{[](auto... __captures) {
+  return []()
+    requires([](int, double) { return true; }(decltype(__captures)()...))
+  {};
+}(1, 2.33)};
+
+void foo() {
+  a.func();
+  // expected-error at -1{{no matching function for call}}
+  // expected-note@#note-a-1{{constraints not satisfied}}
+  // expected-note@#note-a-2{{evaluated to false}}
+  b.func();
+}
+
+} // namespace GH64808


        


More information about the cfe-commits mailing list