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?
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.