Commits

Iain Buclaw committed 88b1c45

Issue #202 - evaluate extern D function arguments in order left to right.

Comments (0)

Files changed (2)

     // Using TREE_TYPE(callable) instead of func_type->toCtype can save a build_method_type
     tree func_type_node = TREE_TYPE(callable);
     tree actual_callee  = callable;
+    tree saved_args = NULL_TREE;
 
     ListMaker actual_arg_list;
 
             Parameter * formal_arg = Parameter::getNth(formal_args, fi);
             actual_arg_tree = convertForArgument(actual_arg_exp, formal_arg);
             actual_arg_tree = d_convert_basic(trueArgumentType(formal_arg), actual_arg_tree);
-
             ++fi;
         }
         else
                     actual_arg_tree = d_convert_basic(prom_type, actual_arg_tree);
             }
         }
+        /* Evaluate the argument before passing to the function.
+           Needed for left to right evaluation.  */
+        if (func_type->linkage == LINKd && !isFreeOfSideEffects(actual_arg_tree))
+        {
+            actual_arg_tree = maybeMakeTemp(actual_arg_tree);
+            saved_args = maybeVoidCompound(saved_args, actual_arg_tree);
+        }
 
         actual_arg_list.cons(actual_arg_tree);
     }
 
     tree result = buildCall(TREE_TYPE(func_type_node), actual_callee, actual_arg_list.head);
-    return maybeExpandSpecialCall(result);
+    result = maybeExpandSpecialCall(result);
+
+    return maybeCompound(saved_args, result);
 }
 
 tree
 {
     int nargs = list_length(args);
     tree * pargs = new tree[nargs];
-    for (int i = 0; args; args = TREE_CHAIN(args), i++)
+    for (size_t i = 0; args; args = TREE_CHAIN(args), i++)
         pargs[i] = TREE_VALUE(args);
     
     return build_call_array(type, callee, nargs, pargs);
 
     int n_parameters = parameters ? parameters->dim : 0;
 
-    int reverse_args = 0; //tf->linkage == LINKd && tf->varargs != 1;
-
     // Special arguments...
     static const int VTHIS = -2;
     static const int VARGUMENTS = -1;
         g.ofile->setDeclLoc(parm_decl, param ? (Dsymbol*) param : (Dsymbol*) this);
 
         // chain them in the correct order
-        if (reverse_args)
-        {
-            param_list = chainon (parm_decl, param_list);
-        }
-        else
-        {
-            param_list = chainon (param_list, parm_decl);
-        }
+        param_list = chainon (param_list, parm_decl);
     }
 
     // param_list is a number of PARM_DECL trees chained together (*not* a TREE_LIST of PARM_DECLs).