Author: rsmith Date: Thu Dec 3 17:24:04 2015 New Revision: 254663 URL: http://llvm.org/viewvc/llvm-project?rev=254663&view=rev Log: 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.
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp cfe/trunk/test/SemaCXX/namespace-alias.cpp Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=254663&r1=254662&r2=254663&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Dec 3 17:24:04 2015 @@ -8682,29 +8682,39 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope } } 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<NamedDecl>(); - 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(); + } - if (PrevDecl) { + // Filter out any other lookup result from an enclosing scope. + FilterLookupForScope(PrevR, CurContext, S, /*ConsiderLinkage*/false, + /*AllowInlineNamespace*/false); + + // Find the previous declaration and check that we can redeclare it. + NamespaceAliasDecl *Prev = nullptr; + if (NamedDecl *PrevDecl = PrevR.getAsSingle<NamedDecl>()) { if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(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<NamespaceDecl>(PrevDecl) ? diag::err_redefinition : diag::err_redefinition_different_kind; @@ -8721,8 +8731,8 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc, Alias, SS.getWithLocInContext(Context), IdentLoc, ND); - if (PrevDecl) - AliasDecl->setPreviousDecl(cast<NamespaceAliasDecl>(PrevDecl)); + if (Prev) + AliasDecl->setPreviousDecl(Prev); PushOnScopeChains(AliasDecl, S); return AliasDecl; Modified: cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp?rev=254663&r1=254662&r2=254663&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp Thu Dec 3 17:24:04 2015 @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -verify %s -fcxx-exceptions -std=c++1y +namespace N {} + template<typename T, // expected-note {{declared here}} typename T> struct X {}; // expected-error {{declaration of 'T' shadows template parameter}} -template<typename T> struct Y { // expected-note 15{{declared here}} +template<typename T> struct Y { // expected-note 16{{declared here}} template<typename T> struct A {}; // expected-error {{declaration of 'T' shadows template parameter}} struct B { @@ -50,6 +52,9 @@ template<typename T> struct Y { // expec 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}} }; Modified: cfe/trunk/test/SemaCXX/namespace-alias.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/namespace-alias.cpp?rev=254663&r1=254662&r2=254663&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/namespace-alias.cpp (original) +++ cfe/trunk/test/SemaCXX/namespace-alias.cpp Thu Dec 3 17:24:04 2015 @@ -125,3 +125,11 @@ namespace PR7014 { namespace Y = X::Y; } + +namespace PR25731 { + void f() { + namespace X = PR25731; + namespace X = PR25731; + X::f(); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits