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

Jason Ekstrand jason at jlekstrand.net
Mon Mar 9 20:00:49 PDT 2015


On Mon, Mar 9, 2015 at 7:58 PM, Matt Turner <mattst88 at gmail.com> wrote:

> 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?
>

If the address of the struct is (void *)-8 and the link field is 8 bytes
into the struct.  In this case, assuming unsigned overflow (I think that's
reasonably safe), the address of the link will be (void *)0
--Jason
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150309/15f76722/attachment.html>


More information about the mesa-dev mailing list