C++: Unshare RANGE_EXPR indices in constructors to fix mutation issues
Fixes a bug where modifying array element initializers corrupted shared constructor trees.
A bug in C++‘s constructor handling, specifically when unsharing CONSTRUCTOR trees for array elements, has been resolved. The issue stemmed from RANGE_EXPR indices remaining shared after a shallow copy. This commit ensures that RANGE_EXPR indices are also copied, preventing modifications in one constructor from affecting others and thus avoiding incorrect initialization omissions.
In Details
The unshare_constructor function performs a shallow copy of CONSTRUCTOR trees. When build_vec_init creates a RANGE_EXPR index for array elements with shared initializers, this index remained shared after unshare_constructor. Subsequent mutations by find_array_ctor_elt to split the RANGE_EXPR would then incorrectly modify the original shared tree, leading to potential initialization omissions via NSDMI. Copying RANGE_EXPR indexes resolves this by ensuring distinct constructors.
- RANGE_EXPR
- An expression in GCC's internal representation that denotes a range of values, often used for array initializers.
- CONSTRUCTOR
- An internal GCC tree node representing an aggregate initializer, used for arrays and structures.
- unshare_constructor
- A GCC internal function that creates a distinct copy of a
CONSTRUCTORtree, intended to prevent unintended modifications to shared data. - build_vec_init
- A GCC internal function involved in building initializers for arrays or vectors.
- NSDMI
- In C++, Non-static data member initialization. This refers to initializers for members defined directly within a class definition.