November 03, 2020
https://issues.dlang.org/show_bug.cgi?id=21359

          Issue ID: 21359
           Summary: The D spec doesn't talk about that Undefined Behaviour
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: aliloko@gmail.com

Original report: https://github.com/ldc-developers/ldc/issues/3603

# SPEC CHANGE

The specification that I feel is incomplete is 10.18.4.7 https://dlang.org/spec/expression.html#cast_expressions

It should says precisely:

   - Casting float values outside [-X , X] to int is illegal.
   - Casting double values outside [-Y , Y] to int is illegal.
   - Casting float values outside [-Z , Z] to long is illegal.
   - Casting double values outside [-W , W] to long is illegal.
   (different behaviour for unsigned?)

   With proper values for X, Y, Z, W.


# PROOF

Consider the following program:

```d
import core.stdc.stdio;

void main(string[] args)
{
   double d = 625935085.258525;
   uint msu = cast(uint)(d * 1000.0);
   printf("msu = %d\n", msu);
   printf("msu at CTFE = %d\n", ctfeResult_uint);

   int msi = cast(int)(d * 1000.0);
   printf("msi = %d\n", msi);
   printf("msi at CTFE = %d\n", ctfeResult_int);

   // and the CTFE ones?
}

enum uint ctfeResult_uint = cast(uint)(625935085.258525 * 1000.0);
enum int ctfeResult_int = cast(int)(625935085.258525 * 1000.0);
```

In LDC x86_64 the output is:
```d
msu = -1130139958
msu at CTFE = -1130139958
msi = -2147483648
msi at CTFE = -2147483648
```

In LDC arm64 the output is:
```d
msu = -1
msu at CTFE = -1130139958
msi = 2147483647
msi at CTFE = -2147483648
```

The ARM FCVTZ instruction doesn't work like the x86 CVTSI2SS instruction with regards to out-of-bounds floats.

--