The following makes sure to also walk CONSTRUCTOR element indexes which can be FIELD_DECLs, referencing otherwise unused types we need to clean. walk_tree only walks CONSTRUCTOR element data.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress, will push when that succeeds. Richard. PR lto/114501 * ipa-free-lang-data.cc (find_decls_types_r): Explicitly handle CONSTRUCTORs as walk_tree handling of those is incomplete. * g++.dg/pr114501_0.C: New testcase. --- gcc/ipa-free-lang-data.cc | 14 ++++++++++++++ gcc/testsuite/g++.dg/pr114501_0.C | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 gcc/testsuite/g++.dg/pr114501_0.C diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc index a865332ddf1..8c4fb3c6b64 100644 --- a/gcc/ipa-free-lang-data.cc +++ b/gcc/ipa-free-lang-data.cc @@ -846,6 +846,20 @@ find_decls_types_r (tree *tp, int *ws, void *data) fld_worklist_push (tem, fld); fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld); } + /* walk_tree does not visit ce->index which can be a FIELD_DECL, pulling + in otherwise unused structure fields so handle CTORs explicitly. */ + else if (TREE_CODE (t) == CONSTRUCTOR) + { + unsigned HOST_WIDE_INT idx; + constructor_elt *ce; + for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++) + { + if (ce->index) + fld_worklist_push (ce->index, fld); + fld_worklist_push (ce->value, fld); + } + *ws = 0; + } if (TREE_CODE (t) != IDENTIFIER_NODE && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)) diff --git a/gcc/testsuite/g++.dg/pr114501_0.C b/gcc/testsuite/g++.dg/pr114501_0.C new file mode 100644 index 00000000000..0439ee5f6e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr114501_0.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-require-effective-target c++17 } +// { dg-require-effective-target lto } +// { dg-options "-flto" } + +typedef long unsigned int size_t; +struct basic_string_view { + typedef long unsigned int size_type; + constexpr size_type size() const { return 0; } +}; +struct array { + char _M_elems[1]; +}; +inline constexpr auto make_it() { + constexpr basic_string_view view; + array arr{}; + arr._M_elems[view.size()] = 'a'; + return arr; +} +auto bar = make_it(); -- 2.43.0