https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122922
--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Nathaniel Shead <[email protected]>: https://gcc.gnu.org/g:4bcb35f372ad750478199b02deabbdcfedaf199f commit r16-6262-g4bcb35f372ad750478199b02deabbdcfedaf199f Author: Nathaniel Shead <[email protected]> Date: Sat Dec 6 16:47:18 2025 +1100 c++/modules: Reattempt to complete ARRAY_TYPEs after reading a cluster [PR122922] The PR raises an issue where we complain about value-initializing an incomplete array type, where the element type is a complete type. Here, the friend declaration brings TTensor<0> and TTensor<1> into the same cluster, and we have no intra-cluster ordering that ensures TTensor<0>'s definition is streamed before TTensor<1>'s definition is. In general we don't currently do any ordering of definitions, we only reorder in cases that a declaration depends on another. In this particular case we happen to stream TTensor<1>'s definition first, which builds an array type of TTensor<0>. At this point TTensor<0>'s definition hasn't been streamed, so the array is considered to be an array of incomplete type. Later we do stream TTensor<0>'s definition, but we don't update the TYPE_SIZE etc. of the array type we built earlier so build_value_init thinks we still have incomplete type and errors. Some possible approaches: 1. Have some post-processing for arrays of incomplete type during module streaming; once we've finished reading the cluster we can loop through those array types and attempt to complete them. 2. Add a dependency ordering between structs that have a field that's a non-dependent array type of a different struct in the same cluster, so that the latter is always streamed first. We shouldn't see cycles because we cannot have two structs with arrays of each other. This would require processing definitions though and I'm not convinced this necessarily would fix the issue in all cases. 3. Add more calls to 'complete_type' when processing structure fields, rather than assuming that if we have a complete record type all its fields must also have been completed already. This seems error-prone though, as we may miss cases. Unless perhaps we replace uses of COMPLETE_TYPE_P entirely in the C++ frontend with a function that attempts to complete the type and returns false if it failed? This patch takes approach #1 as a minimal fix, but maybe it would be worth exploring other approaches later. PR c++/122922 gcc/cp/ChangeLog: * module.cc (trees_in::post_types): New member. (trees_in::trees_in): Initialize it. (trees_in::~trees_in): Clean it up. (trees_in::post_process_type): New functions. (trees_in::tree_node): Save incomplete ARRAY_TYPEs for later post-processing. (module_state::read_cluster): Attempt to complete any ARRAY_TYPEs we saved earlier. gcc/testsuite/ChangeLog: * g++.dg/modules/pr122922_a.C: New test. * g++.dg/modules/pr122922_b.C: New test. Signed-off-by: Nathaniel Shead <[email protected]> Reviewed-by: Jason Merrill <[email protected]>
