aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-09-20 00:05:04 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2024-09-28 09:00:31 +1000
commitb9ac51a843f9dc807b00ab7f49f64968807a4ee8 (patch)
tree7534ce11573ba24cc239711f7c3d0643ecba1801 /gcc/cp
parentcf9efe5ec14fea3ad5746fbefb22544bb9424d9d (diff)
downloadgcc-b9ac51a843f9dc807b00ab7f49f64968807a4ee8.zip
gcc-b9ac51a843f9dc807b00ab7f49f64968807a4ee8.tar.gz
gcc-b9ac51a843f9dc807b00ab7f49f64968807a4ee8.tar.bz2
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 <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/name-lookup.cc12
1 files changed, 7 insertions, 5 deletions
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index eb365b2..a2f94e0 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;
}
}