Skip to content

Commit f0f53cb

Browse files
[clangd] Do not ignore qualifier in heuristic resolution of dependent MemberExpr
Fixes #64841 Differential Revision: https://reviews.llvm.org/D158873
1 parent 6bdf485 commit f0f53cb

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

clang-tools-extra/clangd/HeuristicResolver.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ const Type *HeuristicResolver::getPointeeType(const Type *T) const {
119119

120120
std::vector<const NamedDecl *> HeuristicResolver::resolveMemberExpr(
121121
const CXXDependentScopeMemberExpr *ME) const {
122-
// If the expression has a qualifier, first try resolving the member
123-
// inside the qualifier's type.
122+
// If the expression has a qualifier, try resolving the member inside the
123+
// qualifier's type.
124124
// Note that we cannot use a NonStaticFilter in either case, for a couple
125125
// of reasons:
126126
// 1. It's valid to access a static member using instance member syntax,
@@ -137,10 +137,15 @@ std::vector<const NamedDecl *> HeuristicResolver::resolveMemberExpr(
137137
if (!Decls.empty())
138138
return Decls;
139139
}
140+
141+
// Do not proceed to try resolving the member in the expression's base type
142+
// without regard to the qualifier, as that could produce incorrect results.
143+
// For example, `void foo() { this->Base::foo(); }` shouldn't resolve to
144+
// foo() itself!
145+
return {};
140146
}
141147

142-
// If that didn't yield any results, try resolving the member inside
143-
// the expression's base type.
148+
// Try resolving the member inside the expression's base type.
144149
const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
145150
if (ME->isArrow()) {
146151
BaseType = getPointeeType(BaseType);

clang-tools-extra/clangd/unittests/XRefsTests.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,17 @@ TEST(LocateSymbol, All) {
10091009
void play(Dog *dog) {
10101010
[dog ho^wl];
10111011
}
1012-
)objc"};
1012+
)objc",
1013+
R"cpp(
1014+
struct PointerIntPairInfo {
1015+
static void *getPointer(void *Value);
1016+
};
1017+
1018+
template <typename Info = PointerIntPairInfo> struct PointerIntPair {
1019+
void *Value;
1020+
void *getPointer() const { return Info::get^Pointer(Value); }
1021+
};
1022+
)cpp"};
10131023
for (const char *Test : Tests) {
10141024
Annotations T(Test);
10151025
std::optional<Range> WantDecl;

0 commit comments

Comments
 (0)