Bug 15672 – Casting from void[] to T[] is erroneously considered @safe

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-02-10T22:56:00Z
Last change time
2016-10-01T11:47:53Z
Keywords
pull, safe
Assigned to
nobody
Creator
dhasenan

Comments

Comment #0 by dhasenan — 2016-02-10T22:56:54Z
Example: --- void main() @safe { int*[] a = [new int]; void[] b = cast(void[])a; size_t[] c = cast(size_t[])b; c[0] = 0; *(a[0]) = 0; // Segmentation fault } --- If it were only allowed to cast to immutable(T)[] from void[], that would be safe. Thanks to iakh for the test case.
Comment #1 by hsteoh — 2016-02-19T19:18:15Z
It's not necessarily safe to cast from void[] to immutable(T)[]. Consider: ----- int[] a = [ 12345, 54321 ]; void[] b = a; // any array can implicitly convert to void[] immutable(Object)[] c = cast(immutable(Object)[]) b; // suppose this was allowed b[0].toString(); // illegal pointer dereference ----- In order to ensure @safety, we cannot allow reinterpreting *anything* as a pointer, that wasn't already a pointer of the same type, and with the same attributes. Note that it's not @safe even to convert from a pointer of the same type but different attributes. For instance: ----- alias safeFunc = void function() @safe; alias unsafeFunc = void function() @system; void main() @safe { unsafeFunc[] unsafePtrs = [ &unsafeFunc ]; void[] voidPtrs = unsafePtrs; // OK, everything converts to void[] implicitly auto arr = cast(immutable(safeFunc)[]) voidPtrs; // OK to convert func ptrs to func ptrs, right? arr[0](); // oops, we just called a @system function from @safe code } ----- The void[] step is not necessary, but illustrates the danger of allowing conversions from void[] to immutable(T)[].
Comment #2 by dhasenan — 2016-02-19T19:26:52Z
Right. I meant that we add a restriction that you can't cast void[] to mutable(T)[], keeping existing restrictions in place.
Comment #3 by bugzilla — 2016-06-19T05:35:21Z
Comment #4 by github-bugzilla — 2016-06-27T01:29:47Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/b23203607189a00227ac9636f4b4347fe85f81bf fix Issue 15672 - Casting from void[] to T[] is erroneously considered @safe https://github.com/dlang/dmd/commit/5ca4b331c4ce3b096b04b98edaacd97dc246c9c1 Merge pull request #5876 from WalterBright/fix15672 fix Issue 15672 - Casting from void[] to T[] is erroneously considere…
Comment #5 by github-bugzilla — 2016-10-01T11:47:53Z
Commits pushed to stable at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/b23203607189a00227ac9636f4b4347fe85f81bf fix Issue 15672 - Casting from void[] to T[] is erroneously considered @safe https://github.com/dlang/dmd/commit/5ca4b331c4ce3b096b04b98edaacd97dc246c9c1 Merge pull request #5876 from WalterBright/fix15672