From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id A18143858CDA; Sat, 22 Jul 2023 15:21:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A18143858CDA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1690039291; bh=46FWKZKkIeWos+jCNo304rK8aL55q4vMQ2TuqB9Ky8E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=fpqM5oAi7ehGFgNNdDiCar55WtWVN4SeH1cl6vjlPEQlmMmp6DZqjC+Vhmp4Wo0EE qPg/dJkixl2r5X/PS5k9hACVfcAR2/JaLAB3PNKSbgCmHLpypRv66NoGE9QgxNvonG sXySFUY5DsY0uybfJMrZD8LDr07PARaHcU1y9cAg= From: "roland.illig at gmx dot de" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/110772] strange code generated for bit-field access Date: Sat, 22 Jul 2023 15:21:30 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: 10.5.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: roland.illig at gmx dot de X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D110772 --- Comment #5 from Roland Illig --- Sorry for the confusing description. Let me try again. NetBSD lint includes a yacc parser for C code. This parser contains the rul= es 'block_item_list' and 'block_item': https://github.com/NetBSD/src/blob/7ebcd1679b455e619909ec9c128e8ad7f103ded9= /usr.bin/xlint/lint1/cgram.y#L1804 > block_item_list: /* C99 6.8.2 */ > block_item > | block_item_list block_item { > if ($1 && !$2) > /* declarations after statements is a C99 feature */ > c99ism(327); > $$ =3D $1 || $2; > } The rule 'block_item' remembers in 'y_seen_statement' whether the item was a statement, so that the parser rule 'block_item_list' can warn in C90 mode. In another part of the parser, the rule 'gcc_attribute' handles the keyword 'const', by accessing 'y_type_qualifiers.tq_const', which on 2023-07-15 was= a _Bool bit-field member in 'struct type_qualifiers'. https://github.com/NetBSD/src/blob/7ebcd1679b455e619909ec9c128e8ad7f103ded9= /usr.bin/xlint/lint1/cgram.y#L2197 > gcc_attribute: > | type_qualifier { > if (!$1.tq_const) > yyerror("Bad attribute"); > } On big-endian arm and powerpc, the code that GCC 10.5.0 generates for the 'block_item_list' parser rule depends on whether the 'gcc_attribute' parser rule accesses a bit-field member or not. This does not make sense to me, as= I expect the parser rules to be independent. When I compile this parser on arm with -O2 and run lint in C90 mode, it not only warns about declarations after statements, but also about statements a= fter statements. $ gcc -O2 -ftrapv -fPIE -std=3Dgnu99 -S cgram.c -o cgram.casmv -fverbose-asm The code that is generated for the condition '$1 && !$2' is: > @ cgram.y:1802: if ($1 && !$2) > ldr r6, .L580+796 > add r6, pc, r6 > ldr r4, [r6, #20] > ldrb r3, [r4, #-8] @ $1.y_seen_statement > cmp r3, #0 > beq .L368 > @ cgram.y:550: $$ =3D build_unary($2 =3D=3D INC ? INCAFT : DECAF= T, $3, $1); > ldrb r3, [r4] > @ cgram.y:1802: > lsrs r3, r3, #7 @ $2.y_type_qualifiers.tq_const > beq .L562 (Annotations hand-edited by me.) Two strange things happen here: 1. The code from cgram.y:550 is completely unrelated, so it should not have been mentioned here. The 'ldrb' is correct, so maybe it's just the attribut= ion that is wrong. 2. The expressions '$1' and '$2' both have type _Bool. Nevertheless, the se= cond bool is accessed as if it were a bit-field. Due to this access, no matter whether '$2 as bool' is 1 or 0, the the expression '($2 as bit-field) >> 7' always evaluates to 0, so the condition '$1 && !$2' evaluates to true, which results in the additional warnings from lint. Instead of lsrs, GCC should have generated a cmp instruction. I don't have any other GCC version installed on the machine, so I cannot te= st whether GCC 11.4.0 behaves differently.=