Patch against 2.029. Includes patch for the related bug 2695, as well.
text/plain
2022
Comments
Comment #0 by clugdbug — 2009-04-06T08:03:34Z
The following assert fails, effectively generating bad code.
My patch in #2804 doesn't fix this, but it does reduce the need for marking nested functions as pure. A nested function which is marked as pure should not be able to access variables from the enclosing scope.
It's probably adequate to simply disallow 'pure' on nested functions for now.
---
pure int double_sqr(int x) {
int y = x;
void do_sqr() pure { y *= y; }
do_sqr();
return y;
}
void main(string[] args) {
assert(double_sqr(10) == 100);
}
Comment #1 by clugdbug — 2009-04-22T15:07:24Z
And here's a patch. This makes it safe to have nested pure functions.
A nested pure function is only permitted to access its own variables, plus immutables and manifest constants from outer scopes.
===================================================================
--- expression.c (revision 24)
+++ expression.c (working copy)
@@ -3994,12 +3994,21 @@
#if 1
if (sc->func) {
FuncDeclaration *outerfunc=sc->func;
+ bool hasPureParent=false;
while (outerfunc->toParent2() && outerfunc->toParent2()->isFuncDeclaration()) {
+ hasPureParent |= outerfunc->isPure();
outerfunc = outerfunc->toParent2()->isFuncDeclaration();
}
- if (outerfunc->isPure() && !sc->intypeof && v->isDataseg() && !v->isInvariant())
+ hasPureParent |= outerfunc->isPure();
+ // If ANY of its enclosing functions are pure, it cannot do anything impure.
+ // If it is pure, it cannot access any mutable variables other than those inside itself.
+ if (hasPureParent && !sc->intypeof && v->isDataseg() && !v->isInvariant()) {
error("pure function '%s' cannot access mutable static data '%s'", sc->func->toChars(), v->toChars());
- }
+ } else if (sc->func->isPure() && sc->parent!=v->parent && !sc->intypeof && !v->isInvariant() && !(v->storage_class & STCmanifest)) {
+ error("pure nested function '%s' cannot access mutable data '%s'", sc->func->toChars(), v->toChars());
+ if (v->isEnumDeclaration()) error("enum");
+ }
+ }
#else
if (sc->func && sc->func->isPure() && !sc->intypeof)
{
Comment #2 by clugdbug — 2009-04-22T15:09:04Z
Created attachment 335
Patch against 2.029. Includes patch for the related bug 2695, as well.