www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4004] New: DMD 2.042 CTFE regression with functions taking ref parameters

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

           Summary: DMD 2.042 CTFE regression with functions taking ref
                    parameters
           Product: D
           Version: future
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: wrong-code
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: sandford jhu.edu



There appears to be a weird regression introduced in DMD 2.042 with the compile
time handling of ref parameters (runtime versions of the function are
unaffected). It appears that when a function taking a ref parameter passes it
as a ref parameter to another function. If the first function modifies the
parameter then modifications made by the second function won't be observed.

Below is a very simple test case:

import std.stdio: writeln;

void foo2(ref size_t offset) {
    offset = 8;
}

void foo(ref size_t offset) {
    auto okay = offset;         // Reading from the ref param is okay
    offset += 0;                // comment this line out and it works
    foo2(offset);
}
size_t bar() {
    size_t offset = 0;
    foo(offset);
    return offset;
}
template foobar() { immutable foobar = bar; }

void main(string[] args) {

writeln(foobar!(),'\t', bar ); // prints 0 8 instead of 8 8

}

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


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch
                 CC|                            |clugdbug yahoo.com.au



Reduced test case for test suite.
--------
void bug4004a(ref int a) {
assert(a==7);
a+=3;
}

void bug4004b(ref int b) {
    b= 7;
    bug4004a(b);    
}

int bug4004c() {
    int offset = 5;
    bug4004b(offset);
    return offset;
}

static assert(bug4004c()==10);
-------------------------
PATCH:

Index: interpret.c
===================================================================
--- interpret.c    (revision 420)
+++ interpret.c    (working copy)
   -53,7 +53,7   
 Expression *interpret_values(InterState *istate, Expression *earg,
FuncDeclaration *fd);

 ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type, Expression
*elem, size_t dim);
-Expression * resolveReferences(Expression *e, Expression *thisval);
+Expression * resolveReferences(Expression *e, Expression *thisval, bool
*isReference = NULL);

 /*************************************
  * Attempt to interpret a function given the arguments.
   -1107,8 +1107,11   
 // -------------------------------------------------------------
 // The variable used in a dotvar, index, or slice expression,
 // after 'out', 'ref', and 'this' have been removed.
-Expression * resolveReferences(Expression *e, Expression *thisval)
+// *isReference will be set to true if a reference was removed.
+Expression * resolveReferences(Expression *e, Expression *thisval, bool
*isReference /*=NULL */)
 {
+    if (isReference)
+    *isReference = false;
     for(;;)
     {
     if (e->op == TOKthis)
   -1131,6 +1134,8   
         VarExp *ve2 = (VarExp *)v->value;
         if (!ve2->var->isSymbolDeclaration())
         {
+            if (isReference)
+            *isReference = true;
             e = v->value;
             continue;
         }
   -2087,7 +2092,8   
     v->value = e2;
     return e2;
     }
-    e1 = resolveReferences(e1, istate->localThis);
+    bool destinationIsReference = false;
+    e1 = resolveReferences(e1, istate->localThis, &destinationIsReference);

     // Unless we have a simple var assignment, we're
     // only modifying part of the variable.
   -2167,7 +2174,8   
     {
     VarExp *ve = (VarExp *)e1;
     VarDeclaration *v = ve->var->isVarDeclaration();    
-    addVarToInterstate(istate, v);
+    if (!destinationIsReference)
+        addVarToInterstate(istate, v);
     v->value = newval;
     }
     else if (e1->op == TOKindex)

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


Walter Bright <bugzilla digitalmars.com> changed:

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



13:53:22 PDT ---
changeset 429

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


Don <clugdbug yahoo.com.au> changed:

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


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