[llvm-dev] broken C code only when optimized "-O2"
Adrian Moreno via llvm-dev
llvm-dev at lists.llvm.org
Wed Dec 22 02:05:25 PST 2021
Hi,
I have a suspicion of what could be causing the problem, I'd like to run through
you to get your feedback from the compiler pov.
One of the things that originally felt smelly was that the fact that the macros
that iterate the list elements assume the "struct ovs_list" element is embedded
into another "struct member":
struct member *pos = 0;
for ((((pos) = ((struct member *) (void *) ((uintptr_t)(void *)((&start)->next)
- __builtin_offsetof (struct member, elem)))));
&(pos)->elem != (&start);
((pos) = ((struct member *) (void *) ((uintptr_t)(void
*)((pos)->elem.next) - __builtin_offsetof (struct member , elem)
)))) {
[... use pos ]
}
however, the first node in the list ("start") is a "struct ovs_list" defined in
the stack and _not_ embedded into a "struct member".
Therefore, "(&start)->next - __builtin_offsetof (struct member, elem)" actually
points to somewhere in the stack that contains who knows what. (Note: initially
start->next = start)
In fact, if I make the struct offsets zero:
struct member {
struct ovs_list elem;
[ ... ]
int order;
};
... the code works. However if I use:
struct member {
int padding[10];
struct ovs_list elem;
[ ... ]
int order;
};
... the code fails.
Does anything of what I'm saying make sense so far?
If the code inside the loop just made use of "pos" through "(&pos->elem)" then
the compiler could(?) be ok with it but the loop actually contains:
if (member->order > pos->order) {
break;
}
So here I do not know what the compiler would think about "pos" if it happens to
point to some invalid stack address.
Thanks for the help.
--
Adrián Moreno
More information about the llvm-dev
mailing list