Bug 13508 – array vararg function safety not inferred

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-20T13:39:00Z
Last change time
2015-02-18T03:37:25Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
monarchdodra

Comments

Comment #0 by monarchdodra — 2014-09-20T13:39:01Z
struct S { this(T)(T[] t...) {} } template make(T) { T make(Args...)(Args args) //@safe { return T(args); } } void main() @safe { S s = make!S(5); } //---- Error: safe function 'D main' cannot call system function 'main.make!(S).make!(int).make' //---- If you mark "make" as explicitly safe, then it works. Then again, I believe using "T[] t..." isn't safe to begin with...? (slice contents are destroyed at end of scope). Either way, there's a bug in there.
Comment #1 by hsteoh — 2014-09-20T21:05:21Z
Array vararg functions are not safe, because they take a slice of arguments on the stack. Example problem: ----- class C { int[] data; this(int[] args...) { data = args; // oops: this.data now points to the stack... } } -----
Comment #2 by monarchdodra — 2014-09-20T22:01:28Z
(In reply to hsteoh from comment #1) > Array vararg functions are not safe, because they take a slice of arguments > on the stack. Example problem: > ----- > class C { > int[] data; > this(int[] args...) { > data = args; // oops: this.data now points to the stack... > } > } > ----- That's what I thought, but: "If you mark "make" as explicitly safe, then it works." So there's a loophole somewhere here. Also related, I think it is a flaw that the very *signature* of something is unsafe. In particular, the "array vararg" signature is *also* the one chosen when you pass an array, which is perfectly defined and safe behavior...
Comment #3 by hsteoh — 2014-09-20T22:30:20Z
Yes, definitely there's a loophole somewhere. So that must be fixed. But "conditionally safe" (i.e., conditional upon what arguments are passed by the caller) is the same as "unsafe", because for example, if a function performs pointer arithmetic, then as long as you make sure the pointers you pass in are within bounds, then you won't get any unsafe operations in the function. But that doesn't change the fact that the function is unsafe.
Comment #4 by monarchdodra — 2014-09-20T23:06:51Z
(In reply to hsteoh from comment #3) > But "conditionally safe" (i.e., conditional upon what arguments are passed > by the caller) is the same as "unsafe", because for example, if a function > performs pointer arithmetic, then as long as you make sure the pointers you > pass in are within bounds, then you won't get any unsafe operations in the > function. But that doesn't change the fact that the function is unsafe. Right, but in this case, we're talking about the static types used by the caller. From caller point of view, it's 2 different signatures: make!S(1, 2, 3); //(1) unsafe make!S([1, 2, 3]); //(2) safe In this case, 1 is unsafe, but 2 is (should) be safe.
Comment #5 by k.hara.pg — 2014-09-22T09:15:06Z
Comment #6 by k.hara.pg — 2014-09-22T12:13:51Z
(In reply to hsteoh from comment #1) > Array vararg functions are not safe, because they take a slice of arguments > on the stack. Example problem: > ----- > class C { > int[] data; > this(int[] args...) { > data = args; // oops: this.data now points to the stack... > } > } > ----- I think that typesafe variadic parameters would be designed to be safe, because the following case is correctly rejected by the compile time check. int[] foo(int[] args...) { return args; // Error: escaping reference to variadic parameter args } But as you know, current escape analysis mechanism is incomplete, and scope attribute is yet not defined well.
Comment #7 by github-bugzilla — 2014-09-24T00:30:23Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/f9e1c78871d1790e4728fee1b2a76a4bcf9bec31 fix Issue 13508 - array vararg function safety not inferred https://github.com/D-Programming-Language/dmd/commit/1bba639635f0f1705b137b3d5431364756a13182 Merge pull request #4015 from 9rnsr/fix13508 Issue 13508 - array vararg function safety not inferred
Comment #8 by github-bugzilla — 2015-02-18T03:37:25Z