https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114171

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Iain Buclaw from comment #4)
> Removed druntime dependency.
> ---
> import gcc.builtins;
> struct Token {
>     string label;
> }
> struct BreakStatement {
>     ulong pad;
>     Token label;
> }
> 
> pragma(inline, false)
> auto newclass()
> {
>     void *p = __builtin_malloc(BreakStatement.sizeof);
>     __builtin_memset(p, 0, BreakStatement.sizeof);
>     return cast(BreakStatement*) p;
> }
> 
> int main ()
> {
>     auto bn = newclass();
>     return bn.label is Token.init;
> }
> ---
> 
> 
> 
> Roughly the equivalent C++
> ---
> struct Token {
>     struct {
>     __SIZE_TYPE__ length;
>     const char *ptr;
>     } label;
> };
> struct BreakStatement {
>     __UINT64_TYPE__ pad;
>     Token label;
> };
> 
> __attribute__((noinline))
> BreakStatement *newclass()
> {
>     void *p = __builtin_malloc(sizeof(BreakStatement));
>     __builtin_memset(p, 0, sizeof(BreakStatement));
>     return (BreakStatement*) p;
> }
> 
> int main ()
> {
>     auto bn = newclass();
>     auto init = Token();
>     return *(__uint128_t*)&bn->label == *(__uint128_t*)&init;
> }
> ---

Unless gdc somehow guarantees bn->label and init are 128bit aligned
then "casting" this way is broken.  You can of course use
build_aligned_type to build a properly (mis-)aligned type to use
to dereference to.

Reply via email to