https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110772
Bug ID: 110772
Summary: strange code generated for bit-field access
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: roland.illig at gmx dot de
Target Milestone: ---
Target: arm
Created attachment 55598
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55598&action=edit
precompiled code that generates unrelated diagnostics
In NetBSD's lint, I changed 'struct type_qualifier' from an enum to a set of
bit-fields. It worked well on x86_64 but not on arm and powerpc.
https://github.com/NetBSD/src/commit/35c652085d26b93b94f55312f715361ee0cd2043
On these two 32-bit platforms, lint generated some unrelated and wrong
diagnostics.
I tracked the difference down to a single line of code, and changing that line
changes unrelated code.
In the attached p5.i, applying the following diff changes not only the code in
cgram.y:529, but also in cgram.y:489.
$ diff -u p5.i p3.i
--- p5.i 2023-07-22 00:22:30.748103516 +0200
+++ p3.i 2023-07-22 00:22:05.448298739 +0200
@@ -6424,7 +6424,7 @@
case 68:
# 528 "cgram.y"
{
- if (!yystack.l_mark[0].y_type_qualifiers.tq_const)
+ if (!yystack.l_mark[0].y_seen_statement)
yyerror("Bad attribute");
}
# 1 ""
$ gcc --version
gcc (nb2 20230710) 10.5.0
$ uname -mp
evbarm earmv7hfeb
$ gcc -O2 -S p5.i -fverbose-asm
$ gcc -O2 -S p3.i -fverbose-asm
$ gcc -O2 -c p5.i
$ gcc -O2 -c p3.i
$ objdump -dr p5.o > p5.dis
$ objdump -dr p3.o > p3.dis
$ diff -u p5.dis p3.dis
...
- ba8: e1b033a3 lsrs r3, r3, #7
+ ba8: e3530000 cmp r3, #0
...
- 1010: e1b033a3 lsrs r3, r3, #7
+ 1010: e3530000 cmp r3, #0
The code has changed in two places. Searching for the text "#7" in the p5.s
file shows that the two places where the code has changed are in cgram.y:529
and cgram.y:489.
I doubt that the code invokes undefined behavior, as it is fairly standard yacc
code. Therefore I suspect a compiler error.
Compiling the code with -Os or -O1 instead of -O2 does not show this behavior.
Removing the ':1' from the members in struct type_qualifier does not show this
behavior.
Compiling the code on x86_64 or i386 does not show this behavior.