[Issue 10750] Strict aliasing semantics

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=10750

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P2  |P4

--


[Issue 10750] Strict aliasing semantics

2016-03-05 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=10750

Ketmar Dark  changed:

   What|Removed |Added

 CC||ket...@ketmar.no-ip.org

--


[Issue 10750] Strict aliasing semantics

2015-11-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=10750

weaselcat  changed:

   What|Removed |Added

 CC||r9shacklef...@gmail.com

--- Comment #6 from weaselcat  ---
Ping, did anything ever happen with this? I cannot find anything in D's spec
about aliasing/type punning and this seems to be the only relevant bug report.

--


[Issue 10750] Strict aliasing semantics

2013-11-03 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10750



--- Comment #3 from Johannes Pfau johannesp...@gmail.com 2013-11-03 02:13:39 
PST ---
@bearophile:
To further expand on this:
http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Optimize-Options.html
says:
type-punning is allowed, provided the memory is accessed through the union
type. [...] access by taking the address, casting the resulting pointer and
dereferencing the result has undefined behavior, even if the cast uses a union
type, e.g.: 

@David
What would a safe cast with strict pointer aliasing look like?

First some background information on how aliasing is implemented in gcc
(alias.c): Every type is assigned an alias set. The alias set is only a unique
id + a flattened list of the uids of all 'member types'. For example, this
struct:
--
struct B
{
char member;
}
struct A
{
   int member1, float member2;
   B member3;
}
--

will generate this alias set:
uid=1, children={2(int),3(float),4(char)}

Then for code like this:
--
A instance;
instance.member1 = 0;
A copy = a;
--

The compiler now inspects the line instance.member1 = 0; and assigns alias set
2(int) to it. Line 3 has alias set 1(B). When gcc now schedules instructions it
checks if set 2 conflicts with set 1 by checking: (set1 == set2 || set1 in
set2.children || set2 in set1.children). If they don't conflict gcc reorders
instructions.


This explains the problems with type punning:
--
int a = 3;//alias set 0(int), children = {}
int b = a;//alias set 0(int), children = {}
*(cast(float*)a) = 3.0f; //alias set 1(float), children = {}
--
as you can see these types don't conflict and gcc may reorder line 2 and 3.
Access through unions now solves this problem as the alias set for a union
would include both {float, int} as children.

But as for as I understand these strict alising rules make it impossible to
safely cast from one pointer type to another. Only _access_ through unions will
work.

As an example:

--
T* safeCast(T, U)(U* input)
{
union wrap
{
U inp;
T outp;
}

return (cast(wrap*)input).outp;
}

void withFloat(float* f)
{
*f = 0.1f;
}

int b;
void withInt(int* i)
{
b = *i;
}

void main()
{
int x = 0;
auto asFloat = (safeCast!float(x));
withFloat(asFloat)
withInt(i);
}
--

now with optimizations (inlining)

union wrap
{
int inp;
float outp;
}

int b;
void main()
{
int x = 0;//alias set: int
auto asFloat = ((cast(wrap*)x).outp) //alias set: wrap (but noop)
*asFloat = 0.1f;  //alias set: float
b = x;//alias set: int
}

I know from unfortunate experienc, that gcc may even completely discard the
auto asFloat line. But even if it didn't, *asFloat = 0.1f; and b = x; can
be reordered according to strict aliasing rules. If auto asFloat is
discarded, even int x = 0; and *asFloat = 0.1f; may be reordered.


So to summarize this: I don't know how you could make a safe cast from T* to U*
assuming strict aliasing rules. Unions are only safe if all access goes through
unions, but that is not possible when dealing with 3rd party functions. (Assume
you can't change withFloat, withInt).

We had problems with this in GDC right now on ARM (std.algorithm.find uses
cast(ubyte[])string which internally translates to invalid pointer aliasing)
and as a result we'll now have to disable strict aliasing in the GCC backend.

I think type based aliasing, even if it may provide some optimization benefits,
is in general a horrible idea.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10750] Strict aliasing semantics

2013-11-03 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10750


Iain Buclaw ibuc...@ubuntu.com changed:

   What|Removed |Added

 CC||ibuc...@ubuntu.com


--- Comment #4 from Iain Buclaw ibuc...@ubuntu.com 2013-11-03 03:17:17 PST ---
(In reply to comment #3)
 We had problems with this in GDC right now on ARM (std.algorithm.find uses
 cast(ubyte[])string which internally translates to invalid pointer aliasing)
 and as a result we'll now have to disable strict aliasing in the GCC backend.
 

Which is a shame, because dynamic arrays are perhaps the one type in D that
should instead benefit from strict aliasing rules...

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10750] Strict aliasing semantics

2013-11-03 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10750



--- Comment #5 from Iain Buclaw ibuc...@ubuntu.com 2013-11-03 03:43:06 PST ---
(In reply to comment #4)
 (In reply to comment #3)
  We had problems with this in GDC right now on ARM (std.algorithm.find uses
  cast(ubyte[])string which internally translates to invalid pointer aliasing)
  and as a result we'll now have to disable strict aliasing in the GCC 
  backend.
  
 
 Which is a shame, because dynamic arrays are perhaps the one type in D that
 should instead benefit from strict aliasing rules...

Alternatively, we can just define better aliasing rules that better suit D.

ie:
- Permit type-punning when accessing through a union.
- Determine aliasing rules of dynamic arrays from the elem type, instead of
treating it as aliasing the overall structure.

This might actually be the better solution for us - shall I send you a patch?
:o)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10750] Strict aliasing semantics

2013-11-02 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10750


Johannes Pfau johannesp...@gmail.com changed:

   What|Removed |Added

 CC||johannesp...@gmail.com


--- Comment #2 from Johannes Pfau johannesp...@gmail.com 2013-11-02 13:39:44 
PDT ---
Such a PointerCast is not safe in all cases when compiling with GDC as even
unions are not an exception to strict aliasing rules:
http://stackoverflow.com/questions/2906365/gcc-strict-aliasing-and-casting-through-a-union

I'm not sure if it's possible to change this in the GDC frontend.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 10750] Strict aliasing semantics

2013-08-03 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=10750


bearophile_h...@eml.cc changed:

   What|Removed |Added

 CC||bearophile_h...@eml.cc


--- Comment #1 from bearophile_h...@eml.cc 2013-08-03 04:37:51 PDT ---
(In reply to comment #0)

 (http://forum.dlang.org/post/kt026a$256e$1...@digitalmars.com):

My comments was:

Is it good to add to Phobos a small template (named like PointerCast or
something similar) that uses a union internally to perform pointer type
conversions?

Is then the compiler going to warn the programmer when the pointer type
aliasing rule is violated? I mean when the D code uses cast() between different
pointer types (beside constness). An alternative design is to even deprecate
(and later turn those into errors, where the error message suggests to use
PointerCast).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---