aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-01-27 05:49:43 -0800
committerNathan Sidwell <nathan@acm.org>2020-01-27 06:33:35 -0800
commitfeaa1640b3543c7c3a1f3a788bc449a3638cb780 (patch)
treec800bf7a4aad4d9513a68f2d5ef086581580df19
parentf261388f1a9f8ee4abfefff32bdfe6046914b7f2 (diff)
downloadgcc-feaa1640b3543c7c3a1f3a788bc449a3638cb780.zip
gcc-feaa1640b3543c7c3a1f3a788bc449a3638cb780.tar.gz
gcc-feaa1640b3543c7c3a1f3a788bc449a3638cb780.tar.bz2
c++: Bogus error using namespace alias [PR91826]
My changes to is_nested_namespace broke is_ancestor's use where a namespace alias might be passed in. This changes is_ancestor to look through the alias. PR c++/91826 * name-lookup.c (is_ancestor): Allow CHILD to be a namespace alias.
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/name-lookup.c32
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr91826.C16
3 files changed, 41 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b51d67f..5324a6e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-27 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/91826
+ * name-lookup.c (is_ancestor): Allow CHILD to be a namespace alias.
+
2020-01-26 Jason Merrill <jason@redhat.com>
PR c++/90992
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 5721007..2447166 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4012,38 +4012,46 @@ is_nested_namespace (tree ancestor, tree descendant, bool inline_only)
return ancestor == descendant;
}
-/* Returns true if ROOT (a namespace, class, or function) encloses
- CHILD. CHILD may be either a class type or a namespace. */
+/* Returns true if ROOT (a non-alias namespace, class, or function)
+ encloses CHILD. CHILD may be either a class type or a namespace
+ (maybe alias). */
bool
is_ancestor (tree root, tree child)
{
- gcc_assert ((TREE_CODE (root) == NAMESPACE_DECL
- || TREE_CODE (root) == FUNCTION_DECL
- || CLASS_TYPE_P (root)));
- gcc_assert ((TREE_CODE (child) == NAMESPACE_DECL
- || CLASS_TYPE_P (child)));
+ gcc_checking_assert ((TREE_CODE (root) == NAMESPACE_DECL
+ && !DECL_NAMESPACE_ALIAS (root))
+ || TREE_CODE (root) == FUNCTION_DECL
+ || CLASS_TYPE_P (root));
+ gcc_checking_assert (TREE_CODE (child) == NAMESPACE_DECL
+ || CLASS_TYPE_P (child));
- /* The global namespace encloses everything. */
+ /* The global namespace encloses everything. Early-out for the
+ common case. */
if (root == global_namespace)
return true;
- /* Search until we reach namespace scope. */
+ /* Search CHILD until we reach namespace scope. */
while (TREE_CODE (child) != NAMESPACE_DECL)
{
/* If we've reached the ROOT, it encloses CHILD. */
if (root == child)
return true;
+
/* Go out one level. */
if (TYPE_P (child))
child = TYPE_NAME (child);
child = CP_DECL_CONTEXT (child);
}
- if (TREE_CODE (root) == NAMESPACE_DECL)
- return is_nested_namespace (root, child);
+ if (TREE_CODE (root) != NAMESPACE_DECL)
+ /* Failed to meet the non-namespace we were looking for. */
+ return false;
+
+ if (tree alias = DECL_NAMESPACE_ALIAS (child))
+ child = alias;
- return false;
+ return is_nested_namespace (root, child);
}
/* Enter the class or namespace scope indicated by T suitable for name
diff --git a/gcc/testsuite/g++.dg/lookup/pr91826.C b/gcc/testsuite/g++.dg/lookup/pr91826.C
new file mode 100644
index 0000000..2b313ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/pr91826.C
@@ -0,0 +1,16 @@
+// PR 91826 bogus error with aliased namespace
+
+namespace N1 { class C1; }
+namespace A1 = N1;
+class A1::C1 {}; //Ok
+
+namespace N2
+{
+ namespace N { class C2; }
+ namespace A2 = N;
+ class A2::C2 {}; // { dg_bogus "does not enclose" }
+}
+
+namespace N3 { namespace N { class C3; } }
+namespace A3 = N3::N;
+class A3::C3 {}; //Ok