Thread overview
[Issue 17261] Implicit cast from static array to immutable should not be allowed
Mar 16, 2017
ag0aep6g@gmail.com
Mar 16, 2017
ZombineDev
March 16, 2017
https://issues.dlang.org/show_bug.cgi?id=17261

--- Comment #1 from hsteoh@quickfur.ath.cx ---
P.S. the comment in gunk() has a typo, it should say "implicit conversion
char[32] -> string" (not char[16]).  But that's immaterial to the issue at
hand.

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

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |accepts-invalid, wrong-code

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

ag0aep6g@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ag0aep6g@gmail.com

--- Comment #2 from ag0aep6g@gmail.com ---
I think immutable doesn't matter here. Code is also accepted (wrongly) when you convert to a `char[]` instead of a `string`. Also, implicit and explicit slicing are both accepted (and both wrong). Also accepted in `@safe` code.

dmd's -dip1000 mode correctly rejects this. I don't know if this counts as fixed.

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

--- Comment #3 from hsteoh@quickfur.ath.cx ---
Note that while some may blame implicit slicing for this bug, it still happens with explicit slicing:

-----
string gunk() {
    string x = func()[]; // still allowed, but shouldn't be
    writeln(x.ptr);
    writeln(x);
    return x;
}
-----

Looks like the compiler's escaping ref analysis has a hole here.

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

--- Comment #4 from hsteoh@quickfur.ath.cx ---
Related: https://issues.dlang.org/show_bug.cgi?id=12625

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

--- Comment #5 from hsteoh@quickfur.ath.cx ---
Verified that compiling with -dip1000 correctly rejects this code.

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

ZombineDev <petar.p.kirov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
             Status|NEW                         |RESOLVED
                 CC|                            |petar.p.kirov@gmail.com
           Hardware|x86_64                      |All
         Resolution|---                         |DUPLICATE
                 OS|Linux                       |All

--- Comment #6 from ZombineDev <petar.p.kirov@gmail.com> ---
(In reply to hsteoh from comment #0)
> Code:
> --------
> import std.stdio;
> 
> char[32] func() {
>     char[32] staticArr = "A123456789abcdefB123456789abcdef"; // canary
>     return staticArr; // OK, by-value return
> }
> 
> string gunk() {
>     string x = func(); // implicit conversion char[16] -> string
>     writeln(x.ptr);
>     writeln(x);
>     return x;
> }
> 
> void main() {
>     auto s = gunk();
>     writeln(s.ptr);
>     writeln(s);
> }
> --------
> 
> 
> Output:
> --------
> 7FFCD89895C0
> A123456789abcdefB123456789abcdef
> 7FFCD89895C0
> 9abcdef ����
> --------
> 
> 
> Basically, func() returns a static array by value, so it resides on the
> stack. The implicit conversion in gunk() produces a slice of this stack data
> (red flag), which gets corrupted (overwritten) when it returns to main().
> 
> Implicitly casting static arrays to immutable should not be allowed.

After commenting-out the writeln calls I get: scope_test2.d(12): Error: scope variable x may not be returned when compiling with -dip1000 & DMD 2.073.2.

(Without commenting-out the writeln calls I still get a compiler error, but it's because not all of Phobos is compatible with -dip1000.)

After replacing gunk with the one posted above:
string gunk() {
    string x = func()[]; // still allowed, but shouldn't be
    writeln(x.ptr);
    writeln(x);
    return x;
}

I get the same message:
scope_test3.d(12): Error: scope variable x may not be returned

*** This issue has been marked as a duplicate of issue 12625 ***

--