Issue 6646 - [SafeD] array.reserve is not @safe/trusted
Summary: [SafeD] array.reserve is not @safe/trusted
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: druntime (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: pull, safe
Depends on:
Blocks:
 
Reported: 2011-09-11 10:13 UTC by Dmitry Olshansky
Modified: 2015-07-02 16:55 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Dmitry Olshansky 2011-09-11 10:13:37 UTC
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 hsteoh 2013-07-01 12:01:16 UTC
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 Steven Schveighoffer 2013-07-01 13:27:43 UTC
It should be @trusted.
Comment 4 github-bugzilla 2013-07-02 12:28:37 UTC
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 monarchdodra 2013-07-29 04:17:04 UTC
I think this change is wrong. reserve can call postblit, wich may end up being unsafe (or throwing).
Comment 6 hsteoh 2013-07-29 09:12:32 UTC
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 Steven Schveighoffer 2013-08-05 13:38:51 UTC
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 Dmitry Olshansky 2013-08-05 14:13:05 UTC
(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 monarchdodra 2013-08-06 01:16:23 UTC
(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 monarchdodra 2013-09-09 11:47:53 UTC
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 Dmitry Olshansky 2015-07-02 16:55:16 UTC
Works at least as old as 2.067.