зеркало из https://github.com/microsoft/clang-1.git
When performing name lookup within a class template or class template
partial specialization, make sure we look into non-dependent base classes (but not dependent base classes). Fixes PR4951. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81584 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
4f213d3d74
Коммит
4719f4e86a
|
@ -139,9 +139,12 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
|
|||
QualType BaseType = Context.getCanonicalType(BaseSpec->getType());
|
||||
BaseType = BaseType.getUnqualifiedType();
|
||||
|
||||
// If a base class of the class template depends on a template-parameter,
|
||||
// the base class scope is not examined during unqualified name lookup.
|
||||
// [temp.dep]p3.
|
||||
// C++ [temp.dep]p3:
|
||||
// In the definition of a class template or a member of a class template,
|
||||
// if a base class of the class template depends on a template-parameter,
|
||||
// the base class scope is not examined during unqualified name lookup
|
||||
// either at the point of definition of the class template or member or
|
||||
// during an instantiation of the class tem- plate or member.
|
||||
if (BaseType->isDependentType())
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1032,9 +1032,8 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
|
|||
return LookupResult::CreateLookupResult(Context, I, E);
|
||||
|
||||
// If this isn't a C++ class, we aren't allowed to look into base
|
||||
// classes, we're done, or the lookup context is dependent, we're done.
|
||||
if (RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx) ||
|
||||
LookupCtx->isDependentContext())
|
||||
// classes, we're done.
|
||||
if (RedeclarationOnly || !isa<CXXRecordDecl>(LookupCtx))
|
||||
return LookupResult::CreateLookupResult(Context, 0);
|
||||
|
||||
// Perform lookup into our base classes.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
struct A0 {
|
||||
struct K { };
|
||||
};
|
||||
|
||||
template <typename T> struct B0: A0 {
|
||||
static void f() {
|
||||
K k;
|
||||
}
|
||||
};
|
||||
|
||||
namespace E1 {
|
||||
typedef double A;
|
||||
|
||||
template<class T> class B {
|
||||
typedef int A;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct X : B<T> {
|
||||
A* blarg(double *dp) {
|
||||
return dp;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace E2 {
|
||||
struct A {
|
||||
struct B;
|
||||
int *a;
|
||||
int Y;
|
||||
};
|
||||
|
||||
int a;
|
||||
template<class T> struct Y : T {
|
||||
struct B { /* ... */ };
|
||||
B b;
|
||||
void f(int i) { a = i; }
|
||||
Y* p;
|
||||
};
|
||||
|
||||
Y<A> ya;
|
||||
}
|
Загрузка…
Ссылка в новой задаче