Skip to content

Commit

Permalink
fix Issue 17795 - [scope] Scope errors not detected in ~= operation
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored and mathias-lang-sociomantic committed Sep 25, 2017
1 parent 929e60e commit 8b3b0a4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/ddmd/escape.d
Expand Up @@ -169,7 +169,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier par, Ex
* to eliminate the error.
* Params:
* sc = used to determine current function and module
* ae = AssignExp to check for any pointers to the stack
* e = AssignExp or CatAssignExp to check for any pointers to the stack
* gag = do not print error messages
* Returns:
* true if pointers to the stack can escape via assignment
Expand All @@ -178,9 +178,9 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag)
{
enum log = false;
if (log) printf("checkAssignEscape(e: %s)\n", e.toChars());
if (e.op != TOKassign && e.op != TOKblit && e.op != TOKconstruct)
if (e.op != TOKassign && e.op != TOKblit && e.op != TOKconstruct && e.op != TOKcatass)
return false;
auto ae = cast(AssignExp)e;
auto ae = cast(BinExp)e;
Expression e1 = ae.e1;
Expression e2 = ae.e2;
//printf("type = %s, %d\n", e1.type.toChars(), e1.type.hasPointers());
Expand Down
16 changes: 13 additions & 3 deletions src/ddmd/expressionsem.d
Expand Up @@ -6731,7 +6731,7 @@ extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}

//printf("CatAssignExp::semantic() %s\n", toChars());
//printf("CatAssignExp::semantic() %s\n", exp.toChars());
Expression e = exp.op_overload(sc);
if (e)
{
Expand Down Expand Up @@ -6772,13 +6772,20 @@ extern (C++) final class ExpressionSemanticVisitor : Visitor
Type tb1next = tb1.nextOf();
Type tb2 = exp.e2.type.toBasetype();

/* Two possibilities:
* 1. appending T[] to T[]
* 2. appending T to T[]
*/
bool appendArray = false; // assume case 2

if ((tb1.ty == Tarray) &&
(tb2.ty == Tarray || tb2.ty == Tsarray) &&
(exp.e2.implicitConvTo(exp.e1.type) ||
(tb2.nextOf().implicitConvTo(tb1next) &&
(tb2.nextOf().size(Loc()) == tb1next.size(Loc())))))
{
// Append array
// case 1: append array
appendArray = true;
if (exp.e1.checkPostblit(sc, tb1next))
{
result = new ErrorExp();
Expand Down Expand Up @@ -6822,7 +6829,10 @@ extern (C++) final class ExpressionSemanticVisitor : Visitor
}

exp.type = exp.e1.type;
result = exp.reorderSettingAAElem(sc);
auto res = exp.reorderSettingAAElem(sc);
if (!appendArray && global.params.vsafe)
checkAssignEscape(sc, res, false);
result = res;
}

override void visit(AddExp exp)
Expand Down
23 changes: 23 additions & 0 deletions test/fail_compilation/retscope6.d
@@ -0,0 +1,23 @@
/*
REQUIRED_ARGS: -dip1000
PERMUTE_ARGS:
*/

/*
TEST_OUTPUT:
---
fail_compilation/retscope6.d(6007): Error: reference to local variable `i` assigned to non-scope `arr[0]`
---
*/

#line 6000

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

int* test() @safe
{
int i;
int*[][] arr = new int*[][](1);
arr[0] ~= &i;
return arr[0][0];
}

0 comments on commit 8b3b0a4

Please sign in to comment.