Selaa lähdekoodia

* Force managed types to be always returned in parameters, independent of target (primitive types were already handled that way; the patch affects small records with fields of managed types).
* Generating code to finalize result on exception at callee side is no longer necessary.

git-svn-id: trunk@26228 -

sergei 11 vuotta sitten
vanhempi
commit
6ea9ce1077
2 muutettua tiedostoa jossa 12 lisäystä ja 28 poistoa
  1. 5 3
      compiler/paramgr.pas
  2. 7 25
      compiler/psub.pas

+ 5 - 3
compiler/paramgr.pas

@@ -589,8 +589,10 @@ implementation
     function tparamanager.handle_common_ret_in_param(def: tdef;
       pd: tabstractprocdef; out retinparam: boolean): boolean;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
+        { This must be system independent: safecall and record constructor result
+          is always returned in param.
+          Furthermore, any managed type is returned in param, in order to avoid
+          its finalization on exception at callee side. }
         if (tf_safecall_exceptions in target_info.flags) and
            (pd.proccalloption=pocall_safecall) or
            (
@@ -603,7 +605,7 @@ implementation
                  is_objectpascal_helper(tdef(pd.owner.defowner))
                )
              )
-           ) then
+           ) or is_managed_type(def) then
           begin
             retinparam:=true;
             exit(true);

+ 7 - 25
compiler/psub.pas

@@ -651,28 +651,6 @@ implementation
       end;
 
 
-    function generate_except_block:tnode;
-      var
-        newstatement : tstatementnode;
-      begin
-        generate_except_block:=internalstatements(newstatement);
-
-        { a constructor needs call destructor (if available) when it
-          is not inherited }
-        if not assigned(current_structdef) or
-           (current_procinfo.procdef.proctypeoption<>potype_constructor) then
-          begin
-            { no constructor }
-            { must be the return value finalized before reraising the exception? }
-            if (not is_void(current_procinfo.procdef.returndef)) and
-               is_managed_type(current_procinfo.procdef.returndef) and
-               (not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef)) and
-               (not is_class(current_procinfo.procdef.returndef)) then
-              addstatement(newstatement,cnodeutils.finalize_data_node(load_result_node));
-          end;
-      end;
-
-
 {****************************************************************************
                                   TCGProcInfo
 ****************************************************************************}
@@ -820,7 +798,6 @@ implementation
         finalcode,
         bodyentrycode,
         bodyexitcode,
-        exceptcode,
         wrappedbody,
         newblock     : tnode;
         codestatement,
@@ -864,10 +841,15 @@ implementation
            not(po_assembler in procdef.procoptions) and
            not(target_info.system in systems_garbage_collected_managed_types) then
           begin
+            { Any result of managed type must be returned in parameter }
+            if is_managed_type(procdef.returndef) and
+               (not paramanager.ret_in_param(procdef.returndef,procdef)) and
+               (not is_class(procdef.returndef)) then
+               InternalError(2013121301);
+
             { Generate special exception block only needed when
               implicit finaly is used }
             current_filepos:=exitpos;
-            exceptcode:=generate_except_block;
             { Generate code that will be in the try...finally }
             finalcode:=internalstatements(codestatement);
             addstatement(codestatement,final_asmnode);
@@ -877,7 +859,7 @@ implementation
             wrappedbody:=ctryfinallynode.create_implicit(
                code,
                finalcode,
-               exceptcode);
+               cnothingnode.create);
             { afterconstruction must be called after final_asmnode, because it
                has to execute after the temps have been finalised in case of a
                refcounted class (afterconstruction decreases the refcount