summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp30
-rw-r--r--clang/test/CXX/temp/temp.res/temp.local/p6.cpp7
-rw-r--r--clang/test/SemaCXX/namespace-alias.cpp8
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();
+ }
+}
OpenPOWER on IntegriCloud