September 26, 2023
https://issues.dlang.org/show_bug.cgi?id=24163

          Issue ID: 24163
           Summary: Floating-point variadic array bug
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Windows
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: evilrat666@gmail.com

Here is a "funny" bug with variadic function taking float arguments, whenever foo takes the float parameter and Vector2 is a larger type then the second assert fails.

It works as expected when foo and Vector2 is both float or double, or foo is not float.

There is a strange behavior in the foo as well.

Note that this only happens with DMD, with LDC it works correctly. This code is tested on Windows.

Reproduction code
------------------------------

alias real_t = double;

struct Vector2 {
    real_t x, y;

    this(real_t x, real_t y) { this.x = x; this.y = y; }
}

Vector2 foo(size_t nArgCount)(float[nArgCount] args...)
{
    //import std.stdio;
    //writeln(args); // [0.5]
    //writeln(args[0]); // 0
    //assert(args[0] == 0.5f); // assert failed
    return Vector2(args[0], args[0]);
}

void main()
{
    // ok
    auto c = foo(0.5, 0.5);
    assert(c.x == 0.5 && c.y == 0.5);

    // Note that it is just by coincidence that the stack is zeroed,
    // in real program there will be garbage values.
    // This bug happens ONLY when foo type is float and Vector2 any other type.
    // It works properly with LDC, but not with DMD.
    import std.stdio;
    c = foo(0.5);
    writefln("%f, %f", c.x, c.y); // 0.000000, 0.000000
    assert(c.x == 0.5 && c.y == 0.5);
}

--