Jump to page: 1 2
Thread overview
[Issue 16408] [REG2.065] Converting char* to string with std.conv.to!string is wrong in release mode
[Issue 16408] Converting char* to string with std.conv.to!string is wrong in release mode
Aug 21, 2016
Lodovico Giaretta
Aug 21, 2016
Matt Jones
Aug 21, 2016
ag0aep6g@gmail.com
Aug 21, 2016
ag0aep6g@gmail.com
Aug 21, 2016
Lodovico Giaretta
Aug 21, 2016
Matt Jones
Apr 12, 2017
Walter Bright
Apr 12, 2017
ag0aep6g@gmail.com
Apr 12, 2017
Walter Bright
Apr 16, 2017
Walter Bright
Apr 16, 2017
Walter Bright
[Issue 16408] [REG2.065] left-to-right order of evaluation of function arguments not consistently followed
Apr 16, 2017
Walter Bright
Apr 16, 2017
Walter Bright
May 18, 2017
ag0aep6g@gmail.com
August 21, 2016
https://issues.dlang.org/show_bug.cgi?id=16408

Lodovico Giaretta <lodovico@giaretart.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lodovico@giaretart.net

--- Comment #1 from Lodovico Giaretta <lodovico@giaretart.net> ---
(In reply to Matt Jones from comment #0)
> This program prints WASD in debug mode as expected, but prints DDDD in release mode. My guess is std.conv.to!string is failing with char* for some reason.
> 
> [...]

Can I ask you to try with `std.string.fromStringz` instead of
`std.conv.to!string` ?
This may help find out where the bug is.

--
August 21, 2016
https://issues.dlang.org/show_bug.cgi?id=16408

--- Comment #2 from Matt Jones <matthew.brennan.jones@gmail.com> ---
Interesting. Changing from std.conv.to!string to std.string.fromStringz returns "DDDD" for both debug and release mode.

--
August 21, 2016
https://issues.dlang.org/show_bug.cgi?id=16408

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
                 CC|                            |ag0aep6g@gmail.com
          Component|phobos                      |dmd
           Severity|enhancement                 |regression

--- Comment #3 from ag0aep6g@gmail.com ---
This is triggered by the -inline switch.

This is a regression. With 2.064.2 it prints "WASD" as expected. Since 2.065 it prints "DDDD".

This seems to be related to SDL_GetKeyName reusing the buffer it returns. From its docs [1]:

> Returns a pointer to a UTF-8 string that stays valid at least until the next call to this function.

So when calling SDL_GetKeyName it multiple times, the previous results are strictly invalidated. In practice, they're overwritten with the newest value.

A reduction based on that:

----
import std.stdio;
import std.conv;

char[2] buffer = '\0';

const(char*) SDL_GetKeyName(char k)
{
    buffer[0] = k;
    return buffer.ptr;
}

void main()
{
    /* prints "WASD" or "DDDD" depending on -inline */
    writeln(
        to!string(SDL_GetKeyName('W')),
        to!string(SDL_GetKeyName('A')),
        to!string(SDL_GetKeyName('S')),
        to!string(SDL_GetKeyName('D')),
    );
}
----

That test case works with 2.066 and fails since 2.067. Notice that those are different versions than for the original test case.

A further reduction reveals a wrong-code compiler bug:

----
char[1] SDL_GetKeyName_buffer;

const(char)[] SDL_GetKeyName(char k)
{
    SDL_GetKeyName_buffer[0] = k;
    return SDL_GetKeyName_buffer[];
}

void formatGeneric() {}

void formattedWrite(string strW, string strA)
{
    auto fun = ()@trusted{ return &formatGeneric; }(); /* !? */

    assert(strW == "W", strW); /* passes without -inline, fails with */
    assert(strA == "A");
}

void main()
{
    formattedWrite(
        SDL_GetKeyName('W').idup,
        SDL_GetKeyName('A').idup,
    );
}
----

That one works with 2.065 and fails since 2.066. Yet again other versions.

I'm promoting this to a regression and to a wrong-code compiler bug. When fixing, all test cases should be checked, since they're might be multiple things going on here.


[1] https://wiki.libsdl.org/SDL_GetKeyName

--
August 21, 2016
https://issues.dlang.org/show_bug.cgi?id=16408

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Converting char* to string  |[REG2.065] Converting char*
                   |with std.conv.to!string is  |to string with
                   |wrong in release mode       |std.conv.to!string is wrong
                   |                            |in release mode

--
August 21, 2016
https://issues.dlang.org/show_bug.cgi?id=16408

--- Comment #4 from Lodovico Giaretta <lodovico@giaretart.net> ---
(In reply to Matt Jones from comment #2)
> Interesting. Changing from std.conv.to!string to std.string.fromStringz returns "DDDD" for both debug and release mode.

ag0aep6g's comment (https://issues.dlang.org/show_bug.cgi?id=16408#c3) is
correct.

The fact that SDL_GetKeyName always returns the same buffer explains why fromStringz gives the wrong answer in both debug and release.

So I agree that this is a wrong-code bug.

--
August 21, 2016
https://issues.dlang.org/show_bug.cgi?id=16408

--- Comment #5 from Matt Jones <matthew.brennan.jones@gmail.com> ---
Excellent. Thanks for figuring this out. Now that I know what is wrong, it should be easy to code around.

Thanks.

--
April 12, 2017
https://issues.dlang.org/show_bug.cgi?id=16408

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #6 from Walter Bright <bugzilla@digitalmars.com> ---
Compiles and runs fine with HEAD. I don't know when it was fixed.

--
April 12, 2017
https://issues.dlang.org/show_bug.cgi?id=16408

--- Comment #7 from ag0aep6g@gmail.com ---
(In reply to Walter Bright from comment #6)
> Compiles and runs fine with HEAD. I don't know when it was fixed.

The test cases from comment #3 still fail for me. dmd 15b3ee1 on linux. Did you compile with -inline?

--
April 12, 2017
https://issues.dlang.org/show_bug.cgi?id=16408

--- Comment #8 from Walter Bright <bugzilla@digitalmars.com> ---
Yes, you're right. It's still a bug. I had failed to specify -inline.

--
April 16, 2017
https://issues.dlang.org/show_bug.cgi?id=16408

--- Comment #9 from Walter Bright <bugzilla@digitalmars.com> ---
What's going wrong is the compiler is moving expressions with side effects
(SDL_GetKeyName('W'), SDL_GetKeyName('A')) to before the function call, which
gets the side effects out of order. I seem to recall a PR to do this, I'll have
to find it.

--
« First   ‹ Prev
1 2