aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-06-20 12:53:11 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-06-20 12:53:11 +0000
commit71bbbd133f65c26f65709037401154362210560e (patch)
tree4d79c576c152bbe5c57dca0fa48467a3aec04c20 /gcc
parent531f0b3879b09b53d738b5bf84790c49bdd60977 (diff)
downloadgcc-71bbbd133f65c26f65709037401154362210560e.zip
gcc-71bbbd133f65c26f65709037401154362210560e.tar.gz
gcc-71bbbd133f65c26f65709037401154362210560e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/decl.c14
-rw-r--r--gcc/cp/name-lookup.c29
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr67074.C18
-rw-r--r--gcc/testsuite/g++.dg/parse/namespace-alias-1.C2
6 files changed, 55 insertions, 24 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 10d1ebd..3ed58b2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+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>
PR c++/80562 - ICE with constexpr if.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 16cd2a5..bb7c56f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1751,17 +1751,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
&& (DECL_NAMESPACE_ALIAS (newdecl)
== DECL_NAMESPACE_ALIAS (olddecl)))
return olddecl;
- /* [namespace.alias]
-
- A namespace-name or namespace-alias shall not be declared as
- 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;
+
+ /* Leave it to update_binding to merge or report error. */
+ return NULL_TREE;
}
else
{
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e91b89c..54c9d7b 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -450,7 +450,13 @@ name_lookup::add_value (tree new_val)
else if ((TREE_CODE (value) == TYPE_DECL
&& TREE_CODE (new_val) == TYPE_DECL
&& 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
{
if (deduping)
@@ -1630,10 +1636,10 @@ static void
diagnose_name_conflict (tree decl, tree bval)
{
if (TREE_CODE (decl) == TREE_CODE (bval)
- && (TREE_CODE (decl) != TYPE_DECL
- || (DECL_ARTIFICIAL (decl) && DECL_ARTIFICIAL (bval))
- || (!DECL_ARTIFICIAL (decl) && !DECL_ARTIFICIAL (bval)))
+ && TREE_CODE (decl) != NAMESPACE_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))
error ("redeclaration of %q#D", decl);
else
@@ -1809,15 +1815,14 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
}
else if (TREE_CODE (old) == NAMESPACE_DECL)
{
- if (DECL_NAMESPACE_ALIAS (old) && DECL_NAMESPACE_ALIAS (decl)
- && ORIGINAL_NAMESPACE (old) == ORIGINAL_NAMESPACE (decl))
- /* In a declarative region, a namespace-alias-definition can be
- 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
+ /* Two maybe-aliased namespaces. If they're to the same target
+ namespace, that's ok. */
+ if (ORIGINAL_NAMESPACE (old) != ORIGINAL_NAMESPACE (decl))
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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 28c97de..ee1a4e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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>
PR middle-end/81097
diff --git a/gcc/testsuite/g++.dg/lookup/pr67074.C b/gcc/testsuite/g++.dg/lookup/pr67074.C
new file mode 100644
index 0000000..ce31ede
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/pr67074.C
@@ -0,0 +1,18 @@
+// 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;
diff --git a/gcc/testsuite/g++.dg/parse/namespace-alias-1.C b/gcc/testsuite/g++.dg/parse/namespace-alias-1.C
index 5986ab6..220d5f9 100644
--- a/gcc/testsuite/g++.dg/parse/namespace-alias-1.C
+++ b/gcc/testsuite/g++.dg/parse/namespace-alias-1.C
@@ -3,7 +3,7 @@
namespace N
{
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