Bug 6646 – [SafeD] array.reserve is not @safe/trusted

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-09-11T10:13:00Z
Last change time
2015-07-02T16:55:16Z
Keywords
pull, safe
Assigned to
nobody
Creator
dmitry.olsh

Comments

Comment #0 by dmitry.olsh — 2011-09-11T10:13:37Z
I'm not sure if it's druntime or DMD problem. Testcase: @safe void bug() { int[] a; a.reserve(10); } Fails to compile with: Error: safe function 'bug' cannot call system function 'reserve'
Comment #1 by hsteoh — 2013-07-01T12:01:16Z
IMO, reserve() should be at least @trusted. What's the use of safeD if even language constructs like array.reserve can't be used?
Comment #2 by schveiguy — 2013-07-01T13:27:43Z
It should be @trusted.
Comment #3 by hsteoh — 2013-07-02T09:25:32Z
Comment #4 by github-bugzilla — 2013-07-02T12:28:37Z
Commits pushed to master at https://github.com/D-Programming-Language/druntime https://github.com/D-Programming-Language/druntime/commit/032bac64ef3e354da65da38314c51af09eebcf05 Fix issue 6646: array.reserve should be callable from SafeD. https://github.com/D-Programming-Language/druntime/commit/fa85c1b413cbe81416f02995cfefe6107a4cbb4e Merge pull request #536 from quickfur/issue6646 Fix issue 6646: array.reserve should be callable from SafeD.
Comment #5 by monarchdodra — 2013-07-29T04:17:04Z
I think this change is wrong. reserve can call postblit, wich may end up being unsafe (or throwing).
Comment #6 by hsteoh — 2013-07-29T09:12:32Z
Hmph. I wish there was a consistent way of propagating attributes, or saying "function X's purity depends on argument Y" or something along those lines.
Comment #7 by schveiguy — 2013-08-05T13:38:51Z
This can be fixed, since reserve is a template and not a compiler-builtin. Unfortunately, we need to manually propagate the @safe/@nothrow to the high level reserve call. something like: @safe @nothrow reserve(T)(T[] t) if(isPostblitSafe!T && isPostblitNothrow!T) etc. Ugly...
Comment #8 by dmitry.olsh — 2013-08-05T14:13:05Z
(In reply to comment #7) > This can be fixed, since reserve is a template and not a compiler-builtin. > > Unfortunately, we need to manually propagate the @safe/@nothrow to the high > level reserve call. something like: > > @safe @nothrow reserve(T)(T[] t) if(isPostblitSafe!T && isPostblitNothrow!T) > > etc. > > Ugly... Shouldn't auto-inference help + local @trusted/nothrow lambdas to encapsulate dangerous code?
Comment #9 by monarchdodra — 2013-08-06T01:16:23Z
(In reply to comment #8) > (In reply to comment #7) > > This can be fixed, since reserve is a template and not a compiler-builtin. > > > > Unfortunately, we need to manually propagate the @safe/@nothrow to the high > > level reserve call. something like: > > > > @safe @nothrow reserve(T)(T[] t) if(isPostblitSafe!T && isPostblitNothrow!T) > > > > etc. > > > > Ugly... > > Shouldn't auto-inference help + local @trusted/nothrow lambdas to encapsulate > dangerous code? I was able to make it work simply by calling a dummy postblit: reserve(T)(T[] t) { if (is(typeof({T t2 = t;}))) if (0) T t2 = t; //Call C-reserve function here. } The forced postblit call makes sure the inference is ocrrectly computed. Unfortunately: 1) The C function is still marked nothrow, so all hell probably breaks loose *should* an exception be thrown 2) Hackish as hell. Might be worth it to find a better workaround.
Comment #10 by monarchdodra — 2013-09-09T11:47:53Z
It's not fixed, because reserve is not @safe 100% of the time either. > Shouldn't auto-inference help + local @trusted/nothrow lambdas to encapsulate dangerous code? The problem is that everything is run in druntime, as an non-template extern(C) call to a function that takes a TypeInfo. So no inference here.
Comment #11 by dmitry.olsh — 2015-07-02T16:55:16Z
Works at least as old as 2.067.