Przeglądaj źródła

* Set pi_uses_exceptions flag when creating/firstpassing ttryexceptnode or ttryfinallynode, not when parsing try statements. It ensures that procedures with exception handling nodes created by compiler (constructors in the first place, but also for..in loops with TObject iterators, etc.) are handled the same way as ones containing exception nodes from user code.
* Modified code generation for constructors so they don't always use pi_needs_implicit_finally. It used to prevent stackframe optimization while not preventing regvar optimization ( tabstractvarsym.is_regvar() checks for pi_uses_exceptions but not for pi_needs_implicit_finally, and constructors were not getting pi_uses_exceptions), resulting in strange code using both exceptions and regvars.
Once setting of pi_uses_exception is fixed, the implicit finally frame can be omitted unless managed temps or local vars are actually present.

git-svn-id: trunk@19668 -

sergei 13 lat temu
rodzic
commit
6cb6569d51
3 zmienionych plików z 9 dodań i 4 usunięć
  1. 2 0
      compiler/nflw.pas
  2. 0 2
      compiler/pstatmnt.pas
  3. 7 2
      compiler/psub.pas

+ 2 - 0
compiler/nflw.pas

@@ -1985,6 +1985,7 @@ implementation
       begin
       begin
          result:=nil;
          result:=nil;
          include(current_procinfo.flags,pi_do_call);
          include(current_procinfo.flags,pi_do_call);
+         include(current_procinfo.flags,pi_uses_exceptions);
          expectloc:=LOC_VOID;
          expectloc:=LOC_VOID;
          firstpass(left);
          firstpass(left);
          { on statements }
          { on statements }
@@ -2003,6 +2004,7 @@ implementation
     constructor ttryfinallynode.create(l,r:tnode);
     constructor ttryfinallynode.create(l,r:tnode);
       begin
       begin
         inherited create(tryfinallyn,l,r,nil,nil);
         inherited create(tryfinallyn,l,r,nil,nil);
+        include(current_procinfo.flags,pi_uses_exceptions);
         implicitframe:=false;
         implicitframe:=false;
       end;
       end;
 
 

+ 0 - 2
compiler/pstatmnt.pas

@@ -821,8 +821,6 @@ implementation
          unit_found:boolean;
          unit_found:boolean;
          oldcurrent_exceptblock: integer;
          oldcurrent_exceptblock: integer;
       begin
       begin
-         include(current_procinfo.flags,pi_uses_exceptions);
-
          p_default:=nil;
          p_default:=nil;
          p_specific:=nil;
          p_specific:=nil;
 
 

+ 7 - 2
compiler/psub.pas

@@ -303,7 +303,6 @@ implementation
               begin
               begin
                 if is_class(current_structdef) then
                 if is_class(current_structdef) then
                   begin
                   begin
-                    include(current_procinfo.flags,pi_needs_implicit_finally);
                     srsym:=search_struct_member(current_structdef,'NEWINSTANCE');
                     srsym:=search_struct_member(current_structdef,'NEWINSTANCE');
                     if assigned(srsym) and
                     if assigned(srsym) and
                        (srsym.typ=procsym) then
                        (srsym.typ=procsym) then
@@ -718,7 +717,13 @@ implementation
           end
           end
         else
         else
           begin
           begin
-            maybe_add_constructor_wrapper(code,false);
+            { Constructors need the destroy-on-exception code even if they don't
+              use managed variables/temps. }
+            if (cs_implicit_exceptions in current_settings.moduleswitches) and
+               (is_class(procdef.struct) and (procdef.proctypeoption=potype_constructor)) then
+              maybe_add_constructor_wrapper(code,true)
+            else
+              maybe_add_constructor_wrapper(code,false);
             addstatement(newstatement,loadpara_asmnode);
             addstatement(newstatement,loadpara_asmnode);
             addstatement(newstatement,stackcheck_asmnode);
             addstatement(newstatement,stackcheck_asmnode);
             addstatement(newstatement,entry_asmnode);
             addstatement(newstatement,entry_asmnode);