diff options
author | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-09-20 00:05:04 +1000 |
---|---|---|
committer | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-09-28 09:00:31 +1000 |
commit | b9ac51a843f9dc807b00ab7f49f64968807a4ee8 (patch) | |
tree | 7534ce11573ba24cc239711f7c3d0643ecba1801 /gcc/cp | |
parent | cf9efe5ec14fea3ad5746fbefb22544bb9424d9d (diff) | |
download | gcc-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.cc | 12 |
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; } } |