Skip to content

Commit

Permalink
Merge pull request #4015 from 9rnsr/fix13508
Browse files Browse the repository at this point in the history
Issue 13508 - array vararg function safety not inferred
  • Loading branch information
WalterBright committed Sep 24, 2014
2 parents b5216d4 + f9e1c78 commit 1bba639
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 39 deletions.
53 changes: 26 additions & 27 deletions src/expression.c
Expand Up @@ -1488,43 +1488,42 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
case Tsarray:
case Tarray:
{
// Create a static array variable v of type arg->type
Identifier *id = Lexer::uniqueId("__arrayArg");
Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i));
t = t->semantic(loc, sc);
VarDeclaration *v = new VarDeclaration(loc, t, id,
(sc->func && sc->func->isSafe()) ? NULL : new VoidInitializer(loc));
v->storage_class |= STCtemp | STCctfe;
v->semantic(sc);
v->parent = sc->parent;

Expression *c = new DeclarationExp(loc, v);
c->type = v->type;
/* Create a static array variable v of type arg->type:
* T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ];
*
* The array literal in the initializer of the hidden variable
* is now optimized. See Bugzilla 2356.
*/
Type *tbn = ((TypeArray *)tb)->next;
Type *tsa = tbn->sarrayOf(nargs - i);

for (size_t u = i; u < nargs; u++)
Expressions *elements = new Expressions();
elements->setDim(nargs - i);
for (size_t u = 0; u < elements->dim; u++)
{
Expression *a = (*arguments)[u];
TypeArray *ta = (TypeArray *)tb;
(*arguments)[u] = a;
Expression *a = (*arguments)[i + u];
if (tret && a->implicitConvTo(tret))
{
a = a->implicitCastTo(sc, tret);
a = a->optimize(WANTvalue);
a = toDelegate(a, sc);
}
else
a = a->implicitCastTo(sc, ta->next);
Expression *e = new VarExp(loc, v);
e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams));
ConstructExp *ae = new ConstructExp(loc, e, a);
if (c)
c = new CommaExp(loc, c, ae);
else
c = ae;
a = a->implicitCastTo(sc, tbn);
(*elements)[u] = a;
}
arg = new VarExp(loc, v);
if (c)
arg = new CommaExp(loc, c, arg);
ArrayLiteralExp *ale = new ArrayLiteralExp(loc, elements);
ale->type = tsa;

Identifier *id = Lexer::uniqueId("__arrayArg");
VarDeclaration *v = new VarDeclaration(loc, tsa, id, new ExpInitializer(loc, ale));
v->storage_class |= STCtemp | STCctfe;
v->semantic(sc);
v->parent = sc->parent;

Expression *de = new DeclarationExp(loc, v);
Expression *ve = new VarExp(loc, v);
arg = Expression::combine(de, ve);
break;
}
case Tclass:
Expand Down
25 changes: 13 additions & 12 deletions src/mtype.c
Expand Up @@ -9083,25 +9083,26 @@ int Parameter::isTPL(Parameters *arguments)
* Determine if parameter is a lazy array of delegates.
* If so, return the return type of those delegates.
* If not, return NULL.
*
* Returns T if the type is one of the following forms:
* T delegate()[]
* T delegate()[dim]
*/

Type *Parameter::isLazyArray()
{
// if (inout == Lazy)
Type *tb = type->toBasetype();
if (tb->ty == Tsarray || tb->ty == Tarray)
{
Type *tb = type->toBasetype();
if (tb->ty == Tsarray || tb->ty == Tarray)
Type *tel = ((TypeArray *)tb)->next->toBasetype();
if (tel->ty == Tdelegate)
{
Type *tel = ((TypeArray *)tb)->next->toBasetype();
if (tel->ty == Tdelegate)
{
TypeDelegate *td = (TypeDelegate *)tel;
TypeFunction *tf = (TypeFunction *)td->next;
TypeDelegate *td = (TypeDelegate *)tel;
TypeFunction *tf = (TypeFunction *)td->next;

if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
{
return tf->next; // return type of delegate
}
if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
{
return tf->next; // return type of delegate
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions test/runnable/variadic.d
Expand Up @@ -1554,6 +1554,27 @@ void test9017()
void foo10279(int[][] strs...) @trusted { }
void bar10279() @safe { foo10279(); }

/***************************************/
// 13508

struct S13508
{
this(T)(T[] t...) {}
}

template make13508(T)
{
T make13508(Args...)(Args args)
{
return T(args);
}
}

void test13508() @safe @nogc
{
S13508 s = make13508!S13508(5);
}

/***************************************/
// 10414

Expand Down

0 comments on commit 1bba639

Please sign in to comment.