https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96024
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|FIXED |--- CC| |jakub at gcc dot gnu.org --- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The new testcase seems to fail on big-endian hosts. I've analyzed this on 11 branch: 3190 /* For a constant string constructor, make sure the length is 3191 correct; truncate of fill with blanks if needed. */ 3192 if (this_comp->ts.type == BT_CHARACTER && !this_comp->attr.allocatable 3193 && this_comp->ts.u.cl && this_comp->ts.u.cl->length 3194 && this_comp->ts.u.cl->length->expr_type == EXPR_CONSTANT 3195 && actual->expr->ts.type == BT_CHARACTER 3196 && actual->expr->expr_type == EXPR_CONSTANT) 3197 { 3198 ptrdiff_t c, e1; 3199 c = gfc_mpz_get_hwi (this_comp->ts.u.cl->length->value.integer); 3200 e1 = actual->expr->value.character.length; 3201 3202 if (c != e1) 3203 { 3204 ptrdiff_t i, to; 3205 gfc_char_t *dest; 3206 dest = gfc_get_wide_string (c + 1); *this_comp->ts.u.cl->length $20 = {expr_type = EXPR_CONSTANT, ts = {type = BT_CHARACTER, kind = 1 ... } Because it is a BT_CHARACTER EXPR_CONSTANTS, simplify_achar_char initialized it as 813 result = gfc_get_character_expr (kind, &e->where, NULL, 1); 814 result->value.character.string[0] = mpz_get_ui (e->value.integer); i.e. using the value.character union member. But the code assumes it is an integral constant instead and uses value.integer instead. p this_comp->ts.u.cl->length->value.character $22 = {length = 1, string = 0x2aa02ab2de0} where string points to array of unsigned int, big endian, so contains value 0x00000001 followed by garbage, which happens to be 0, so bytes 0, 0, 0, 1, 0, 0, 0, 0 Now p this_comp->ts.u.cl->length->value.integer $23 = {{_mp_alloc = 0, _mp_size = 1, _mp_d = 0x2aa02ab2de0}} (note, _mp_alloc and _mp_size are both 32-bit while length is 64-bit) and _mp_d points to array of mp_limb_t, which is unsigned long. So, this means c is 0x100000000 and we try to allocate 0x100000001 * 4 bytes == 17179869188. Now, on x86_64 string also points to array of unsigned int, but because it is little endian, the value 1 is there 1, 0, 0, 0, 0, 0, 0, 0, 0 (the last 4 bytes random garbage), so c is 1 rather than 0x100000000 and it allocates 2 * 4 bytes. So, presumably we need in addition to the && this_comp->ts.u.cl->length->expr_type == EXPR_CONSTANT check also test that the constant uses value.integer union member rather than some other one. Would && this_comp->ts.u.cl->length->ts.type == BT_INTEGER be the right test for it or something else?