소스 검색

* Handle assigned(x) expressions entirely in first pass by converting them to "x<>nil", indicate that procedure variables should not be called by setting nf_load_procvar flag (which is already used with typeconvnode for exactly the same purpose). This allows to generate better code when assigned(x) is used on right side of assigments. Mantis #24572.

git-svn-id: trunk@25499 -
sergei 12 년 전
부모
커밋
dac8cbcefc
4개의 변경된 파일18개의 추가작업 그리고 12개의 파일을 삭제
  1. 9 3
      compiler/nadd.pas
  2. 1 4
      compiler/ncginl.pas
  3. 7 5
      compiler/ninl.pas
  4. 1 0
      compiler/node.pas

+ 9 - 3
compiler/nadd.pas

@@ -1017,9 +1017,15 @@ implementation
          if codegenerror then
            exit;
 
-         { tp procvar support }
-         maybe_call_procvar(left,true);
-         maybe_call_procvar(right,true);
+         { tp procvar support. Omit for converted assigned() nodes }
+         if not (nf_load_procvar in flags) then
+           begin
+             maybe_call_procvar(left,true);
+             maybe_call_procvar(right,true);
+           end
+         else
+           if not (nodetype in [equaln,unequaln]) then
+             InternalError(2013091601);
 
          { convert array constructors to sets, because there is no other operator
            possible for array constructors }

+ 1 - 4
compiler/ncginl.pas

@@ -579,10 +579,7 @@ implementation
 
     procedure tcginlinenode.second_assigned;
       begin
-        secondpass(tcallparanode(left).left);
-        hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,left.resultdef,OC_NE,0,tcallparanode(left).left.location,current_procinfo.CurrTrueLabel);
-        hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
-        location_reset(location,LOC_JUMP,OS_NO);
+        internalerror(2013091602);
       end;
 
     procedure Tcginlinenode.second_get_frame;

+ 7 - 5
compiler/ninl.pas

@@ -2783,9 +2783,8 @@ implementation
                       tcallparanode(left).get_paratype;
                     end;
 
-                  { converting to an add node is tricky because of differences
-                    in procvar handling between FPC and Delphi handling, so
-                    handle specially }
+                  { Postpone conversion into addnode until firstpass, so targets
+                    may override first_assigned and insert specific code. }
                   set_varstate(tcallparanode(left).left,vs_read,[vsf_must_be_valid]);
                   resultdef:=pasbool8type;
                 end;
@@ -3983,10 +3982,13 @@ implementation
           end;
        end;
 
+
      function tinlinenode.first_assigned: tnode;
        begin
-         result:=nil;
-         expectloc := LOC_JUMP;
+         { Comparison must not call procvars, indicate that with nf_load_procvar flag }
+         result:=caddnode.create(unequaln,tcallparanode(left).left,cnilnode.create);
+         include(result.flags,nf_load_procvar);
+         tcallparanode(left).left:=nil;
        end;
 
 

+ 1 - 0
compiler/node.pas

@@ -251,6 +251,7 @@ interface
 
          { ttypeconvnode, and the first one also treal/ord/pointerconstn }
          { second one also for subtractions of u32-u32 implicitly upcasted to s64 }
+         { last one also used on addnode to inhibit procvar calling }
          nf_explicit,
          nf_internal,  { no warnings/hints generated }
          nf_load_procvar,