D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 15704 - @safe code should not allow copying to/from void[]
Summary: @safe code should not allow copying to/from void[]
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 major
Assignee: No Owner
URL:
Keywords: accepts-invalid, pull, safe
Depends on:
Blocks:
 
Reported: 2016-02-18 23:05 UTC by hsteoh
Modified: 2021-03-18 07:19 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description hsteoh 2016-02-18 23:05:34 UTC
-----
void main() @safe {
    Object[] objs = [ new Object() ];
    void[] arr1 = objs;
    void[] arr2 = [ 123, 345, 567 ];

    arr1[] = arr2[];  // overwrites pointers with arbitrary ints
}
-----

It should be illegal to copy the contents of one void[] to another void[], since void[] by definition is a type-erased array and can represent any arbitrary type, including types with indirections. Since type information has been erased, there is no way to verify that the destination array has no indirections, so to guarantee @safety, such an operation must not be allowed in @safe code.
Comment 1 Nick Treleaven 2016-06-13 21:22:03 UTC
Shouldn't we just disallow all writes to a void[] in safe code?
Comment 2 hsteoh 2016-06-14 15:15:55 UTC
It's not just writing to void[] that's the problem. Consider:

----
int[] intArr = [ 1,2,3,4,5 ];
void[] voidArr = intArr; // OK, every array converts to void[]
int*[] ptrArr;
ptrArr.length = 5;
ptrArr[] = voidArr[]; // reinterpret intArr as pointers
ptrArr[0] = 1; // oops
----

Basically, *anything* that leads to reinterpretation of something as pointer values cannot be allowed in @safe.
Comment 3 Steven Schveighoffer 2016-06-14 15:26:44 UTC
(In reply to hsteoh from comment #2)
> It's not just writing to void[] that's the problem. Consider:
> 
> ----
> int[] intArr = [ 1,2,3,4,5 ];
> void[] voidArr = intArr; // OK, every array converts to void[]
> int*[] ptrArr;
> ptrArr.length = 5;
> ptrArr[] = voidArr[]; // reinterpret intArr as pointers

Wait, does this really work (I didn't think it did)? If so, isn't it still implicitly doing this:

(cast(void[])ptrArr)[] = voidArr[];

Which is still writing void data.
Comment 4 hsteoh 2016-06-14 15:40:34 UTC
Oh, you're right, it doesn't compile because implicit conversion from void[] to int*[] is not allowed.  OK, nevermind what I said, then. :-D
Comment 5 Walter Bright 2016-06-20 08:26:40 UTC
https://github.com/dlang/dmd/pull/5877
Comment 6 github-bugzilla 2016-06-21 11:22:47 UTC
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/378e6e3ff01e8e1afd5b5bb97d259ae68918ef9e
fix Issue 15704 - @safe code should not allow copying to/from void[]

https://github.com/dlang/dmd/commit/8ed696695c913234d7bed276215c9dcae8a9cc66
Merge pull request #5877 from WalterBright/fix15704

fix Issue 15704 - @safe code should not allow copying to/from void[]
Comment 7 github-bugzilla 2016-10-01 11:47:55 UTC
Commits pushed to stable at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/378e6e3ff01e8e1afd5b5bb97d259ae68918ef9e
fix Issue 15704 - @safe code should not allow copying to/from void[]

https://github.com/dlang/dmd/commit/8ed696695c913234d7bed276215c9dcae8a9cc66
Merge pull request #5877 from WalterBright/fix15704