https://gcc.gnu.org/g:b9ac51a843f9dc807b00ab7f49f64968807a4ee8

commit r15-3938-gb9ac51a843f9dc807b00ab7f49f64968807a4ee8
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Fri Sep 20 00:05:04 2024 +1000

    c++: Don't strip USING_DECLs when updating local bindings [PR116748]
    
    Currently update_binding strips USING_DECLs too eagerly, leading to ICEs
    in pop_local_decl as it can't find the decl it's popping in the binding
    list.  Let's rather try to keep the original USING_DECL around.
    
    This also means that using59.C can point to the location of the
    using-decl rather than the underlying object directly; this is in the
    direction required to fix PR c++/106851 (though more work is needed to
    emit properly helpful diagnostics here).
    
            PR c++/116748
    
    gcc/cp/ChangeLog:
    
            * name-lookup.cc (update_binding): Maintain USING_DECLs in the
            binding slots.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/lookup/using59.C: Update location.
            * g++.dg/lookup/using69.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/name-lookup.cc                 | 12 +++++++-----
 gcc/testsuite/g++.dg/lookup/using59.C |  4 ++--
 gcc/testsuite/g++.dg/lookup/using69.C | 10 ++++++++++
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index eb365b259d92..a2f94e0f363e 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -3005,6 +3005,8 @@ update_binding (cp_binding_level *level, cxx_binding 
*binding, tree *slot,
 
   if (old == error_mark_node)
     old = NULL_TREE;
+
+  tree old_bval = old;
   old = strip_using_decl (old);
 
   if (DECL_IMPLICIT_TYPEDEF_P (decl))
@@ -3021,7 +3023,7 @@ update_binding (cp_binding_level *level, cxx_binding 
*binding, tree *slot,
          gcc_checking_assert (!to_type);
          hide_type = hiding;
          to_type = decl;
-         to_val = old;
+         to_val = old_bval;
        }
       else
        hide_value = hiding;
@@ -3034,7 +3036,7 @@ update_binding (cp_binding_level *level, cxx_binding 
*binding, tree *slot,
       /* OLD is an implicit typedef.  Move it to to_type.  */
       gcc_checking_assert (!to_type);
 
-      to_type = old;
+      to_type = old_bval;
       hide_type = hide_value;
       old = NULL_TREE;
       hide_value = false;
@@ -3093,7 +3095,7 @@ update_binding (cp_binding_level *level, cxx_binding 
*binding, tree *slot,
        {
          if (same_type_p (TREE_TYPE (old), TREE_TYPE (decl)))
            /* Two type decls to the same type.  Do nothing.  */
-           return old;
+           return old_bval;
          else
            goto conflict;
        }
@@ -3106,7 +3108,7 @@ update_binding (cp_binding_level *level, cxx_binding 
*binding, tree *slot,
 
          /* The new one must be an alias at this point.  */
          gcc_assert (DECL_NAMESPACE_ALIAS (decl));
-         return old;
+         return old_bval;
        }
       else if (TREE_CODE (old) == VAR_DECL)
        {
@@ -3121,7 +3123,7 @@ update_binding (cp_binding_level *level, cxx_binding 
*binding, tree *slot,
       else
        {
        conflict:
-         diagnose_name_conflict (decl, old);
+         diagnose_name_conflict (decl, old_bval);
          to_val = NULL_TREE;
        }
     }
diff --git a/gcc/testsuite/g++.dg/lookup/using59.C 
b/gcc/testsuite/g++.dg/lookup/using59.C
index 3c3a73c28d59..b7ec325d2348 100644
--- a/gcc/testsuite/g++.dg/lookup/using59.C
+++ b/gcc/testsuite/g++.dg/lookup/using59.C
@@ -1,10 +1,10 @@
 
 namespace Y
 {
-  extern int I; //  { dg-message "previous declaration" }
+  extern int I;
 }
 
-using Y::I;
+using Y::I; // { dg-message "previous declaration" }
 extern int I; // { dg-error "conflicts with a previous" }
 
 extern int J;
diff --git a/gcc/testsuite/g++.dg/lookup/using69.C 
b/gcc/testsuite/g++.dg/lookup/using69.C
new file mode 100644
index 000000000000..7d52b73b9ce0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/using69.C
@@ -0,0 +1,10 @@
+// PR c++/116748
+
+namespace ns {
+  struct empty;
+}
+
+void foo() {
+  using ns::empty;
+  int empty;
+}

Reply via email to