Skip to content

Commit c865ba5

Browse files
committed
[Clang] Dependent CallExpr having UnresolvedLookupExpr are not created inside non-dependent context
1 parent 178f471 commit c865ba5

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

clang/lib/Sema/SemaOverload.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14228,9 +14228,24 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn,
1422814228
const FunctionDecl *FDecl = Best->Function;
1422914229
if (FDecl && FDecl->isTemplateInstantiation() &&
1423014230
FDecl->getReturnType()->isUndeducedType()) {
14231+
14232+
// Creating dependent CallExpr is not okay if the enclosing context itself
14233+
// is not dependent. This situation notably arises if a non-dependent
14234+
// member function calls the later-defined overloaded static function.
14235+
//
14236+
// For example, in
14237+
// class A {
14238+
// void c() { callee(1); }
14239+
// static auto callee(auto x) { }
14240+
// };
14241+
//
14242+
// Here callee(1) is unresolved at the call site, but is not inside a
14243+
// dependent context. There will be no further attempt to resolve this
14244+
// call if it is made dependent.
14245+
1423114246
if (const auto *TP =
1423214247
FDecl->getTemplateInstantiationPattern(/*ForDefinition=*/false);
14233-
TP && TP->willHaveBody()) {
14248+
TP && TP->willHaveBody() && CurContext->isDependentContext()) {
1423414249
return CallExpr::Create(Context, Fn, Args, Context.DependentTy,
1423514250
VK_PRValue, RParenLoc, CurFPFeatureOverrides());
1423614251
}

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

Lines changed: 42 additions & 0 deletions
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)