Commit 71bbbd13 by Nathan Sidwell Committed by Nathan Sidwell

PR c++/67074 - namespace aliases

	PR c++/67074 - namespace aliases
	* decl.c (duplicate_decls): Don't error here on mismatched
	namespace alias.
	* name-lookup.c (name_lookup::add_value): Matching namespaces are
	not ambiguous.
	(diagnose_name_conflict): Namespaces are never redeclarations.
	(update_binding): An alias can match a real namespace.

	PR c++/67074
	* g++.dg/lookup/pr67074.C: New.
	* g++.dg/parse/namespace-alias-1.C: Adjust.

From-SVN: r249408
parent 531f0b38
2017-06-20 Nathan Sidwell <nathan@acm.org>
PR c++/67074 - namespace aliases
* decl.c (duplicate_decls): Don't error here on mismatched
namespace alias.
* name-lookup.c (name_lookup::add_value): Matching namespaces are
not ambiguous.
(diagnose_name_conflict): Namespaces are never redeclarations.
(update_binding): An alias can match a real namespace.
2017-06-19 Jason Merrill <jason@redhat.com> 2017-06-19 Jason Merrill <jason@redhat.com>
PR c++/80562 - ICE with constexpr if. PR c++/80562 - ICE with constexpr if.
......
...@@ -1751,17 +1751,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1751,17 +1751,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
&& (DECL_NAMESPACE_ALIAS (newdecl) && (DECL_NAMESPACE_ALIAS (newdecl)
== DECL_NAMESPACE_ALIAS (olddecl))) == DECL_NAMESPACE_ALIAS (olddecl)))
return olddecl; return olddecl;
/* [namespace.alias]
/* Leave it to update_binding to merge or report error. */
A namespace-name or namespace-alias shall not be declared as return NULL_TREE;
the name of any other entity in the same declarative region.
A namespace-name defined at global scope shall not be
declared as the name of any other entity in any global scope
of the program. */
error ("conflicting declaration of namespace %q+D", newdecl);
inform (DECL_SOURCE_LOCATION (olddecl),
"previous declaration of namespace %qD here", olddecl);
return error_mark_node;
} }
else else
{ {
......
...@@ -450,7 +450,13 @@ name_lookup::add_value (tree new_val) ...@@ -450,7 +450,13 @@ name_lookup::add_value (tree new_val)
else if ((TREE_CODE (value) == TYPE_DECL else if ((TREE_CODE (value) == TYPE_DECL
&& TREE_CODE (new_val) == TYPE_DECL && TREE_CODE (new_val) == TYPE_DECL
&& same_type_p (TREE_TYPE (value), TREE_TYPE (new_val)))) && same_type_p (TREE_TYPE (value), TREE_TYPE (new_val))))
; /* Typedefs to the same type. */;
else if (TREE_CODE (value) == NAMESPACE_DECL
&& TREE_CODE (new_val) == NAMESPACE_DECL
&& ORIGINAL_NAMESPACE (value) == ORIGINAL_NAMESPACE (new_val))
/* Namespace (possibly aliased) to the same namespace. Locate
the namespace*/
value = ORIGINAL_NAMESPACE (value);
else else
{ {
if (deduping) if (deduping)
...@@ -1630,10 +1636,10 @@ static void ...@@ -1630,10 +1636,10 @@ static void
diagnose_name_conflict (tree decl, tree bval) diagnose_name_conflict (tree decl, tree bval)
{ {
if (TREE_CODE (decl) == TREE_CODE (bval) if (TREE_CODE (decl) == TREE_CODE (bval)
&& (TREE_CODE (decl) != TYPE_DECL && TREE_CODE (decl) != NAMESPACE_DECL
|| (DECL_ARTIFICIAL (decl) && DECL_ARTIFICIAL (bval))
|| (!DECL_ARTIFICIAL (decl) && !DECL_ARTIFICIAL (bval)))
&& !DECL_DECLARES_FUNCTION_P (decl) && !DECL_DECLARES_FUNCTION_P (decl)
&& (TREE_CODE (decl) != TYPE_DECL
|| DECL_ARTIFICIAL (decl) == DECL_ARTIFICIAL (bval))
&& CP_DECL_CONTEXT (decl) == CP_DECL_CONTEXT (bval)) && CP_DECL_CONTEXT (decl) == CP_DECL_CONTEXT (bval))
error ("redeclaration of %q#D", decl); error ("redeclaration of %q#D", decl);
else else
...@@ -1809,15 +1815,14 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot, ...@@ -1809,15 +1815,14 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
} }
else if (TREE_CODE (old) == NAMESPACE_DECL) else if (TREE_CODE (old) == NAMESPACE_DECL)
{ {
if (DECL_NAMESPACE_ALIAS (old) && DECL_NAMESPACE_ALIAS (decl) /* Two maybe-aliased namespaces. If they're to the same target
&& ORIGINAL_NAMESPACE (old) == ORIGINAL_NAMESPACE (decl)) namespace, that's ok. */
/* In a declarative region, a namespace-alias-definition can be if (ORIGINAL_NAMESPACE (old) != ORIGINAL_NAMESPACE (decl))
used to redefine a namespace-alias declared in that declarative
region to refer only to the namespace to which it already
refers. [namespace.alias] */
return old;
else
goto conflict; goto conflict;
/* The new one must be an alias at this point. */
gcc_assert (DECL_NAMESPACE_ALIAS (decl));
return old;
} }
else if (TREE_CODE (old) == VAR_DECL) else if (TREE_CODE (old) == VAR_DECL)
{ {
......
2017-06-20 Nathan Sidwell <nathan@acm.org>
PR c++/67074
* g++.dg/lookup/pr67074.C: New.
* g++.dg/parse/namespace-alias-1.C: Adjust.
2017-06-20 Richard Biener <rguenther@suse.de> 2017-06-20 Richard Biener <rguenther@suse.de>
PR middle-end/81097 PR middle-end/81097
......
// PR c++/67074 namespace aliases to the same place.
namespace P {
namespace X {
static int i = 1;
}
}
namespace Q {
namespace X = P::X;
}
using namespace P;
using namespace Q;
void Frob () { X::i; }
namespace N {}
namespace N = N;
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
namespace N namespace N
{ {
namespace M = N; // { dg-message "previous declaration" } namespace M = N; // { dg-message "previous declaration" }
namespace M {} // { dg-error "declaration of namespace" } namespace M {} // { dg-error "conflicts with a previous declaration" }
} }
namespace A namespace A
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment