On Fri, Feb 12, 2021 at 1:35 AM Martin Sebor via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > While trawling through old bugs I came across one from 2005: PR 21433 > - The COMPONENT_REF case of expand_expr_real_1 is probably wrong. > > The report looks correct in that argument 0 in COMPONENT_REF cannot > be a CONSTRUCTOR. In my tests it's only been one of the following > codes: > > array_ref > component_ref > mem_ref > parm_decl > result_decl > var_decl > > The attached patch removes the CONSTRUCTOR code and replaces it with > an assert verifying it doesn't come up there. Besides testing on > x86_64-linux, the change is supported by comments in code and also > in the internals manual (although that looks incorrect and should > be changed to avoid suggesting the first operand is a decl).
Note the CTOR operand is valid GENERIC and likely came up before we introduced GIMPLE. GIMPLE simply feeds more restrictive GENERIC to the RTL expansion routines nowadays (so the patch is OK eventually), but please avoid altering GENERIC or tree.def documentation which documents _GENERIC_. The restricted boundary of GIMPLE -> RTL expansion is not documented and in theory we might even run into your assert when processing global initializers (in case the CTOR ends up TREE_CONSTANT). > tree.def: > > /* Value is structure or union component. > Operand 0 is the structure or union (an expression). > Operand 1 is the field (a node of type FIELD_DECL). > Operand 2, if present, is the value of DECL_FIELD_OFFSET, measured > in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. */ > DEFTREECODE (COMPONENT_REF, "component_ref", tcc_reference, 3) > > generic.texi: > > @item COMPONENT_REF > These nodes represent non-static data member accesses. The first > operand is the object (rather than a pointer to it); the second operand > is the @code{FIELD_DECL} for the data member. The third operand represents > the byte offset of the field, but should not be used directly; call > @code{component_ref_field_offset} instead.