https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117423
Bug ID: 117423
Summary: union not written to with particular layout
Product: gcc
Version: 14.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: tpg+gcc at mutabah dot net
Target Milestone: ---
Created attachment 59524
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59524&action=edit
Preprocessed output of reproduction (2-20241102-TimeCodegenError.i) from
12.3.0-1ubuntu1~22.04
Found on ubuntu using 11.4.0-1ubuntu1~22.04, reproduced using
12.3.0-1ubuntu1~22.04, and then checked using godbolt to be present from 10.0
up to (latest) 14.2, but NOT on 9.5
Seen while debugging auto-generated code. When optimisations are enabled, a
particular union field isn't assigned - leading to use of uninitialised memory.
For the below code snippet (full source attached) the write of `var7` to
`rv.DATA.var_0._0` is not present in the final executable (as demonstrated by
the disassembly - and a runtime assertion failure).
>From my testing, the intermediate variable `var7` needs to exist, it needs to
be in a conditional branch, and the layout of the output union needs to have a
specific pattern.
```
#include <stdint.h>
#include <assert.h>
struct s_ZRG2cE18time0_3_29_H40000d4date4Date0g {
// /*@0*/struct s_ZRG3cE9core0_0_03num7nonzero10NonZeroI320g _0; //
::"core-0_0_0"::num::nonzero::NonZeroI32/*S*/
/*@0*/int32_t _0; // i32
} ;
struct
s_ZRG2cE9core0_0_06resultG9ResultErr2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
{
/*@0*/uint8_t _4; // bool
/*@8*/int64_t _1; // i64
} ;
struct
e_ZRG2cE9core0_0_06result6Result2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
{
union {
struct
s_ZRG2cE9core0_0_06resultG8ResultOk2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
{
/*@0*/uint8_t _1; // u8
/*@4*/struct s_ZRG2cE18time0_3_29_H40000d4date4Date0g
_0; // Required!
} var_0;
struct
s_ZRG2cE9core0_0_06resultG9ResultErr2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
var_1;
} DATA;
};
__attribute__ ((noinline)) int
ZRIG2cI17deranged0_3_8_H8110ranged_i329RangedI320v2gV4_0989e2ffV4_2cfe51003new0g_OP(int32_t
arg0);
//{ return arg0 > 12345; }
struct s_ZRG2cE18time0_3_29_H40000d4date4Date0g
ZRIG2cE18time0_3_29_H40000d4date4Date0g25from_julian_day_unchecked0g(int32_t
arg0);
//{ struct s_ZRG2cE18time0_3_29_H40000d4date4Date0g rv = { arg0 }; return rv; }
// <::"time-0_3_29_H40000d"::date::Date/*S*/ /*- */>::from_julian_day
struct
e_ZRG2cE9core0_0_06result6Result2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
ZRIG2cE18time0_3_29_H40000d4date4Date0g15from_julian_day0g(
int32_t arg0 // i32
) // ->
::"core-0_0_0"::result::Result<::"time-0_3_29_H40000d"::date::Date/*S*/,::"time-0_3_29_H40000d"::error::component_range::ComponentRange/*S*/,>/*E*/
{
struct
e_ZRG2cE9core0_0_06result6Result2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
rv;
struct
s_ZRG2cE9core0_0_06resultG9ResultErr2gG2cE18time0_3_29_H40000d4date4Date0gG3c_D5error15component_range14ComponentRange0g
var6 = {0};
struct s_ZRG2cE18time0_3_29_H40000d4date4Date0g var7;
if(
ZRIG2cI17deranged0_3_8_H8110ranged_i329RangedI320v2gV4_0989e2ffV4_2cfe51003new0g_OP(arg0)
) {
rv.DATA.var_1 = var6;
return rv;
}
else {
rv.DATA.var_0._1 = 2;
// Intermetdiate variable needed.
var7 =
ZRIG2cE18time0_3_29_H40000d4date4Date0g25from_julian_day_unchecked0g( arg0 );
rv.DATA.var_0._0 = var7;
return rv;
}
}
```
```
000000000000115e <ZRIG2cE18time0_3_29_H40000d4date4Date0g15from_julian_day0g>:
115e: f3 0f 1e fa endbr64
1162: 53 push %rbx
1163: 89 fb mov %edi,%ebx
1165: e8 df ff ff ff call 1149
<ZRIG2cI17deranged0_3_8_H8110ranged_i329RangedI320v2gV4_0989e2ffV4_2cfe51003new0g_OP>
116a: ba 00 00 00 00 mov $0x0,%edx
116f: 84 c0 test %al,%al
1171: 74 0e je 1181
<ZRIG2cE18time0_3_29_H40000d4date4Date0g15from_julian_day0g+0x23>
1173: b8 00 00 00 00 mov $0x0,%eax
1178: 88 d0 mov %dl,%al
117a: ba 00 00 00 00 mov $0x0,%edx
117f: 5b pop %rbx
1180: c3 ret
1181: 89 df mov %ebx,%edi
1183: e8 cf ff ff ff call 1157
<ZRIG2cE18time0_3_29_H40000d4date4Date0g25from_julian_day_unchecked0g>
1188: ba 02 00 00 00 mov $0x2,%edx
118d: eb e4 jmp 1173
<ZRIG2cE18time0_3_29_H40000d4date4Date0g15from_julian_day0g+0x15>
```