r206011 - Fix handling of redeclaration lookup for using declarations, where the prior

Richard Smith richard-llvm at metafoo.co.uk
Thu Apr 10 18:03:38 PDT 2014


Author: rsmith
Date: Thu Apr 10 20:03:38 2014
New Revision: 206011

URL: http://llvm.org/viewvc/llvm-project?rev=206011&view=rev
Log:
Fix handling of redeclaration lookup for using declarations, where the prior
declaration is not visible. Previously we didn't find hidden friend names in
this redeclaration lookup, because we forgot to treat it as a redeclaration
lookup. Conversely, we did find some local extern names, but those don't
actually conflict with a namespace-scope using declaration, because the only
conflicts we can get are scope conflicts, not conflicts due to the entities
being members of the same namespace.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/SemaCXX/using-decl-1.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=206011&r1=206010&r2=206011&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Apr 10 20:03:38 2014
@@ -7379,6 +7379,13 @@ NamedDecl *Sema::BuildUsingDeclaration(S
       NamedDecl *D = F.next();
       if (!isDeclInScope(D, CurContext, S))
         F.erase();
+      // If we found a local extern declaration that's not ordinarily visible,
+      // and this declaration is being added to a non-block scope, ignore it.
+      // We're only checking for scope conflicts here, not also for violations
+      // of the linkage rules.
+      else if (!CurContext->isFunctionOrMethod() && D->isLocalExternDecl() &&
+               !(D->getIdentifierNamespace() & Decl::IDNS_Ordinary))
+        F.erase();
     }
     F.done();
   } else {

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=206011&r1=206010&r2=206011&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Apr 10 20:03:38 2014
@@ -244,10 +244,11 @@ static inline unsigned getIDNS(Sema::Loo
       IDNS = Decl::IDNS_Tag;
     }
     break;
+
   case Sema::LookupLabel:
     IDNS = Decl::IDNS_Label;
     break;
-      
+
   case Sema::LookupMemberName:
     IDNS = Decl::IDNS_Member;
     if (CPlusPlus)
@@ -263,8 +264,10 @@ static inline unsigned getIDNS(Sema::Loo
     break;
 
   case Sema::LookupUsingDeclName:
-    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag
-         | Decl::IDNS_Member | Decl::IDNS_Using;
+    assert(Redeclaration && "should only be used for redecl lookup");
+    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member |
+           Decl::IDNS_Using | Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend |
+           Decl::IDNS_LocalExtern;
     break;
 
   case Sema::LookupObjCProtocolName:

Modified: cfe/trunk/test/SemaCXX/using-decl-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-1.cpp?rev=206011&r1=206010&r2=206011&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/using-decl-1.cpp (original)
+++ cfe/trunk/test/SemaCXX/using-decl-1.cpp Thu Apr 10 20:03:38 2014
@@ -160,3 +160,37 @@ namespace M { }
 }
 using N::M::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_nested_specifier::N::M'; did you mean 'N::FFF'?}}
 }
+
+namespace UsingDeclVsHiddenName {
+  namespace A {
+    enum HiddenTag1 {}; // expected-note {{previous use is here}}
+    enum HiddenTag2 {}; // expected-note {{target}}
+    int HiddenFn1; // expected-note {{target}}
+    int HiddenFn2; // expected-note {{target}}
+    int HiddenLocalExtern1;
+    int HiddenLocalExtern2;
+  }
+
+  namespace B {
+    using A::HiddenTag1;
+    using A::HiddenFn1; // expected-note {{using declaration}}
+    using A::HiddenLocalExtern1;
+
+    struct S {
+      friend struct HiddenTag1; // expected-error {{tag type that does not match previous}}
+      friend struct HiddenTag2; // expected-note {{conflicting declaration}}
+      friend void HiddenFn1(); // expected-error {{cannot befriend target of using declaration}}
+      friend void HiddenFn2(); // expected-note {{conflicting declaration}}
+      void f() {
+        // OK, these are not in the scope of namespace B, even though they're
+        // members of the namespace.
+        void HiddenLocalExtern1();
+        void HiddenLocalExtern2();
+      }
+    };
+
+    using A::HiddenTag2; // expected-error {{conflicts with declaration already in scope}}
+    using A::HiddenFn2; // expected-error {{conflicts with declaration already in scope}}
+    using A::HiddenLocalExtern2;
+  }
+}





More information about the cfe-commits mailing list