Bug creation and email sending has been disabled, file new bugs at gcc.gnu.org/bugzilla
Bug 115 - Union literals as rvalues yields different values every run
Summary: Union literals as rvalues yields different values every run
Status: RESOLVED FIXED
Alias: None
Product: GDC
Classification: Unclassified
Component: gdc (show other bugs)
Version: 4.8.x
Hardware: x86_64 Linux
: --- normal
Assignee: Iain Buclaw
URL:
Depends on:
Blocks:
 
Reported: 2014-04-05 22:32 CEST by Klas Björkqvist
Modified: 2014-04-15 19:48 CEST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Klas Björkqvist 2014-04-05 22:32:43 CEST
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
Comment 1 Johannes Pfau 2014-04-06 11:18:03 CEST
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?
Comment 2 Iain Buclaw 2014-04-06 14:32:04 CEST
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.
Comment 3 Iain Buclaw 2014-04-08 13:33:46 CEST
(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...
Comment 4 Iain Buclaw 2014-04-08 13:34:17 CEST
(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