diff options
author | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-05-03 19:36:17 +1000 |
---|---|---|
committer | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-05-07 11:37:47 +1000 |
commit | ec2365e07537e8b17745d75c28a2b45bf33be119 (patch) | |
tree | 370bdfd1a2943e9a7f8a521db213c7df37aa57bb /gcc/cp/module.cc | |
parent | f56280d57fb6e2bb131f00ef66842f942cd0d01a (diff) | |
download | gcc-ec2365e07537e8b17745d75c28a2b45bf33be119.zip gcc-ec2365e07537e8b17745d75c28a2b45bf33be119.tar.gz gcc-ec2365e07537e8b17745d75c28a2b45bf33be119.tar.bz2 |
c++/modules: Fix dangling pointer with imported_temploid_friends
I got notified by Linaro CI and by checking testresults that there seems
to be some occasional failures in tpl-friend-4_b.C on some architectures
and standards modes since r15-59-gb5f6a56940e708. I haven't been able
to reproduce but looking at the backtrace I suspect the issue is that
we're adding to the 'imported_temploid_friend' map a decl that is
ultimately discarded, which then has its address reused by a later decl
causing a failure in the assert in 'set_originating_module'.
This patch fixes the problem by ensuring 'imported_temploid_friends' is
correctly marked as a GTY root, and that 'duplicate_decls' properly
removes entries from the map for declarations that it frees.
PR c++/114275
gcc/cp/ChangeLog:
* cp-tree.h (remove_defining_module): Declare.
* decl.cc (duplicate_decls): Call remove_defining_module on
to-be-freed newdecl.
* module.cc (imported_temploid_friends): Mark as GTY root...
(init_modules): ...and allocate from ggc.
(trees_in::decl_value): Only track for declarations that won't
be discarded.
(remove_defining_module): New function.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Diffstat (limited to 'gcc/cp/module.cc')
-rw-r--r-- | gcc/cp/module.cc | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 44dc81e..520dd71 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2731,7 +2731,7 @@ static keyed_map_t *keyed_table; need to be attached to the same module as the temploid. This maps these decls to the temploid they are instantiated them, as there is no other easy way to get this information. */ -static hash_map<tree, tree> *imported_temploid_friends; +static GTY((cache)) decl_tree_cache_map *imported_temploid_friends; /********************************************************************/ /* Tree streaming. The tree streaming is very specific to the tree @@ -8327,7 +8327,8 @@ trees_in::decl_value () if (TREE_CODE (inner) == FUNCTION_DECL || TREE_CODE (inner) == TYPE_DECL) if (tree owner = tree_node ()) - imported_temploid_friends->put (decl, owner); + if (is_new) + imported_temploid_friends->put (decl, owner); /* Regular typedefs will have a NULL TREE_TYPE at this point. */ unsigned tdef_flags = 0; @@ -19336,6 +19337,18 @@ propagate_defining_module (tree decl, tree orig) } } +/* DECL is being freed, clear data we don't need anymore. */ + +void +remove_defining_module (tree decl) +{ + if (!modules_p ()) + return; + + if (imported_temploid_friends) + imported_temploid_friends->remove (decl); +} + /* Create the flat name string. It is simplest to have it handy. */ void @@ -20550,7 +20563,7 @@ init_modules (cpp_reader *reader) entity_map = new entity_map_t (EXPERIMENT (1, 400)); vec_safe_reserve (entity_ary, EXPERIMENT (1, 400)); imported_temploid_friends - = new hash_map<tree,tree> (EXPERIMENT (1, 400)); + = decl_tree_cache_map::create_ggc (EXPERIMENT (1, 400)); } #if CHECKING_P |