Skip to content

Commit

Permalink
Merge remote branch 'd/master' into type-checked-arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
michelf committed Jul 12, 2011
2 parents 478306b + 7aeb7d2 commit 9b1e486
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 34 deletions.
45 changes: 19 additions & 26 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
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, new VoidInitializer(loc));
VarDeclaration *v = new VarDeclaration(loc, t, id, fd->isSafe() ? NULL : new VoidInitializer(loc));
v->storage_class |= STCctfe;
v->semantic(sc);
v->parent = sc->parent;
Expand Down Expand Up @@ -1367,17 +1367,23 @@ void Expression::checkPurity(Scope *sc, VarDeclaration *v, Expression *ethis)
* requiring each function in between to be impure.
*/
Dsymbol *vparent = v->toParent2();
for (Dsymbol *s = sc->func; s; s = s->toParent2())
Dsymbol *s = sc->func, *snext = s->toParent2();
// Make sure we're really finding parent *functions*, not parent
// class.
if (vparent->isFuncDeclaration() || snext != vparent)
{
if (s == vparent)
break;
FuncDeclaration *ff = s->isFuncDeclaration();
if (!ff)
break;
if (ff->setImpure())
{ error("pure nested function '%s' cannot access mutable data '%s'",
ff->toChars(), v->toChars());
break;
for (; s; s = s->toParent2())
{
if (s == vparent)
break;
FuncDeclaration *ff = s->isFuncDeclaration();
if (!ff)
break;
if (ff->setImpure())
{ error("pure nested function '%s' cannot access mutable data '%s'",
ff->toChars(), v->toChars());
break;
}
}
}
}
Expand Down Expand Up @@ -9594,22 +9600,9 @@ Expression *AssignExp::semantic(Scope *sc)
}
//error("cannot assign to static array %s", e1->toChars());
}
else if (e1->op == TOKslice)
else if (e1->op == TOKslice && t2->toBasetype()->ty == Tarray &&
t2->toBasetype()->nextOf()->implicitConvTo(t1->nextOf()))
{
/* This test is so we can do things like:
* byte[] b; b[] = [1,2,3];
*/
if (e2->op != TOKarrayliteral && e2->op != TOKstring)
{
Type *t1n = t1->toBasetype()->nextOf();
Type *t2n = t2->toBasetype()->nextOf();
assert(t1n && t2n);
if (!t2n->implicitConvTo(t1n))
{
error("cannot assign from %s to %s", t2->toChars(), t1->toChars());
return new ErrorExp();
}
}
e2 = e2->implicitCastTo(sc, e1->type->constOf());
}
else
Expand Down
7 changes: 5 additions & 2 deletions src/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -2676,9 +2676,9 @@ enum PURE FuncDeclaration::isPure()
TypeFunction *tf = (TypeFunction *)type;
if (flags & FUNCFLAGpurityInprocess)
setImpure();
enum PURE purity = tf->purity;
if (purity == PUREfwdref)
if (tf->purity == PUREfwdref)
tf->purityLevel();
enum PURE purity = tf->purity;
if (purity > PUREweak && needThis())
{ // The attribute of the 'this' reference affects purity strength
if (type->mod & (MODimmutable | MODwild))
Expand All @@ -2688,6 +2688,9 @@ enum PURE FuncDeclaration::isPure()
else
purity = PUREweak;
}
tf->purity = purity;
// ^ This rely on the current situation that every FuncDeclaration has a
// unique TypeFunction.
return purity;
}

Expand Down
5 changes: 4 additions & 1 deletion src/interpret.c
Original file line number Diff line number Diff line change
Expand Up @@ -2997,14 +2997,15 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
Expression * newval = NULL;

if (!wantRef)
// We need to treat pointers specially, because TOKsymoff can be used to
{ // We need to treat pointers specially, because TOKsymoff can be used to
// return a value OR a pointer
assert(e1);
assert(e1->type);
if ((e1->type->ty == Tpointer && e1->type->nextOf()->ty != Tfunction) && (e2->op == TOKsymoff || e2->op==TOKaddress || e2->op==TOKvar)) // && (e1->op==TOKaddress)) //TOKsymoff || e1->op==TOKdotvar))
newval = this->e2->interpret(istate, ctfeNeedLvalue);
else
newval = this->e2->interpret(istate);
}
if (newval == EXP_CANT_INTERPRET)
return newval;
// ----------------------------------------------------
Expand Down Expand Up @@ -3969,6 +3970,8 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal)
e = e->interpret(istate);
if (e != EXP_CANT_INTERPRET)
{
if (e->op == TOKslice)
e= resolveSlice(e);
e = expType(type, e);
e = copyLiteral(e);
}
Expand Down
6 changes: 2 additions & 4 deletions src/opover.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,9 @@ Expression *BinExp::op_overload(Scope *sc)

Objects *targsi = NULL;
#if DMDV2
if (!s && !s_r && op != TOKequal && op != TOKnotequal && op != TOKassign)
if (!s && !s_r && op != TOKequal && op != TOKnotequal && op != TOKassign &&
op != TOKplusplus && op != TOKminusminus)
{
if (op == TOKplusplus || op == TOKminusminus)
return NULL;

/* Try the new D2 scheme, opBinary and opBinaryRight
*/
if (ad1)
Expand Down
23 changes: 23 additions & 0 deletions test/compilable/interpret3.d
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,29 @@ int zfs()

static assert(!is(typeof(compiles!(zfs()))));

/**************************************************
.dup must protect string literals
**************************************************/

string mutateTheImmutable(immutable string _s)
{
char[] s = _s.dup;
foreach(ref c; s)
c = 'x';
return s.idup;
}

string doharm(immutable string _name)
{
return mutateTheImmutable(_name[2..$].idup);
}

enum victimLiteral = "CL_INVALID_CONTEXT";

enum thug = doharm(victimLiteral);
static assert(victimLiteral == "CL_INVALID_CONTEXT");


/**************************************************
Use $ in a slice of a dotvar slice
**************************************************/
Expand Down
13 changes: 13 additions & 0 deletions test/runnable/aliasthis.d
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,25 @@ void test4()

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

void test5()
{
static struct Double1 {
double val = 1;
alias val this;
}
static Double1 x() { return Double1(); }
x()++;
}

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

int main()
{
test1();
test2();
test3();
test4();
test5();

printf("Success\n");
return 0;
Expand Down
9 changes: 8 additions & 1 deletion test/runnable/testsafe.d
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,13 @@ void structcast()
static assert(!__traits(compiles, c = cast(C)a));
static assert(!__traits(compiles, c = cast(C)b));
}


@safe
void varargs()
{
static void fun(string[] val...) {}
fun("a");
}

void main() { }

75 changes: 75 additions & 0 deletions test/runnable/xtest46.d
Original file line number Diff line number Diff line change
Expand Up @@ -3192,6 +3192,79 @@ pure int test4031()

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

struct S6230 {
int p;
int q() const pure {
return p;
}
void r() pure {
p = 231;
}
}
class C6230 {
int p;
int q() const pure {
return p;
}
void r() pure {
p = 552;
}
}
int q6230(ref const S6230 s) pure { // <-- Currently OK
return s.p;
}
int q6230(ref const C6230 c) pure { // <-- Currently OK
return c.p;
}
void r6230(ref S6230 s) pure {
s.p = 244;
}
void r6230(ref C6230 c) pure {
c.p = 156;
}
bool test6230pure() pure {
auto s = S6230(4);
assert(s.p == 4);
assert(q6230(s) == 4);
assert(s.q == 4);

auto c = new C6230;
c.p = 6;
assert(q6230(c) == 6);
assert(c.q == 6);

r6230(s);
assert(s.p == 244);
s.r();
assert(s.p == 231);

r6230(c);
assert(c.p == 156);
c.r();
assert(c.p == 552);

return true;
}
void test6230() {
assert(test6230pure());
}

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

void test6264()
{
struct S { auto opSlice() { return this; } }
int[] a;
S s;
static assert(!is(typeof(a[] = s[])));
int*[] b;
static assert(!is(typeof(b[] = [new immutable(int)])));
char[] c = new char[](5);
c[] = "hello";
}

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

int main()
{
test1();
Expand Down Expand Up @@ -3353,6 +3426,8 @@ int main()
test4258();
test4963();
test4031();
test6230();
test6264();

printf("Success\n");
return 0;
Expand Down

0 comments on commit 9b1e486

Please sign in to comment.