https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119933

Jiahao Xu <xujiahao at loongson dot cn> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rdubner at symas dot com

--- Comment #4 from Jiahao Xu <xujiahao at loongson dot cn> ---
All 120 unexpected failures appear to be caused by the warning:

warning: 'SECTION segment' requires '-dialect ibm' [-Wsegment]

This warning is emitted on LoongArch64, but not on x86_64 or AArch64.

Tracing the warning shows that it originates from the following code in the
generated parse.cc:

if ((yyvsp[0].string)
    && dialect_ok((yylsp[0]), IbmSectionSegmentW, "SECTION segment"))
{
    ...
}

On x86_64 and AArch64, yyvsp[0].string is NULL, so dialect_ok is not called. On
LoongArch64, however, yyvsp[0].string becomes a non-NULL invalid pointer,
causing the condition to evaluate as true and the warning to be emitted.

yyvsp[0] comes from yylval, which is a union whose first members are:

union YYSTYPE
{
    bool boolean;
    int number;
    char *string;
    ...
};

Before the check above, the lexer executes:

if (token == SECTION)
    yylval.number = 0;

On x86_64, the previous pointer value stored in the union typically has its
upper 32 bits equal to zero. After writing 0 to the number member, the same
storage is later observed as a null pointer when accessed through the string
member.

On LoongArch64, the previous pointer value often has non-zero upper 32 bits.
Writing 0 to the number member clears only the lower 32 bits, leaving the upper
32 bits unchanged. When the union storage is later interpreted as a char *, it
becomes a non-NULL invalid pointer (for example, 0x100000000), causing the
condition above to evaluate as true and the warning to be emitted.

As an experiment, I changed:

if (token == SECTION)
    yylval.number = 0;

to:

if (token == SECTION)
    yylval.string = NULL;

After this change, the warning disappears and all COBOL tests pass on both
x86_64 and LoongArch64.

I am not familiar enough with this part of the COBOL frontend to determine
whether this is the correct fix, but it appears that the current behavior
depends on reading a different union member from the one that was written, and
LoongArch64 exposes the issue because pointer values commonly have non-zero
upper 32 bits.

Reply via email to