Browse Source

* For cdecl functions the funcret is not popped by the caller when it is passed
as a para. But in case of the safecall convention, the funcret is always
returned as para and from the c point-of-view this is a normal para. So it has
to be popped normally. This was done by correcting the pop_size in
ti386callnode.pop_parasize but it's better to do this directly in
tcgcallnode.pass_generate_code.

git-svn-id: trunk@15994 -

joost 15 years ago
parent
commit
b938ea0f2a
2 changed files with 7 additions and 8 deletions
  1. 0 6
      compiler/i386/n386cal.pas
  2. 7 2
      compiler/ncgcal.pas

+ 0 - 6
compiler/i386/n386cal.pas

@@ -91,12 +91,6 @@ implementation
             paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
             paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
           inc(pop_size,sizeof(aint));
           inc(pop_size,sizeof(aint));
 
 
-        { Safecall generates a hidden return value, which is always passed }
-        { in eax. So there is nothing to remove from the stack.            }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (procdefinition.proccalloption=pocall_safecall) then
-          inc(pop_size,sizeof(aint));
-
         { better than an add on all processors }
         { better than an add on all processors }
         if pop_size=4 then
         if pop_size=4 then
           begin
           begin

+ 7 - 2
compiler/ncgcal.pas

@@ -838,8 +838,13 @@ implementation
           begin
           begin
             pop_size:=pushedparasize;
             pop_size:=pushedparasize;
             { for Cdecl functions we don't need to pop the funcret when it
             { for Cdecl functions we don't need to pop the funcret when it
-              was pushed by para }
-            if paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
+              was pushed by para. Except for safecall functions with
+              safecall-exceptions enabled. In that case the funcret is always
+              returned as a para which is considered a normal para on the
+              c-side, so the funcret has to be pop'ed normally. }
+            if not ((procdefinition.proccalloption=pocall_safecall) and
+                    (tf_safecall_exceptions in target_info.flags)) and
+               paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
               dec(pop_size,sizeof(pint));
               dec(pop_size,sizeof(pint));
             { Remove parameters/alignment from the stack }
             { Remove parameters/alignment from the stack }
             pop_parasize(pop_size);
             pop_parasize(pop_size);