www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3912] New: pure static nested functions are not recognized as pure

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

           Summary: pure static nested functions are not recognized as
                    pure
           Product: D
           Version: 2.040
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: clugdbug yahoo.com.au


--- Comment #0 from Don <clugdbug yahoo.com.au> 2010-03-09 04:29:59 PST ---
This bug was reported in a comment in bug 3835 ("fragile CTFE"), but it does
not involve CTFE, so I've created a new bug for it.
=====
pure int genFactorials(int n) {
    static pure int factorial(int n) {
      if (n==2) return 1;
      return factorial(2);
    }
    return factorial(n);
}

============================
bug.d(7): Error: pure function 'factorial' cannot call impure function 'factor
ial'

bug.d(9): Error: pure function 'genFactorials' cannot call impure function 'fa
ctorial'

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 09 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3912


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #1 from Don <clugdbug yahoo.com.au> 2010-03-10 13:48:03 PST ---
This was a mistake in my patch for bug 2804 (one of my first ever patches).
I had only considered one level of nesting.
I've also changed the error message so that it names the pure function, not the
nested impure one.
There's also some error messages with spurious newlines in them.
Here's a test case which should fail:
---
      void f() pure
      { void g()
        {
         void h() pure
         {
            void i() { }
            void j() { i(); g(); }
         }
        }
      }
------

PATCH against DMD2.041. Expression::checkPurity(), around line 1280.

Index: expression.c
===================================================================
--- expression.c    (revision 413)
+++ expression.c    (working copy)
   -1296,17 +1296,31   
      * i() can call h() and g() but not f()
      */
     FuncDeclaration *outerfunc = sc->func;
-    while (outerfunc->toParent2() &&
outerfunc->toParent2()->isFuncDeclaration())
+    // Find the closest pure parent of the calling function
+    while (outerfunc->toParent2() && !outerfunc->isPure()
+       && outerfunc->toParent2()->isFuncDeclaration() )
     {
         outerfunc = outerfunc->toParent2()->isFuncDeclaration();
     }
-    if (outerfunc->isPure() && !sc->intypeof && (!f->isNested() &&
!f->isPure()))
-        error("pure function '%s' cannot call impure function '%s'\n",
-        sc->func->toChars(), f->toChars());
+    // Find the closest pure parent of the called function
+    FuncDeclaration *calledparent = f;
+    while (calledparent->toParent2() && !calledparent->isPure()
+        && calledparent->toParent2()->isFuncDeclaration() )
+    {
+        calledparent = calledparent->toParent2()->isFuncDeclaration();
+    }
+    // If the caller has a pure parent, then either the called func must be
pure,
+        // OR, they must have the same pure parent.
+    if (outerfunc->isPure() && !sc->intypeof && 
+        !(f->isPure() || (calledparent == outerfunc)))
+    {
+        error("pure function '%s' cannot call impure function '%s'",
+        outerfunc->toChars(), f->toChars());
+    }
     }
 #else
     if (sc->func && sc->func->isPure() && !sc->intypeof && !f->isPure())
-    error("pure function '%s' cannot call impure function '%s'\n",
+    error("pure function '%s' cannot call impure function '%s'",
         sc->func->toChars(), f->toChars());
 #endif
 }
   -1315,7 +1329,7   
 {
     if (sc->func && sc->func->isSafe() && !sc->intypeof &&
     !f->isSafe() && !f->isTrusted())
-    error("safe function '%s' cannot call system function '%s'\n",
+    error("safe function '%s' cannot call system function '%s'",
         sc->func->toChars(), f->toChars());
 }
 #endif

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3912


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com


--- Comment #2 from Walter Bright <bugzilla digitalmars.com> 2010-03-12
20:26:01 PST ---
changeset 414

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 12 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3912


Don <clugdbug yahoo.com.au> changed:

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


--- Comment #3 from Don <clugdbug yahoo.com.au> 2010-03-27 07:49:36 PDT ---
Fixed DMD2.042.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 27 2010