Skip to content

Commit

Permalink
Merge pull request #4447 from 9rnsr/fix13729
Browse files Browse the repository at this point in the history
[REG2.067a] Issue 13729 - One not detected case of not purity
Conflicts:
	src/expression.c
  • Loading branch information
MartinNowak committed Feb 28, 2015
1 parent 128849d commit fe6729a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 6 deletions.
36 changes: 30 additions & 6 deletions src/expression.c
Expand Up @@ -2399,11 +2399,11 @@ void Expression::checkPurity(Scope *sc, FuncDeclaration *f)
}
else if (f->isInstantiated())
{
// The attributes of f is inferred from its body.
// The attributes of f are inferred from its body.
}
else if (f->isFuncLiteralDeclaration())
{
// The attributes of f is always inferred in its declared place.
// The attributes of f are always inferred in its declared place.
}
else
{
Expand Down Expand Up @@ -2492,11 +2492,35 @@ void Expression::checkPurity(Scope *sc, VarDeclaration *v)
* Therefore, this function and all its immediately enclosing
* functions must be pure.
*/
FuncDeclaration *ff = sc->func;
if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
/* Today, static local functions are impure by default, but they cannot
* violate purity of enclosing functions.
*
* auto foo() pure { // non instantiated funciton
* static auto bar() { // static, without pure attribute
* globalData++; // impure access
* // Although globalData is accessed inside bar,
* // it is not accessible inside pure foo.
* }
* }
*/
for (Dsymbol *s = sc->func; s; s = s->toParent2())
{
error("pure function '%s' cannot access mutable static data '%s'",
ff->toPrettyChars(), v->toChars());
FuncDeclaration *ff = s->isFuncDeclaration();
if (!ff)
break;
if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
{
error("pure function '%s' cannot access mutable static data '%s'",
ff->toPrettyChars(), v->toChars());
break;
}
/* If the enclosing is an instantiated function or a lambda, its
* attribute inference result is preferred.
*/
if (ff->isInstantiated())
break;
if (ff->isFuncLiteralDeclaration())
break;
}
}
else
Expand Down
26 changes: 26 additions & 0 deletions test/fail_compilation/testInference.d
Expand Up @@ -179,3 +179,29 @@ void test12422() pure
void bar12422()() { foo12422(); }
bar12422();
}

/*
TEST_OUTPUT:
---
fail_compilation/testInference.d(196): Error: pure function 'testInference.test13729a' cannot access mutable static data 'g13729'
fail_compilation/testInference.d(206): Error: pure function 'testInference.test13729b' cannot call impure function 'testInference.test13729b.foo!().foo'
---
*/
int g13729;

void test13729a() pure
{
static void foo() // typed as impure
{
g13729++; // disallowed
}
foo();
}
void test13729b() pure
{
static void foo()() // inferred to impure
{
g13729++;
}
foo(); // cannot call impure function
}

0 comments on commit fe6729a

Please sign in to comment.