https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94436
Bug ID: 94436 Summary: incompatible-pointer-types warning with container_of Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: regression Assignee: unassigned at gcc dot gnu.org Reporter: npfhrotynz-ptnqh.myvf at noclue dot notk.org Target Milestone: --- Created attachment 48157 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48157&action=edit test program.c This looks like a regression in warnings: passing an argument straight from a container_of construct fails with incompatible type warning. In the attached code, the if 0'd implementation taken from the linux kernel works, but the other one also seen in the linux kernel (why do they have multiple implementations?!) produces the following warning: ------------ t.c: In function ‘main’: t.c:14:41: warning: passing argument 1 of ‘func’ from incompatible pointer type [-Wincompatible-pointer-types] 14 | #define container_of(ptr, type, member) (type *)((char *)(ptr) - (char *) &((type *)0)->member) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | char * t.c:24:14: note: in expansion of macro ‘container_of’ 24 | return func(container_of(&bar, struct foo, bar)); | ^~~~~~~~~~~~ t.c:17:22: note: expected ‘struct foo *’ but argument is of type ‘char *’ 17 | int func(struct foo* foo) { | ~~~~~~~~~~~~^~~ ------------- Here is -E preprocessed interesting line: return func((struct foo *)((char *)(&bar) - (char *) &((struct foo *)0)->bar)); For me the whole thing is cast with (struct foo*) so it should silence that warning as it used to do (tested with gcc 7.4.0 and gcc 9.2.0) In the case I'm looking at I could work around by using the other implementation, but I see that macro defined all the time so would be interested in seeing the old behaviour back. Thanks!