diff options
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 30 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.res/temp.local/p6.cpp | 7 | ||||
-rw-r--r-- | clang/test/SemaCXX/namespace-alias.cpp | 8 |
3 files changed, 34 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index eb010e9e39a..3745641eb01 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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<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(); + } + + // 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<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 *S, SourceLocation NamespaceLoc, 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; diff --git a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp index eccbb899321..06eb1bef7fe 100644 --- a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp +++ b/clang/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<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 { // 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/clang/test/SemaCXX/namespace-alias.cpp b/clang/test/SemaCXX/namespace-alias.cpp index 63615ecbd35..1cf820e3e38 100644 --- a/clang/test/SemaCXX/namespace-alias.cpp +++ b/clang/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(); + } +} |