When running the following program: a.d ------ import std.stdio; union _f { float f; uint i; } void func(const uint x) { writeln(x); } void main() { float a = 123.0; const l = _f(a); func(l.i); func(_f(a).i); } ---- multiple times, the value printed for "_f(a).i" is different each time, and appears mostly random when compared to the value of "l.i". > gdc a.d && ./a.out 1123418112 430703264 > ./a.out 1123418112 3680514720 > ./a.out 1123418112 2543067808
The problem starts in the frontend, optimize.c(DotVarExp::optimize). It optimizes 'func(_f(a).i)' into 'func (a)', so it produces a call to func with an incorrectly typed parameter. The backend then tries to pass 'a' in floating point register leading to these strange results. @Iain do you think this should be fixed in the frontend or in the glue layer by doing an explicit conversion? I also wonder why the GCC backend didn't catch this problem, I thought it should know there's a type mismatch between the function declaration and the actual call?
Are you using a compiler with --enable-checking? Release compilers don't generally complain about mismatched arguments. I'll have a look when I get time.
(In reply to comment #1) > The problem starts in the frontend, optimize.c(DotVarExp::optimize). > It optimizes 'func(_f(a).i)' into 'func (a)', so it produces a call to func > with an incorrectly typed parameter. > > The backend then tries to pass 'a' in floating point register leading to > these strange results. > > @Iain do you think this should be fixed in the frontend or in the glue layer > by doing an explicit conversion? I also wonder why the GCC backend didn't > catch this problem, I thought it should know there's a type mismatch between > the function declaration and the actual call? You could do a view convert in SymbolExp if 'this->type' and 'this->var->type' mismatch. There'd be no way to enforce that we are dealing with a union optimisation though...
(In reply to comment #3) > (In reply to comment #1) > > The problem starts in the frontend, optimize.c(DotVarExp::optimize). > > It optimizes 'func(_f(a).i)' into 'func (a)', so it produces a call to func > > with an incorrectly typed parameter. > > > > The backend then tries to pass 'a' in floating point register leading to > > these strange results. > > > > @Iain do you think this should be fixed in the frontend or in the glue layer > > by doing an explicit conversion? I also wonder why the GCC backend didn't > > catch this problem, I thought it should know there's a type mismatch between > > the function declaration and the actual call? > > You could do a view convert in SymbolExp if 'this->type' and > 'this->var->type' mismatch. There'd be no way to enforce that we are > dealing with a union optimisation though... *SymbolExp::toElem
https://github.com/D-Programming-GDC/GDC/commit/d1afed7fa3b4482e41df95bd21326d1a2f9f1653