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.