From: Richard Smith Date: Thu, 3 Dec 2015 23:24:04 +0000 (+0000) Subject: PR25731: namespace alias declarations can appear at block scope; ensure that we X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c0b5b91dffd6556647597bef238fbaa4dae69af0;p=clang PR25731: namespace alias declarations can appear at block scope; ensure that we do scope-based lookup when looking for redeclarations of them. Add some related missing checks for the scope-based redeclaration lookup: properly filter the list of found declarations to match the scope, and diagnose shadowing of a template parameter name. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@254663 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index eb010e9e39..3745641eb0 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8682,29 +8682,39 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, } } assert(!R.isAmbiguous() && !R.empty()); + NamedDecl *ND = R.getFoundDecl(); // Check if we have a previous declaration with the same name. LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName, ForRedeclaration); - LookupQualifiedName(PrevR, CurContext->getRedeclContext()); - NamedDecl *PrevDecl = PrevR.getAsSingle(); - if (PrevDecl && !isVisible(PrevDecl)) - PrevDecl = nullptr; + LookupName(PrevR, S); - NamedDecl *ND = R.getFoundDecl(); + // Check we're not shadowing a template parameter. + if (PrevR.isSingleResult() && PrevR.getFoundDecl()->isTemplateParameter()) { + DiagnoseTemplateParameterShadow(AliasLoc, PrevR.getFoundDecl()); + PrevR.clear(); + } + + // Filter out any other lookup result from an enclosing scope. + FilterLookupForScope(PrevR, CurContext, S, /*ConsiderLinkage*/false, + /*AllowInlineNamespace*/false); - if (PrevDecl) { + // Find the previous declaration and check that we can redeclare it. + NamespaceAliasDecl *Prev = nullptr; + if (NamedDecl *PrevDecl = PrevR.getAsSingle()) { if (NamespaceAliasDecl *AD = dyn_cast(PrevDecl)) { // We already have an alias with the same name that points to the same // namespace; check that it matches. - if (!AD->getNamespace()->Equals(getNamespaceDecl(ND))) { + if (AD->getNamespace()->Equals(getNamespaceDecl(ND))) { + Prev = AD; + } else if (isVisible(PrevDecl)) { Diag(AliasLoc, diag::err_redefinition_different_namespace_alias) << Alias; Diag(PrevDecl->getLocation(), diag::note_previous_namespace_alias) << AD->getNamespace(); return nullptr; } - } else { + } else if (isVisible(PrevDecl)) { unsigned DiagID = isa(PrevDecl) ? diag::err_redefinition : diag::err_redefinition_different_kind; @@ -8721,8 +8731,8 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc, Alias, SS.getWithLocInContext(Context), IdentLoc, ND); - if (PrevDecl) - AliasDecl->setPreviousDecl(cast(PrevDecl)); + if (Prev) + AliasDecl->setPreviousDecl(Prev); PushOnScopeChains(AliasDecl, S); return AliasDecl; diff --git a/test/CXX/temp/temp.res/temp.local/p6.cpp b/test/CXX/temp/temp.res/temp.local/p6.cpp index eccbb89932..06eb1bef7f 100644 --- a/test/CXX/temp/temp.res/temp.local/p6.cpp +++ b/test/CXX/temp/temp.res/temp.local/p6.cpp @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -verify %s -fcxx-exceptions -std=c++1y +namespace N {} + template struct X {}; // expected-error {{declaration of 'T' shadows template parameter}} -template struct Y { // expected-note 15{{declared here}} +template struct Y { // expected-note 16{{declared here}} template struct A {}; // expected-error {{declaration of 'T' shadows template parameter}} struct B { @@ -50,6 +52,9 @@ template struct Y { // expected-note 15{{declared here}} void d() { void T(); // expected-error {{declaration of 'T' shadows template parameter}} } + void e() { + namespace T = N; // expected-error {{declaration of 'T' shadows template parameter}} + } friend struct T; // expected-error {{declaration of 'T' shadows template parameter}} }; diff --git a/test/SemaCXX/namespace-alias.cpp b/test/SemaCXX/namespace-alias.cpp index 63615ecbd3..1cf820e3e3 100644 --- a/test/SemaCXX/namespace-alias.cpp +++ b/test/SemaCXX/namespace-alias.cpp @@ -125,3 +125,11 @@ namespace PR7014 { namespace Y = X::Y; } + +namespace PR25731 { + void f() { + namespace X = PR25731; + namespace X = PR25731; + X::f(); + } +}