From: Jakub Jelinek Date: Fri, 14 Feb 2025 11:01:13 +0000 (+0100) Subject: tree: Fix up the DECL_VALUE_EXPR GC marking [PR118790] X-Git-Tag: basepoints/gcc-16~2027 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=74ea20e16cf18b42071557b71a42ea31c8192425;p=thirdparty%2Fgcc.git tree: Fix up the DECL_VALUE_EXPR GC marking [PR118790] The ggc_set_mark call in gt_value_expr_mark_2 is actually wrong, that just marks the VAR_DECL itself, but doesn't mark the subtrees of it (type etc.). So, I think we need to test gcc_marked_p for whether it is marked or not, if not marked walk the DECL_VALUE_EXPR and then gt_ggc_mx mark the VAR_DECL that was determined not marked and needs to be marked now. One option would be to call gt_ggc_mx (t) right after the DECL_VALUE_EXPR walking, but I'm a little bit worried that the subtree marking could mark other VAR_DECLs (e.g. seen from DECL_SIZE or TREE_TYPE and the like) and if they would be DECL_HAS_VALUE_EXPR_P we might not walk their DECL_VALUE_EXPR anymore later. So, the patch defers the gt_ggc_mx calls until we've walked all the DECL_VALUE_EXPRs directly or indirectly connected to already marked VAR_DECLs. 2025-02-14 Jakub Jelinek PR debug/118790 * tree.cc (struct gt_value_expr_mark_data): New type. (gt_value_expr_mark_2): Don't call ggc_set_mark, instead check ggc_marked_p. Treat data as gt_value_expr_mark_data * with pset in it rather than address of the pset itself and push to be marked VAR_DECLs into to_mark vec. (gt_value_expr_mark_1): Change argument from hash_set * to gt_value_expr_mark_data * and find pset in it. (gt_value_expr_mark): Pass to traverse_noresize address of gt_value_expr_mark_data object rather than hash_table and for all entries in the to_mark vector after the traversal call gt_ggc_mx. --- diff --git a/gcc/tree.cc b/gcc/tree.cc index 4319f8d41e6..0743ed71c78 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -211,6 +211,11 @@ struct cl_option_hasher : ggc_cache_ptr_hash static GTY ((cache)) hash_table *cl_option_hash_table; +struct gt_value_expr_mark_data { + hash_set pset; + auto_vec to_mark; +}; + /* Callback called through walk_tree_1 to discover DECL_HAS_VALUE_EXPR_P VAR_DECLs which weren't marked yet, in that case marks them and walks their DECL_VALUE_EXPR expressions. */ @@ -219,11 +224,12 @@ static tree gt_value_expr_mark_2 (tree *tp, int *, void *data) { tree t = *tp; - if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t) && !ggc_set_mark (t)) + if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t) && !ggc_marked_p (t)) { tree dve = DECL_VALUE_EXPR (t); - walk_tree_1 (&dve, gt_value_expr_mark_2, data, - (hash_set *) data, NULL); + gt_value_expr_mark_data *d = (gt_value_expr_mark_data *) data; + walk_tree_1 (&dve, gt_value_expr_mark_2, data, &d->pset, NULL); + d->to_mark.safe_push (t); } return NULL_TREE; } @@ -232,10 +238,10 @@ gt_value_expr_mark_2 (tree *tp, int *, void *data) value_expr_for_decl hash table. */ int -gt_value_expr_mark_1 (tree_decl_map **e, hash_set *pset) +gt_value_expr_mark_1 (tree_decl_map **e, gt_value_expr_mark_data *data) { if (ggc_marked_p ((*e)->base.from)) - walk_tree_1 (&(*e)->to, gt_value_expr_mark_2, pset, pset, NULL); + walk_tree_1 (&(*e)->to, gt_value_expr_mark_2, data, &data->pset, NULL); return 1; } @@ -255,8 +261,11 @@ gt_value_expr_mark (hash_table *h) if (!h) return; - hash_set pset; - h->traverse_noresize *, gt_value_expr_mark_1> (&pset); + gt_value_expr_mark_data data; + h->traverse_noresize (&data); + for (auto v : data.to_mark) + gt_ggc_mx (v); } /* General tree->tree mapping structure for use in hash tables. */