[gcc(refs/vendors/redhat/heads/gcc-8-branch)] c++: Bogus error using namespace alias [PR91826]

Jakub Jelinek jakub@gcc.gnu.org
Thu Sep 17 16:37:09 GMT 2020


https://gcc.gnu.org/g:112dcf70e29abf3c217aea4cfdf722db67d88f79

commit 112dcf70e29abf3c217aea4cfdf722db67d88f79
Author: Nathan Sidwell <nathan@acm.org>
Date:   Mon Jan 27 05:49:43 2020 -0800

    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.

Diff:
---
 gcc/cp/ChangeLog                      |  5 +++++
 gcc/cp/name-lookup.c                  | 32 ++++++++++++++++++++------------
 gcc/testsuite/g++.dg/lookup/pr91826.C | 16 ++++++++++++++++
 3 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3eff9839cf8..f9b02d0309b 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-24  Jason Merrill  <jason@redhat.com>
 
 	PR c++/92852 - ICE with generic lambda and reference var.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 7b82f90c835..3f8e4a0e3a8 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4198,38 +4198,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 00000000000..2b313ece8a7
--- /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


More information about the Gcc-cvs mailing list