[clang] 523cf65 - [Clang] Do not create dependent CallExpr having UnresolvedLookupExpr inside non-dependent context (#124609)

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 20 12:29:27 PDT 2025


Author: TilakChad
Date: 2025-03-20T16:29:23-03:00
New Revision: 523cf65b668e2c7c572c8b5a54e28388d5e955a4

URL: https://github.com/llvm/llvm-project/commit/523cf65b668e2c7c572c8b5a54e28388d5e955a4
DIFF: https://github.com/llvm/llvm-project/commit/523cf65b668e2c7c572c8b5a54e28388d5e955a4.diff

LOG: [Clang] Do not create dependent CallExpr having UnresolvedLookupExpr inside non-dependent context (#124609)

The `UnresolvedLookupExpr` doesn't get looked up and resolved again
while it is inside the non-dependent context. It propagates into the
codegen phase, causing the assertion failure.

We attempt to determine if the current context is dependent before
moving on with the substitution introduced in the
https://github.com/llvm/llvm-project/commit/20a05677f9394d4bc9467fe7bc93a4ebd3aeda61.

This fixes https://github.com/llvm/llvm-project/issues/122892.

---------

Co-authored-by: Sirraide <aeternalmail at gmail.com>

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaOverload.cpp
    clang/test/SemaCXX/deduced-return-type-cxx14.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 97f6ea90d4705..724cb62f1b0e6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -355,6 +355,7 @@ Bug Fixes to C++ Support
 - Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411)
 - Clang was previously coalescing volatile writes to members of volatile base class subobjects.
   The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824)
+- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
 - Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
   and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
 

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 670c27f7bdf09..6d8006b35dcf4 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -14361,9 +14361,24 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn,
     const FunctionDecl *FDecl = Best->Function;
     if (FDecl && FDecl->isTemplateInstantiation() &&
         FDecl->getReturnType()->isUndeducedType()) {
+
+      // Creating dependent CallExpr is not okay if the enclosing context itself
+      // is not dependent. This situation notably arises if a non-dependent
+      // member function calls the later-defined overloaded static function.
+      //
+      // For example, in
+      // class A {
+      //    void c() { callee(1); }
+      //    static auto callee(auto x) { }
+      // };
+      //
+      // Here callee(1) is unresolved at the call site, but is not inside a
+      // dependent context. There will be no further attempt to resolve this
+      // call if it is made dependent.
+
       if (const auto *TP =
               FDecl->getTemplateInstantiationPattern(/*ForDefinition=*/false);
-          TP && TP->willHaveBody()) {
+          TP && TP->willHaveBody() && CurContext->isDependentContext()) {
         return CallExpr::Create(Context, Fn, Args, Context.DependentTy,
                                 VK_PRValue, RParenLoc, CurFPFeatureOverrides());
       }

diff  --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
index c33e07088ba32..aa62c4a57a636 100644
--- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -703,6 +703,48 @@ auto f(auto x) { // cxx14-error {{'auto' not allowed in function prototype}}
   return f(1) + 1;
 }
 
+namespace GH122892 {
+  struct NonTemplate {
+    void caller() {
+        c1(int{}); // since-cxx20-error {{cannot be used before it is defined}}
+        c2(int{}); // since-cxx14-error {{cannot be used before it is defined}}
+    }
+
+    static auto c1(auto x) { // since-cxx20-note {{declared here}} // cxx14-error {{'auto' not allowed in function prototype}}
+    }
+
+    template <typename T>
+    static auto c2(T x) { // since-cxx14-note {{declared here}}
+        return x;
+    }
+  };
+
+  struct FunctionTemplateSpecialized {
+    template <typename T>
+    void specialized(){}
+
+    template <>
+    void specialized<int>() {
+      c1(int{}); // since-cxx20-error {{cannot be used before it is defined}}
+      c2(int{}); // since-cxx14-error {{cannot be used before it is defined}}
+    }
+
+    static auto c1(auto x) { // since-cxx20-note {{declared here}} // cxx14-error {{'auto' not allowed in function prototype}}
+    }
+
+    template <typename T>
+    static auto c2(T x) { // since-cxx14-note {{declared here}}
+        return x;
+    }
+  };
+
+  struct MemberInit {
+    int x1 = c1(int{}); // since-cxx20-error {{cannot be used before it is defined}}
+
+    static auto c1(auto x) { return x; } // since-cxx20-note {{declared here}} // cxx14-error {{'auto' not allowed in function prototype}}
+  };
+
+}
 }
 
 #if __cplusplus >= 202002L


        


More information about the cfe-commits mailing list