aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-05-26 18:13:53 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-05-26 18:13:53 +0000
commit945bf9e13f706bed44ec760ac60693e00c59b146 (patch)
tree1e04f598dbc5f8f70a5b6c8ed07b67188c211a11
parent3c9feefc8d6372d0e24070b53b40c2a36026e798 (diff)
downloadgcc-945bf9e13f706bed44ec760ac60693e00c59b146.zip
gcc-945bf9e13f706bed44ec760ac60693e00c59b146.tar.gz
gcc-945bf9e13f706bed44ec760ac60693e00c59b146.tar.bz2
Implement DR2061
gcc/ Implement DR2061 * name-lookup.c (push_inline_namespaces): New. (push_namespace): Look inside inline namespaces. testsuite/ * g++.dg/cpp0x/dr2061.C: New. * g++.dg/parse/namespace-alias-1.C: Add more test. From-SVN: r248521
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/name-lookup.c80
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/dr2061.C46
-rw-r--r--gcc/testsuite/g++.dg/parse/namespace-alias-1.C15
5 files changed, 115 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1890449..8e3530f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2017-05-26 Nathan Sidwell <nathan@acm.org>
+ Implement DR2061
+ * name-lookup.c (push_inline_namespaces): New.
+ (push_namespace): Look inside inline namespaces.
+
Inline and using namespace representation change.
* cp-tree.h (struct lang_decl_ns): Delete ns_using. Add usings,
inlinees as vector.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index dc03877..9c03901 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6057,6 +6057,23 @@ pushdecl_top_level_and_finish (tree x, tree init)
return x;
}
+/* Enter the namespaces from current_namerspace to NS. */
+
+static int
+push_inline_namespaces (tree ns)
+{
+ int count = 0;
+ if (ns != current_namespace)
+ {
+ gcc_assert (ns != global_namespace);
+ count += push_inline_namespaces (CP_DECL_CONTEXT (ns));
+ resume_scope (NAMESPACE_LEVEL (ns));
+ current_namespace = ns;
+ count++;
+ }
+ return count;
+}
+
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE,
then we enter an anonymous namespace. If MAKE_INLINE is true, then
we create an inline namespace (it is up to the caller to check upon
@@ -6076,43 +6093,36 @@ push_namespace (tree name, bool make_inline)
if (!name)
name = anon_identifier;
- /* Check whether this is an extended namespace definition. */
- tree ns = get_namespace_binding (current_namespace, name);
- if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
- {
- if (tree dna = DECL_NAMESPACE_ALIAS (ns))
- {
- /* We do some error recovery for, eg, the redeclaration of M
- here:
-
- namespace N {}
- namespace M = N;
- namespace M {}
-
- However, in nasty cases like:
-
- namespace N
- {
- namespace M = N;
- namespace M {}
- }
-
- we just error out below, in duplicate_decls. */
- if (NAMESPACE_LEVEL (dna)->level_chain == current_binding_level)
- {
- error ("namespace alias %qD not allowed here, "
- "assuming %qD", ns, dna);
- ns = dna;
- }
- else
- ns = NULL_TREE;
- }
- }
- else
- ns = NULL_TREE;
+ tree ns = NULL_TREE;
+ {
+ name_lookup lookup (name, 0);
+ if (!lookup.search_qualified (current_namespace, /*usings=*/false))
+ ;
+ else if (TREE_CODE (lookup.value) != NAMESPACE_DECL)
+ ;
+ else if (tree dna = DECL_NAMESPACE_ALIAS (lookup.value))
+ {
+ /* A namespace alias is not allowed here, but if the alias
+ is for a namespace also inside the current scope,
+ accept it with a diagnostic. That's better than dying
+ horribly. */
+ if (is_nested_namespace (current_namespace, CP_DECL_CONTEXT (dna)))
+ {
+ error ("namespace alias %qD not allowed here, "
+ "assuming %qD", lookup.value, dna);
+ ns = dna;
+ }
+ }
+ else
+ ns = lookup.value;
+ }
bool new_ns = false;
- if (!ns)
+ if (ns)
+ /* DR2061. NS might be a member of an inline namespace. We
+ need to push into those namespaces. */
+ count += push_inline_namespaces (CP_DECL_CONTEXT (ns));
+ else
{
ns = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
SCOPE_DEPTH (ns) = SCOPE_DEPTH (current_namespace) + 1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5136e4a..8eca177 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-26 Nathan Sidwell <nathan@acm.org>
+
+ * g++.dg/cpp0x/dr2061.C: New.
+ * g++.dg/parse/namespace-alias-1.C: Add more test.
+
2017-05-26 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/80815
diff --git a/gcc/testsuite/g++.dg/cpp0x/dr2061.C b/gcc/testsuite/g++.dg/cpp0x/dr2061.C
new file mode 100644
index 0000000..302279b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/dr2061.C
@@ -0,0 +1,46 @@
+// { dg-do compile { target c++11 } }
+
+// DR2061, look inside inline namespace when pushing a namespace.
+
+inline namespace One
+{
+ namespace Term
+ {
+ }
+ inline namespace Two
+ {
+ namespace Space
+ {
+ }
+ }
+}
+
+namespace Term
+{
+ void bob ();
+}
+
+namespace Space
+{
+ void bill ();
+}
+
+inline namespace Two
+{
+ void weed ();
+}
+
+void One::Term::bob () {}
+void One::Two::Space::bill () {}
+void One::Two::weed () {}
+
+void Thing ()
+{
+ Term::bob ();
+ Space::bill ();
+ weed ();
+}
+
+// { dg-final { scan-assembler "_ZN3One4Term3bobEv:" } }
+// { dg-final { scan-assembler "_ZN3One3Two5Space4billEv:" } }
+// { dg-final { scan-assembler "_ZN3One3Two4weedEv:" } }
diff --git a/gcc/testsuite/g++.dg/parse/namespace-alias-1.C b/gcc/testsuite/g++.dg/parse/namespace-alias-1.C
index 4b44335..5986ab6 100644
--- a/gcc/testsuite/g++.dg/parse/namespace-alias-1.C
+++ b/gcc/testsuite/g++.dg/parse/namespace-alias-1.C
@@ -5,3 +5,18 @@ namespace N
namespace M = N; // { dg-message "previous declaration" }
namespace M {} // { dg-error "declaration of namespace" }
}
+
+namespace A
+{
+ namespace B
+ {
+ namespace C
+ {
+ }
+ }
+
+ namespace D = B::C;
+ namespace D // { dg-error "not allowed" }
+ {
+ }
+}