Fix filtering of prior declarations when checking for a tag redeclaration to

map to the redecl context for both decls, not just one of them, and to properly
check that the decl contexts are equivalent.

llvm-svn: 270482
This commit is contained in:
Richard Smith 2016-05-23 20:03:04 +00:00
parent f3c8f532d2
commit cc1b82be17
3 changed files with 54 additions and 1 deletions

View File

@ -12338,7 +12338,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
LookupResult::Filter F = Previous.makeFilter(); LookupResult::Filter F = Previous.makeFilter();
while (F.hasNext()) { while (F.hasNext()) {
NamedDecl *ND = F.next(); NamedDecl *ND = F.next();
if (ND->getDeclContext()->getRedeclContext() != SearchDC) if (!ND->getDeclContext()->getRedeclContext()->Equals(
SearchDC->getRedeclContext()))
F.erase(); F.erase();
} }
F.done(); F.done();

View File

@ -204,3 +204,41 @@ extern "C" {
struct pr5065_n6 : public virtual pr5065_3 {}; struct pr5065_n6 : public virtual pr5065_3 {};
} }
struct pr5065_n7 {}; 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}}
}

View File

@ -363,3 +363,17 @@ void g_pr6954() {
f_pr6954(5); // expected-error{{undeclared identifier 'f_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;
}
}