Skip to content

Commit 523cf65

Browse files
TilakChadSirraide
andauthored
[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 20a0567. This fixes #122892. --------- Co-authored-by: Sirraide <[email protected]>
1 parent df2a567 commit 523cf65

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

clang/docs/ReleaseNotes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ Bug Fixes to C++ Support
355355
- Correctly diagnoses if unresolved using declarations shadows template paramters (#GH129411)
356356
- Clang was previously coalescing volatile writes to members of volatile base class subobjects.
357357
The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824)
358+
- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
358359
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
359360
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
360361

clang/lib/Sema/SemaOverload.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -14361,9 +14361,24 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn,
1436114361
const FunctionDecl *FDecl = Best->Function;
1436214362
if (FDecl && FDecl->isTemplateInstantiation() &&
1436314363
FDecl->getReturnType()->isUndeducedType()) {
14364+
14365+
// Creating dependent CallExpr is not okay if the enclosing context itself
14366+
// is not dependent. This situation notably arises if a non-dependent
14367+
// member function calls the later-defined overloaded static function.
14368+
//
14369+
// For example, in
14370+
// class A {
14371+
// void c() { callee(1); }
14372+
// static auto callee(auto x) { }
14373+
// };
14374+
//
14375+
// Here callee(1) is unresolved at the call site, but is not inside a
14376+
// dependent context. There will be no further attempt to resolve this
14377+
// call if it is made dependent.
14378+
1436414379
if (const auto *TP =
1436514380
FDecl->getTemplateInstantiationPattern(/*ForDefinition=*/false);
14366-
TP && TP->willHaveBody()) {
14381+
TP && TP->willHaveBody() && CurContext->isDependentContext()) {
1436714382
return CallExpr::Create(Context, Fn, Args, Context.DependentTy,
1436814383
VK_PRValue, RParenLoc, CurFPFeatureOverrides());
1436914384
}

clang/test/SemaCXX/deduced-return-type-cxx14.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,48 @@ auto f(auto x) { // cxx14-error {{'auto' not allowed in function prototype}}
703703
return f(1) + 1;
704704
}
705705

706+
namespace GH122892 {
707+
struct NonTemplate {
708+
void caller() {
709+
c1(int{}); // since-cxx20-error {{cannot be used before it is defined}}
710+
c2(int{}); // since-cxx14-error {{cannot be used before it is defined}}
711+
}
712+
713+
static auto c1(auto x) { // since-cxx20-note {{declared here}} // cxx14-error {{'auto' not allowed in function prototype}}
714+
}
715+
716+
template <typename T>
717+
static auto c2(T x) { // since-cxx14-note {{declared here}}
718+
return x;
719+
}
720+
};
721+
722+
struct FunctionTemplateSpecialized {
723+
template <typename T>
724+
void specialized(){}
725+
726+
template <>
727+
void specialized<int>() {
728+
c1(int{}); // since-cxx20-error {{cannot be used before it is defined}}
729+
c2(int{}); // since-cxx14-error {{cannot be used before it is defined}}
730+
}
731+
732+
static auto c1(auto x) { // since-cxx20-note {{declared here}} // cxx14-error {{'auto' not allowed in function prototype}}
733+
}
734+
735+
template <typename T>
736+
static auto c2(T x) { // since-cxx14-note {{declared here}}
737+
return x;
738+
}
739+
};
740+
741+
struct MemberInit {
742+
int x1 = c1(int{}); // since-cxx20-error {{cannot be used before it is defined}}
743+
744+
static auto c1(auto x) { return x; } // since-cxx20-note {{declared here}} // cxx14-error {{'auto' not allowed in function prototype}}
745+
};
746+
747+
}
706748
}
707749

708750
#if __cplusplus >= 202002L

0 commit comments

Comments
 (0)