Skip to content

Commit

Permalink
Bug 6230: Member functions can no longer be weakly pure
Browse files Browse the repository at this point in the history
  • Loading branch information
kennytm committed Jul 4, 2011
1 parent b135734 commit c393afb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 12 deletions.
26 changes: 16 additions & 10 deletions src/expression.c
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
7 changes: 5 additions & 2 deletions src/func.c
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
59 changes: 59 additions & 0 deletions test/runnable/xtest46.d
Expand Up @@ -3192,6 +3192,64 @@ 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());
}


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

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

0 comments on commit c393afb

Please sign in to comment.