Audit uses of Sema::LookupSingleName for those lookups that are

intended for redeclarations, fixing those that need it. Fixes PR6831.

This uncovered an issue where the C++ type-specifier-seq parsing logic
would try to perform name lookup on an identifier after it already had
a type-specifier, which could also lead to spurious ambiguity errors
(as in PR6831, but with a different test case).

llvm-svn: 101419
This commit is contained in:
Douglas Gregor 2010-04-15 23:40:53 +00:00
parent 1d3ee607b3
commit b8eaf2944b
6 changed files with 43 additions and 15 deletions

View File

@ -1437,6 +1437,11 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
switch (Tok.getKind()) {
case tok::identifier: // foo::bar
// If we already have a type specifier, this identifier is not a type.
if (DS.getTypeSpecType() != DeclSpec::TST_unspecified ||
DS.getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
DS.getTypeSpecSign() != DeclSpec::TSS_unspecified)
return false;
// Check for need to substitute AltiVec keyword tokens.
if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
break;

View File

@ -4937,7 +4937,8 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
bool Invalid = D.isInvalidType();
IdentifierInfo *II = D.getIdentifier();
if (NamedDecl *PrevDecl = LookupSingleName(S, II, D.getIdentifierLoc(),
LookupOrdinaryName)) {
LookupOrdinaryName,
ForRedeclaration)) {
// The scope should be freshly made just for us. There is just no way
// it contains any previous declaration.
assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));

View File

@ -67,13 +67,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
// Just pretend that we didn't see the previous declaration.
PrevDecl = 0;
}
LookupOrdinaryName, ForRedeclaration);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
@ -202,7 +196,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
SourceLocation ClassLocation) {
// Look for previous declaration of alias name
NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
LookupOrdinaryName);
LookupOrdinaryName, ForRedeclaration);
if (ADecl) {
if (isa<ObjCCompatibleAliasDecl>(ADecl))
Diag(AliasLocation, diag::warn_previous_alias_decl);
@ -213,14 +207,14 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
}
// Check for class declaration
NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
LookupOrdinaryName);
LookupOrdinaryName, ForRedeclaration);
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
QualType T = TDecl->getUnderlyingType();
if (T->isObjCInterfaceType()) {
if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
ClassName = IDecl->getIdentifier();
CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
LookupOrdinaryName);
LookupOrdinaryName, ForRedeclaration);
}
}
}
@ -547,7 +541,8 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
ObjCInterfaceDecl* IDecl = 0;
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl
= LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName);
= LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
ForRedeclaration);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
@ -1013,7 +1008,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl
= LookupSingleName(TUScope, IdentList[i], IdentLocs[i],
LookupOrdinaryName);
LookupOrdinaryName, ForRedeclaration);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);

View File

@ -456,7 +456,8 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
if (ParamName) {
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc,
LookupTagName);
LookupOrdinaryName,
ForRedeclaration);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
PrevDecl);
@ -578,7 +579,8 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
IdentifierInfo *ParamName = D.getIdentifier();
if (ParamName) {
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(),
LookupTagName);
LookupOrdinaryName,
ForRedeclaration);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
PrevDecl);

View File

@ -26,3 +26,15 @@ template<class T, T i> struct X2 {
// expected-error{{no viable conversion}}
}
};
namespace PR6831 {
namespace NA { struct S; }
namespace NB { struct S; }
using namespace NA;
using namespace NB;
template <typename S> void foo();
template <int S> void bar();
template <template<typename> class S> void baz();
}

View File

@ -107,3 +107,16 @@ public:
}
virtual void test () = 0; // expected-note{{pure virtual function 'test'}}
};
namespace PR6831 {
namespace NA { struct S; }
namespace NB { struct S; }
void f() {
using namespace NA;
using namespace NB;
try {
} catch (int S) {
}
}
}