[Mesa-dev] [PATCH 08/13] util/list: Add C99-based iterator macros
Jason Ekstrand
jason at jlekstrand.net
Tue May 5 11:36:35 PDT 2015
On Tue, May 5, 2015 at 11:13 AM, Neil Roberts <neil at linux.intel.com> wrote:
> Jason Ekstrand <jason at jlekstrand.net> writes:
>
>> +#define list_for_each_entry(type, pos, head, member) \
>> + for (type *pos = container_of((head)->next, pos, member); \
>> + &pos->member != (head); \
>> + pos = container_of(pos->member.next, pos, member))
>
> I think this is technically invalid. The container_of macro dereferences
> the pos pointer but at this point it is undefined so I think the
> compiler is allowed to do whatever it wants here. There is a comment
> above the container_of macro saying exactly that.
Right. I think I've come across that too. We also have a LIST_ELEM
(or maybe ITEM) macro in the file that does the type-based thing.
I'll fix it up to use that instead.
--Jason
> Some quick testing with clang shows that it actually takes advantage of
> this undefined behaviour and doesn't add the offset to pos to get the
> container and it all falls apart.
>
> A while ago we added the wayland linked-list implementation to Cogl and
> we ran into a similar problem. We actually ended up changing the
> container_of macro to take a type instead of a sample pointer because
> this is such an easy trap to fall into.
>
> https://git.gnome.org/browse/cogl/commit/?id=1efed1e0a2bce706eb490197
>
> Regards,
> - Neil
More information about the mesa-dev
mailing list