]> granicus.if.org Git - clang/commitdiff
Fix filtering of prior declarations when checking for a tag redeclaration to
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 23 May 2016 20:03:04 +0000 (20:03 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 23 May 2016 20:03:04 +0000 (20:03 +0000)
map to the redecl context for both decls, not just one of them, and to properly
check that the decl contexts are equivalent.

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

lib/Sema/SemaDecl.cpp
test/SemaCXX/extern-c.cpp
test/SemaCXX/friend.cpp

index 9c442a61ce2e2f6cb6335233306977e887c2d8ac..81460418ca4ec2adea741160734e118b23a0fc46 100644 (file)
@@ -12338,7 +12338,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
       LookupResult::Filter F = Previous.makeFilter();
       while (F.hasNext()) {
         NamedDecl *ND = F.next();
-        if (ND->getDeclContext()->getRedeclContext() != SearchDC)
+        if (!ND->getDeclContext()->getRedeclContext()->Equals(
+                SearchDC->getRedeclContext()))
           F.erase();
       }
       F.done();
index 295d1f305ee28197a91d95af4cdd7b06d360304b..fa6c2b1990c073e089134a54eb1947c2ac207713 100644 (file)
@@ -204,3 +204,41 @@ extern "C" {
   struct pr5065_n6 : public virtual pr5065_3 {};
 }
 struct pr5065_n7 {};
+
+namespace tag_hiding {
+  namespace namespace_with_injected_name {
+    class Boo {
+      friend struct ExternCStruct1;
+    };
+    void ExternCStruct4(); // expected-note 2{{candidate}}
+  }
+
+  class Baz {
+    friend struct ExternCStruct2;
+    friend void ExternCStruct3();
+  };
+
+  using namespace namespace_with_injected_name;
+
+  extern "C" {
+    struct ExternCStruct1;
+    struct ExternCStruct2;
+    struct ExternCStruct3;
+    struct ExternCStruct4; // expected-note {{candidate}}
+  }
+  ExternCStruct1 *p1;
+  ExternCStruct2 *p2;
+  ExternCStruct3 *p3;
+  ExternCStruct4 *p4; // expected-error {{ambiguous}}
+
+  extern "C" {
+    struct ExternCStruct1;
+    struct ExternCStruct2;
+    struct ExternCStruct3;
+    struct ExternCStruct4; // expected-note {{candidate}}
+  }
+  ExternCStruct1 *q1 = p1;
+  ExternCStruct2 *q2 = p2;
+  ExternCStruct3 *q3 = p3;
+  ExternCStruct4 *q4 = p4; // expected-error {{ambiguous}}
+}
index a8e20439419fd3a0292f74aad6aa71ae0641d913..c90ce74616d6dea50a400b3b2c2e878dd2a68582 100644 (file)
@@ -363,3 +363,17 @@ void g_pr6954() {
   f_pr6954(5); // expected-error{{undeclared identifier 'f_pr6954'}}
 }
 
+namespace tag_redecl {
+  namespace N {
+    struct X *p;
+    namespace {
+      class K {
+        friend struct X;
+      };
+    }
+  }
+  namespace N {
+    struct X;
+    X *q = p;
+  }
+}