]> granicus.if.org Git - clang/commitdiff
Audit uses of Sema::LookupSingleName for those lookups that are
authorDouglas Gregor <dgregor@apple.com>
Thu, 15 Apr 2010 23:40:53 +0000 (23:40 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 15 Apr 2010 23:40:53 +0000 (23:40 +0000)
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).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101419 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaTemplate.cpp
test/CXX/temp/temp.param/p3.cpp
test/SemaCXX/exceptions.cpp

index 09ae231c5e74ec4409243ad8b02778d6eed01d1d..2a58120f26f661a915c494c3f15d022a3858076c 100644 (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;
index ca4dc6f11d4384912b3a871f1446206be368437d..d84111541d2eaf0537879846a3de74db0b619afe 100644 (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)));
index 006cd8ac6cd2bd0a6422d59cc1c725d8ada537db..ba6c8bb88662121937b5af560b74d92147039c61 100644 (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);
index 4cee60d778a0464c3aa3dca0770937cb38d0981c..fbe331b6b267a6da99f82bfa6b9edf011ab93daf 100644 (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);
index 8fcc2dc85957928edccc8017e2fd2c7fc79aa2eb..dc40c4bb909047176e4b2c99e602e2702a5632b0 100644 (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();
+}
index e009558ce3e7f72cf7f4a44fa11908757d16a3bd..18349d10ef71c15637c0775596ba2175c68a5202 100644 (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) { 
+    }
+  }
+}