Skip to content

Commit

Permalink
fix Issue 17123 - [REG 2.073] Issues with return @safe inference
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Feb 12, 2017
1 parent 4f1425c commit 7dd10aa
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 19 deletions.
11 changes: 11 additions & 0 deletions src/func.d
Expand Up @@ -2426,6 +2426,17 @@ extern (C++) class FuncDeclaration : Declaration
*/
VarDeclaration v = new ThisDeclaration(loc, Type.tvoid.pointerTo());
v.storage_class |= STCparameter;
if (type.ty == Tfunction)
{
TypeFunction tf = cast(TypeFunction)type;
if (tf.isreturn)
v.storage_class |= STCreturn;
if (tf.isscope)
v.storage_class |= STCscope;
}
if (flags & FUNCFLAGinferScope)
v.storage_class |= STCmaybescope;

v.semantic(sc);
if (!sc.insert(v))
assert(0);
Expand Down
30 changes: 28 additions & 2 deletions src/mtype.d
Expand Up @@ -781,7 +781,7 @@ extern (C++) abstract class Type : RootObject
goto Lnotcovariant;
}

// We can subtract 'return' from 'this', but cannot add it
// We can subtract 'return ref' from 'this', but cannot add it
else if (t1.isreturn && !t2.isreturn)
goto Lnotcovariant;

Expand Down Expand Up @@ -6698,8 +6698,13 @@ extern (C++) final class TypeFunction : TypeNext

override Type addStorageClass(StorageClass stc)
{
//printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
TypeFunction t = cast(TypeFunction)Type.addStorageClass(stc);
if ((stc & STCpure && !t.purity) || (stc & STCnothrow && !t.isnothrow) || (stc & STCnogc && !t.isnogc) || (stc & STCsafe && t.trust < TRUSTtrusted))
if ((stc & STCpure && !t.purity) ||
(stc & STCnothrow && !t.isnothrow) ||
(stc & STCnogc && !t.isnogc) ||
(stc & STCscope && !t.isscope) ||
(stc & STCsafe && t.trust < TRUSTtrusted))
{
// Klunky to change these
auto tf = new TypeFunction(t.parameters, t.next, t.varargs, t.linkage, 0);
Expand All @@ -6723,6 +6728,8 @@ extern (C++) final class TypeFunction : TypeNext
tf.isnogc = true;
if (stc & STCsafe)
tf.trust = TRUSTsafe;
if (stc & STCscope)
tf.isscope = true;

tf.deco = tf.merge().deco;
t = tf;
Expand Down Expand Up @@ -7192,6 +7199,25 @@ extern (C++) final class TypeDelegate : TypeNext
}
}

override Type addStorageClass(StorageClass stc)
{
TypeDelegate t = cast(TypeDelegate)Type.addStorageClass(stc);
if (!global.params.vsafe)
return t;

/* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
* alias dg_t = void* delegate();
* scope dg_t dg = ...;
*/
auto n = t.next.addStorageClass(stc & STCscope);
if (n != t.next)
{
t.next = n;
t.deco = t.merge().deco;
}
return t;
}

override d_uns64 size(Loc loc) const
{
return Target.ptrsize * 2;
Expand Down
32 changes: 16 additions & 16 deletions test/fail_compilation/retscope.d
Expand Up @@ -235,10 +235,10 @@ void* funretscope(scope dg_t ptr) @safe
/*
TEST_OUTPUT:
---
fail_compilation/retscope.d(249): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe
fail_compilation/retscope.d(249): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe
fail_compilation/retscope.d(250): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe
fail_compilation/retscope.d(250): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return @safe to void* delegate() @safe
fail_compilation/retscope.d(249): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return scope @safe to void* delegate() scope @safe
fail_compilation/retscope.d(249): Error: cannot implicitly convert expression (__lambda1) of type void* delegate() pure nothrow @nogc return scope @safe to void* delegate() scope @safe
fail_compilation/retscope.d(250): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return scope @safe to void* delegate() scope @safe
fail_compilation/retscope.d(250): Error: cannot implicitly convert expression (__lambda2) of type void* delegate() pure nothrow @nogc return scope @safe to void* delegate() scope @safe
---
*/

Expand Down Expand Up @@ -626,18 +626,6 @@ struct Result(R)
n.empty();
}

/**********************************************/

@safe void foo22()(ref char[] s)
{
char[] a = s;
}

@safe void test22(scope char[] s)
{
foo22(s);
}

/************************************************/

// https://issues.dlang.org/show_bug.cgi?id=17117
Expand All @@ -660,3 +648,15 @@ int test21()
return s;
}

/**********************************************/

@safe void foo22()(ref char[] s)
{
char[] a = s;
}

@safe void test22(scope char[] s)
{
foo22(s);
}

15 changes: 14 additions & 1 deletion test/fail_compilation/retscope2.d
Expand Up @@ -21,6 +21,19 @@ fail_compilation/retscope2.d(107): Error: address of variable s assigned to p wi

/**********************************************/

// https://issues.dlang.org/show_bug.cgi?id=17123

void test200()
{
char[256] buffer;

char[] delegate() read = () {
return buffer[];
};
}

/**********************************************/

/*
TEST_OUTPUT:
---
Expand Down Expand Up @@ -69,7 +82,6 @@ fail_compilation/retscope2.d(504): Error: scope variable c may not be returned
return c;
}


/**********************************************/

/*
Expand Down Expand Up @@ -99,3 +111,4 @@ fail_compilation/retscope2.d(614): Error: template instance retscope2.test600!(i
test600(p, q);
}


0 comments on commit 7dd10aa

Please sign in to comment.