From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id EE43838AAC19; Tue, 11 Jan 2022 14:47:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EE43838AAC19 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/103964] [9/10/11/12 Regression] OVS miscompilation since r0-92313-g5006671f1aaa63cd Date: Tue, 11 Jan 2022 14:47:39 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 12.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: RESOLVED X-Bugzilla-Resolution: INVALID X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 9.5 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 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Jan 2022 14:47:40 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D103964 --- Comment #9 from Jakub Jelinek --- (In reply to Ilya Maximets from comment #7) > (In reply to Jakub Jelinek from comment #6) > > What is the reason why OVS (and kernel) doesn't use 2 variables, one fo= r the > > iterator that is a pointer to the prev/next structure only and one assi= gned > > e.g. in the condition from the iterator that is used only when it isn't= the > > start? > > At least if targetting C99 and above (or C++) one can declare one of th= ose > > iterators in the for loop init expression... >=20 > The problem is that we need 2 variables and one of them need to be access= ible > outside of the loop. And I don't think it is possible to declare one > variable > and only initialize another one. If you only need to use one variable outside of the loop and not the other = one, that should be doable. If you use one in some spots and another in other s= pots but never both, you could have different macros for those 2 versions. E.g. the one where the list iterator is used inside of the loop only and the var pointing to the containing objects could look like: for (struct ovs_list *iter =3D (pos =3D NULL, &start); iter !=3D (&= start) && (((pos) =3D ((typeof(pos))(void*)((uintptr_t)((iter->next) - __builtin_offsetof(struct member, elem))))), 1); iter =3D iter->next, pos =3D NULL) which would get you after the loop pos =3D NULL if break; wasn't done and pos non-NULL otherwise. But in your testcase you actually need to use the other var after the loop, so it would need to be done the other way around, but then the user variable would need to be struct ovs_list * and the macro would need to be told in a different way what type the var declared in the loop should have. > One thing that is not clear to me is if the following code has an UB or n= ot: >=20 > struct member* pos; > struct ovs_list start; >=20 > pos =3D (struct member *)(void*)((uintptr_t)(&start) - 64); > ovs_list_insert((void *)((uintptr_t)pos + 64), &member->elem); It still creates a pointer out of something that doesn't point to such an object or points to some unrelated one, doesn't necessarily have sufficient alignment etc., so I think it is UB too, but perhaps the compiler at least = now will handle it the way you expect. A lot of programs including e.g. POSIX = rely on at least (void *) -1 and similar pointer constants to be usable in equality comparis= ons (e.g. MAP_FAILED macro).=