aliasing

Richard Biener richard.guenther@gmail.com
Mon Mar 18 08:26:18 GMT 2024


On Mon, Mar 18, 2024 at 8:03 AM Martin Uecker <uecker@tugraz.at> wrote:
>
>
> Hi,
>
> can you please take a quick look at this? This is intended to align
> the C standard with existing practice with respect to aliasing by
> removing the special rules for "objects with no declared type" and
> making it fully symmetric and only based on types with non-atomic
> character types being able to alias everything.
>
>
> Unrelated to this change, I have another question:  I wonder if GCC
> (or any other compiler) actually exploits the " or is copied as an
> array of  byte type, " rule to  make assumptions about the effective
> types of the target array?

We do not make assumptions about this anymore.  We did in the
past (might be a distant past) transform say

struct X { int i; float f; } a, b;

void foo ()
{
  __builtin_memcpy (&a, &b, sizeof (struct X));
}

into

  a = b;

which has an lvalue of type struct X.  But this assumed b's effective
type was X.  Nowadays we treat the copy as using alias set zero.
That effectively means the destination gets its effective type "cleared"
(all subsequent accesses are valid to access storage with the effective
type of a byte array).

> I know compilers do this work memcpy...
> Maybe also if a loop is transformed to memcpy?

We currently do not preserve the original effective type of the destination
(or the effective type used to access the source) when doing this.  With
some tricks we could (we also lose aligment guarantees of the original
accesses).

> Martin
>
>
> Add the following definition after 3.5, paragraph 2:
>
> byte array
> object having either no declared type or an array of objects declared with a byte type
>
> byte type
> non-atomic character type
>
> Modify 6.5,paragraph 6:
> The effective type of an object that is not a byte array, for an access to its
> stored value, is the declared type of the object.97) If a value is
> stored into a byte array through an lvalue having a byte type, then
> the type of the lvalue becomes the effective type of the object for that
> access and for subsequent accesses that do not modify the stored value.
> If a value is copied into a byte array using memcpy or memmove, or is
> copied as an array of byte type, then the effective type of the
> modified object for that access and for subsequent accesses that do not
> modify the value is the effective type of the object from which the
> value is copied, if it has one. For all other accesses to a byte array,
> the effective type of the object is simply the type of the lvalue used
> for the access.

What's the purpose of this change?  To me this reads more confusing and
complicated than what I find in the c23 draft from April last year.

I'll note that GCC does not take advantage of "The effective type of an
object for an access to its stored value is the declard type of the object",
instead it always relies on the type of the lvalue (treating non-atomic
character types specially, as well as treating all string ops like memcpy
or strcpy as using a character type for the access) and the effective type
of the object for that access and for subsequent accesses that do not
modify the stored value always becomes that of the lvalue type used for
the access.

Let me give you an complication example made valid in C++:

struct B { float x; float y; };
struct X { int n; char buf[8]; } x, y;

void foo(struct B *b)
{
  memcpy (x.buf, b, sizeof (struct B)); // in C++:  new (x.buf) B (*b);
  y = x; // (*)
}

What's the effective type of 'x' in the 'y = x' copy?  With your new
wording, does 'B' transfer to x.buf with memcpy?  What's the
frankenstein effective type of 'x' then?  What's the effective type
of 'y' after the copy?  Can an lvalue of type 'B' access y.buf?

Richard.

> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3230.pdf
>
>


More information about the Gcc mailing list