www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2807] New: Marking a nested function as 'pure' may cause bad code generations silently accepted

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2807

           Summary: Marking a nested function as 'pure' may cause bad code
                    generations silently accepted
           Product: D
           Version: 2.027
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: accepts-invalid
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: clugdbug yahoo.com.au


The following assert fails, effectively generating bad code.

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);
}


-- 
Apr 06 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2807






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)
        {


-- 
Apr 22 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2807






Created an attachment (id=335)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=335&action=view)
Patch against 2.029. Includes patch for the related bug 2695, as well.


-- 
Apr 22 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2807


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED





Fixed DMD2.030

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 14 2009