https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103965
Bug ID: 103965
Summary: optimizer (-O2) changes behavior in cast-to-container
iteration
Product: gcc
Version: 11.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: amorenoz at redhat dot com
Target Milestone: ---
Created attachment 52155
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52155&action=edit
test case that returns 0 when working fine and 1 when broken
Hi,
The attached test-case has been extracted from openvswitch source code. Macros
have been expanded and code has been simplified as much as possible.
The problematic code is a cast-to-container list iteration that uses a
stack-allocated list element without containing object:
struct member {
int padding[14];
int order;
struct ovs_list elem;
};
[...]
struct ovs_list start;
struct member *member *members[2];
for (i = 0; i < 2; i++) {
struct member* pos;
member = members[i];
for (((pos) = ((void*)0),
((pos) = ((typeof(pos))(void*)((uintptr_t)((&start)->next) -
__builtin_offsetof(struct member,
elem)))));
&(pos)->elem != (&start);
((pos) = ((typeof(pos))(void*)((uintptr_t)((pos)->elem.next) -
__builtin_offsetof(struct member,
elem))))) {
if (member->order > pos->order) {
break;
}
}
ovs_list_insert(&pos->elem, &member->elem);
}
When "-O2" is used, gcc seems to just optimize out one of the iterations.
Interestingly, replacing the pointer arithmetics with integer arithmetics still
makes the code fail.
Is this a bug in gcc? or is this just invalid C code? and if so, why?