Skip to content

Commit 4eb7be6

Browse files
committed
[clang] Fix name lookup for dependent bases
1 parent 5d39e0c commit 4eb7be6

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

clang/lib/AST/CXXInheritance.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,18 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
169169
// Find the record of the base class subobjects for this type.
170170
QualType BaseType =
171171
Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType();
172+
bool isCurrentInstantiation = false;
173+
if (auto *TST = BaseSpec.getType()->getAs<TemplateSpecializationType>())
174+
isCurrentInstantiation = TST->isCurrentInstantiation();
172175

173176
// C++ [temp.dep]p3:
174177
// In the definition of a class template or a member of a class template,
175178
// if a base class of the class template depends on a template-parameter,
176179
// the base class scope is not examined during unqualified name lookup
177180
// either at the point of definition of the class template or member or
178181
// during an instantiation of the class tem- plate or member.
179-
if (!LookupInDependent && BaseType->isDependentType())
182+
if (!LookupInDependent &&
183+
(BaseType->isDependentType() && !isCurrentInstantiation))
180184
continue;
181185

182186
// Determine whether we need to visit this base class at all,
@@ -244,9 +248,8 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
244248
return FoundPath;
245249
}
246250
} else if (VisitBase) {
247-
CXXRecordDecl *BaseRecord;
251+
CXXRecordDecl *BaseRecord = nullptr;
248252
if (LookupInDependent) {
249-
BaseRecord = nullptr;
250253
const TemplateSpecializationType *TST =
251254
BaseSpec.getType()->getAs<TemplateSpecializationType>();
252255
if (!TST) {
@@ -265,8 +268,8 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
265268
BaseRecord = nullptr;
266269
}
267270
} else {
268-
BaseRecord = cast<CXXRecordDecl>(
269-
BaseSpec.getType()->castAs<RecordType>()->getDecl());
271+
if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
272+
BaseRecord = cast<CXXRecordDecl>(RT->getDecl());
270273
}
271274
if (BaseRecord &&
272275
lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {

clang/test/CXX/drs/cwg5xx.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,17 +1178,21 @@ namespace cwg590 { // cwg590: yes
11781178
template<typename T> typename A<T>::B::C A<T>::B::C::f(A<T>::B::C) {}
11791179
}
11801180

1181-
namespace cwg591 { // cwg591: no
1181+
namespace cwg591 { // cwg591: yes
11821182
template<typename T> struct A {
11831183
typedef int M;
11841184
struct B {
11851185
typedef void M;
11861186
struct C;
1187+
struct D;
11871188
};
11881189
};
11891190

11901191
template<typename T> struct A<T>::B::C : A<T> {
1191-
// FIXME: Should find member of non-dependent base class A<T>.
1192+
M m;
1193+
};
1194+
1195+
template<typename T> struct A<T>::B::D : A<T*> {
11921196
M m;
11931197
// expected-error@-1 {{field has incomplete type 'M' (aka 'void'}}
11941198
};

0 commit comments

Comments
 (0)