This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: GCC 4.8.4 4.9.2 nifti_swap_2bytes optimization bug
- From: Martin Sebor <msebor at redhat dot com>
- To: Andrew Haley <aph at redhat dot com>, Andreas Schuh <andreas dot schuh dot 84 at gmail dot com>, gcc-help at gcc dot gnu dot org
- Date: Sun, 05 Apr 2015 20:58:30 -0600
- Subject: Re: GCC 4.8.4 4.9.2 nifti_swap_2bytes optimization bug
- Authentication-results: sourceware.org; auth=none
- References: <3ED91A29-66B4-46D0-B4B1-0078A0EAE5A7 at gmail dot com> <551C0567 dot 60406 at redhat dot com> <551C35CB dot 6010600 at redhat dot com> <551CFA1F dot 3010401 at redhat dot com> <551DE81A dot 8000903 at redhat dot com> <551E5BB8 dot 6020804 at redhat dot com>
For the aliasing rule to be violated the access (defined in 3.1, p1
as an action to read or modify an object) to the object would need
to be via an lvalue of a type other than character or short (such as
struct twobytes in the example program).
I'm not convinced that's true. If you look at 6.3.2.3 you'll see that
you have permission to convert a pointer to an object type to a
pointer to a different object type (possibly several times) and back
to the original type, or to a character type. That's it. You can't
do anything else with the converted pointers.
6.3.2.3 only specifies the rules for pointer conversions.
The constraints on expressions involving converted pointers
are detailed elsewhere. For example, whether or not an object
of one type can be accessed via a pointer to a different type,
such as in the following, is specified in 6.5, p7:
struct A { int i; } *p;
struct B { int j, k; } b = { 1, 2 };
p = (struct A*)&b;
++p->i; // valid, increments b.j
It would have been legal
to convert that pointer to a char* and dereference it, but not to
access a structure member. I think that would have worked in GCC.
Taking the address of a struct member doesn't constitute
an access to the object or the member. In our case where
ar is a pointer to an object and (tb == (twobytes*)ar),
the original expression
tb[ii].a
is the same as
((twobytes*)ar)[ii].a
which is equivalent to
*((char*)ar + ii * sizeof(twobytes) + offsetof(twobytes, a))
All three expressions satisfy all their constraints and none
of them accesses an object. Accessing the target object via
any of the expressions is valid since they are all lvalues
of character type.
But in any case, I can't see that there is any point in such a fine
nitpicking argument. It's not going to fix the problem, and I doubt
that GCC is going to change.
The point, presumably, is to answer the question whether the
output of the posted program demonstrates a bug in gcc or one
in the program itself.
Martin