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

--- Comment #6 from Iain Buclaw <ibuclaw at gcc dot gnu.org> ---
(In reply to Iain Buclaw from comment #2)
> (In reply to Sam James from comment #0)
> > When bootstrapping with some patches for improving Valgrind support (see
> > PR116947), I hit this:
> > 
> > ==26778== Conditional jump or move depends on uninitialised value(s)
> > ==26778==    at 0x911F41: dmd.dstruct._isZeroInit(dmd.expression.Expression)
> > (dstruct.d:635)
> 
> If this line number is correct against current mainline, the trigger is
> 
> exp.toReal() is CTFloat.zero
> 
> Which would be a memcmp between two struct longdouble - a thin wrap around
> gcc REAL_VALUE_TYPE types.
So, the array buffer in `longdouble' is actually bigger than REAL_VALUE_TYPE. 
```
longdouble r;  // [ud,ud,ud,ud,ud]
real_from_string (&r.rv (), ...);
return r;      // [0,0,0,0,ud]
```

This extra padding is usually never directly referenced on the C++ side,
because all accesses to the underlying data go through `rv()`.
```
return real_compare(EQ_EXPR, &this->rv(), &r.rv());
```

On the D side however, `is` is a memcmp operation, so the ud element is read.

Fix should be to explicitly zero initialize all longdouble/real_t objects
before passing off their `object.rv()` data to be set.

Reply via email to