[Mesa-dev] [PATCH 1/2] util: Fix foreach_list_typed_safe when exec_node is not at offset 0.

Matt Turner mattst88 at gmail.com
Mon Mar 9 19:58:15 PDT 2015


On Mon, Mar 9, 2015 at 7:32 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
>
>
> On Mon, Mar 9, 2015 at 7:24 PM, Matt Turner <mattst88 at gmail.com> wrote:
>>
>> On Mon, Mar 9, 2015 at 6:36 PM, Kenneth Graunke <kenneth at whitecape.org>
>> wrote:
>> > From: Jason Ekstrand <jason.ekstrand at intel.com>
>> >
>> > __next and __prev are pointers to the structure containing the exec_node
>> > link, not the embedded exec_node.  NULL checks would fail unless the
>> > embedded exec_node happened to be at offset 0 in the parent struct.
>> >
>> > Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
>> > Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
>> > ---
>> >  src/glsl/list.h | 4 ++--
>> >  1 file changed, 2 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/src/glsl/list.h b/src/glsl/list.h
>> > index ddb98f7..680e963 100644
>> > --- a/src/glsl/list.h
>> > +++ b/src/glsl/list.h
>> > @@ -684,7 +684,7 @@ inline void exec_node::insert_before(exec_list
>> > *before)
>> >             exec_node_data(__type, (__list)->head, __field),
>> > \
>> >                 * __next =
>> > \
>> >             exec_node_data(__type, (__node)->__field.next, __field);
>> > \
>> > -        __next != NULL;
>> > \
>> > +        &__next->__field != NULL;
>> > \
>>
>> I'm not understanding now the address of __next->__field can ever be NULL.
>>
>> __next is something with an embedded struct exec_node, so don't we
>> want "__next->__field != NULL" without the address-of operator?
>
>
> No, "__field" is the name of the exec_node field embedded in the __type
> struct.  So if I have
>
> struct foo {
>    /* stuff */
>    struct exec_node bar;
> }
>
> as my type, __type is "struct foo", __next and __node are both of type
> "__type *", and __field is "bar".  So, in order to get form __next to an
> exec_node, you have to do &__next->__field because we need the actual
> exec_node back.

More concretely, for something like:

      foreach_list_typed_safe (bblock_link, successor, link,
                               &predecessor->block->children)

I think this macro expands to (after this patch)

   for (bblock_link * successor =
           exec_node_data(bblock_link,
(&predecessor->block->children)->head, link),
               * __next =
           exec_node_data(bblock_link, (successor)->link.next, link);
        &__next->link != NULL;
        successor = __next, __next =
           exec_node_data(bblock_link, (__next)->link.next, link))

How can the address of a field in a struct (e.g., __next->link) be NULL?


More information about the mesa-dev mailing list