[Mesa-dev] [PATCH] Fix strict-aliasing violations in GLSL shader list implementation
Davin McCall
davmac at davmac.org
Wed Jun 24 15:59:36 PDT 2015
Hi Ian,
On 23/06/15 23:26, Ian Romanick wrote:
> On 06/23/2015 02:36 PM, Thomas Helland wrote:
>> 2015-06-24 23:05 GMT+02:00 Davin McCall <davmac at davmac.org>:
>>> Hi - I'm new here.
>>>
>>> I've recently started poking the Mesa codebase for little reason other than
>>> personal interest. In the "help wanted" section of the website it mentions
>>> aliasing violations as a target for newcomers to fix, so with that in mind
>>> I've attached a patch (against git head) which resolves a few of them, by
>>> targeting the linked list implementation (list.h) used in the GLSL
>>> compiler/optimizers. This change slightly increases the storage requirements
>>> for a list (adds one word) but resolves the blatant aliasing violation that
>>> was caused by the trick used to conserve that word in the first place.
>>>
>>> (I toyed with another approach - using a single sentinel node for both the
>>> head and tail of a list - but this was much more invasive, and meant that
>>> you could no longer check whether a particular node was a sentinel node
>>> unless you had a reference to the list, so I gave up and went with this
>>> simpler approach).
>>>
>>> The most essential change is in the 'exec_list' structure. Three fields
>>> 'head', 'tail' and 'tail_pred' are removed, and two separate sentinel nodes
>>> are inserted in their place. The old 'head' is replaced by
>>> 'head_sentinel.next', 'tail_pred' by 'tail_sentinel.prev', and tail (always
>>> NULL) by 'head_sentinel.prev' and 'tail_sentinel.next' (both always NULL).
> NAK. The datastructure is correct as-is. It has been in common use
> since at least 1985. See the references in the header file.
I understand the data structure and how it is supposed to work; the
issue is that the trick it employs cannot be implemented in C without
breaking the strict aliasing rules (or at least, the current
implementation in Mesa breaks the strict aliasing rules). The current
code works correctly only with the -fno-strict-aliasing compiler option.
The issue is that a pair of 'exec_node *' do not constitute an exec_node
in the eyes of the language spec, even though exec_node is declared as
holding two such pointers. Consider (from src/glsl/list.h):
static inline void
exec_list_make_empty(struct exec_list *list)
{
list->head = (struct exec_node *) & list->tail;
list->tail = NULL;
list->tail_pred = (struct exec_node *) & list->head;
}
'list->head' is of type 'struct exec_node *', and so should point at a
'struct exec_node'. In the code above it is instead co-erced to point
at a 'struct exec_node *' (list->tail). That in itself doesn't break the
alias rules, but then:
static inline bool
exec_node_is_tail_sentinel(const struct exec_node *n)
{
return n->next == NULL;
}
In 'exec_node_is_tail_sentinel', the sentinel is not actually an
exec_node - it is &list->tail. So, if the parameter n does refer to the
sentinel, then it does not point to an actual exec_node structure.
However, it is de-referenced (by 'n->next') which breaks the strict
aliasing rules. This means that the method above can only ever return
false, unless it violates the aliasing rules.
(The above method could be fixed by casting n to an 'struct exec_node
**' and then comparing '**n' against NULL. However, there are other
similar examples throughout the code that I do not think would be so
trivial).
I can quote the relevant parts of the standard if necessary, but your
tone somewhat implies that you wouldn't even consider this patch?
Davin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150624/d1f307da/attachment.html>
More information about the mesa-dev
mailing list