Browse Source

* ansistring memory leaks fixed

florian 27 years ago
parent
commit
d656d708b7
8 changed files with 367 additions and 256 deletions
  1. 252 213
      compiler/cg386add.pas
  2. 45 4
      compiler/cg386cal.pas
  3. 32 21
      compiler/cg386cnv.pas
  4. 4 11
      compiler/cg386flw.pas
  5. 11 1
      compiler/cg386ld.pas
  6. 11 2
      compiler/i386.pas
  7. 6 2
      compiler/pass_2.pas
  8. 6 2
      compiler/symdef.inc

+ 252 - 213
compiler/cg386add.pas

@@ -126,6 +126,7 @@ implementation
         cmpop      : boolean;
         savedunused : tregisterset;
         hr : treference;
+        oldrl : plinkedlist;
 
       begin
         { string operations are not commutative }
@@ -137,6 +138,8 @@ implementation
                 case p^.treetype of
                    addn:
                      begin
+                        oldrl:=temptoremove;
+                        temptoremove:=new(plinkedlist,init);
                         cmpop:=false;
                         secondpass(p^.left);
                         pushed:=maybe_push(p^.right^.registers32,p);
@@ -168,19 +171,28 @@ implementation
                         p^.location.register:=getexplicitregister32(R_EAX);
                         p^.location.loc:=LOC_REGISTER;
                         emit_reg_reg(A_MOV,S_L,R_EAX,p^.location.register);
+
+                        { unused:=unused-[R_EAX]; }
+                        removetemps(exprasmlist,temptoremove);
+                        dispose(temptoremove,done);
+                        temptoremove:=oldrl;
+                        { unused:=unused+[R_EAX]; }
+
                         popusedregisters(pushedregs);
                         maybe_loadesi;
                         ungetiftemp(p^.left^.location.reference);
                         ungetiftemp(p^.right^.location.reference);
                         reset_reference(hr);
                         gettempansistringreference(hr);
-                        {temptoremove^.concat(new(ptemptodestroy,init(hr,p^.resulttype)));}
+                        addtemptodestroy(p^.resulttype,hr);
                         exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,p^.location.register,
                           newreference(hr))));
                      end;
                    ltn,lten,gtn,gten,
                    equaln,unequaln:
                      begin
+                        oldrl:=temptoremove;
+                        temptoremove:=new(plinkedlist,init);
                         secondpass(p^.left);
                         pushed:=maybe_push(p^.right^.registers32,p);
                         secondpass(p^.right);
@@ -214,6 +226,11 @@ implementation
                             exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,p^.left^.location.register)));
                         end;
                         emitcall('FPC_ANSISTR_COMPARE',true);
+                        unused:=unused-[R_EAX];
+                        removetemps(exprasmlist,temptoremove);
+                        dispose(temptoremove,done);
+                        temptoremove:=oldrl;
+                        unused:=unused+[R_EAX];
                         emit_reg_reg(A_OR,S_L,R_EAX,R_EAX);
                         popusedregisters(pushedregs);
                         maybe_loadesi;
@@ -489,6 +506,7 @@ implementation
 {$ifdef SUPPORT_MMX}
          mmxbase : tmmxtype;
 {$endif SUPPORT_MMX}
+         pushedreg : tpushed;
 
       begin
       { to make it more readable, string and set (not smallset!) have their
@@ -1099,15 +1117,6 @@ implementation
                                   mboverflow:=true;
                                 end;
                              end;
-                      muln : begin
-                                begin
-                                  if unsigned then
-                                   op:=A_MUL
-                                  else
-                                   op:=A_IMUL;
-                                  mboverflow:=true;
-                                end;
-                             end;
                       subn : begin
                                 op:=A_SUB;
                                 op2:=A_SBB;
@@ -1139,250 +1148,277 @@ implementation
                            op:=A_AND;
                            op2:=A_AND;
                         end;
+                      muln:
+                        ;
                    else
                      CGMessage(type_e_mismatch);
                    end;
 
-
-                   { left and right no register?  }
-                   { then one must be demanded    }
-                   if (p^.left^.location.loc<>LOC_REGISTER) and
-                      (p^.right^.location.loc<>LOC_REGISTER) then
+                   if p^.treetype=muln then
                      begin
-                        { register variable ? }
-                        if (p^.left^.location.loc=LOC_CREGISTER) then
-                          begin
-                             { it is OK if this is the destination }
-                             if is_in_dest then
-                               begin
-                                  hregister:=p^.location.registerlow;
-                                  hregister2:=p^.location.registerhigh;
-                                  emit_reg_reg(A_MOV,S_L,p^.left^.location.registerlow,
-                                    hregister);
-                                  emit_reg_reg(A_MOV,S_L,p^.left^.location.registerlow,
-                                    hregister2);
-                               end
-                             else
-                             if cmpop then
-                               begin
-                                  { do not disturb the register }
-                                  hregister:=p^.location.registerlow;
-                                  hregister2:=p^.location.registerhigh;
-                               end
-                             else
-                               begin
-                                  hregister:=getregister32;
-                                  hregister2:=getregister32;
-                                  emit_reg_reg(A_MOV,S_L,p^.left^.location.registerlow,
-                                    hregister);
-                                  emit_reg_reg(A_MOV,S_L,p^.left^.location.registerhigh,
-                                    hregister2);
-                               end
-                          end
+                        if cs_check_overflow in aktlocalswitches then
+                          push_int(1)
                         else
-                          begin
-                             ungetiftemp(p^.left^.location.reference);
-                             del_reference(p^.left^.location.reference);
-                             if is_in_dest then
-                               begin
-                                  hregister:=p^.location.registerlow;
-                                  hregister2:=p^.location.registerhigh;
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                                    newreference(p^.left^.location.reference),hregister)));
-                                  hr:=newreference(p^.left^.location.reference);
-                                  inc(hr^.offset,4);
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                                    hr,hregister2)));
-                               end
-                             else
-                               begin
-                                  hregister:=getregister32;
-                                  hregister2:=getregister32;
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                                    newreference(p^.left^.location.reference),hregister)));
-                                  hr:=newreference(p^.left^.location.reference);
-                                  inc(hr^.offset,4);
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                                    hr,hregister2)));
-                               end;
-                          end;
-                        clear_location(p^.location);
+                          push_int(0);
+                        release_qword_loc(p^.left^.location);
+                        release_qword_loc(p^.right^.location);
+                        p^.location.registerlow:=getexplicitregister32(R_EAX);
+                        p^.location.registerhigh:=getexplicitregister32(R_EDX);
+                        { ($80 shr byte(r) }
+                        pushusedregisters(pushedreg,$ff);
+                        emit_pushq_loc(p^.left^.location);
+                        emit_pushq_loc(p^.right^.location);
+                        if porddef(p^.resulttype)^.typ=u64bit then
+                          emitcall('FPC_MUL_QWORD',true)
+                        else
+                          emitcall('FPC_MUL_INT64',true);
+                        emit_reg_reg(A_MOV,S_L,R_EAX,p^.location.registerlow);
+                        emit_reg_reg(A_MOV,S_L,R_EDX,p^.location.registerhigh);
+                        popusedregisters(pushedreg);
                         p^.location.loc:=LOC_REGISTER;
-                        p^.location.registerlow:=hregister;
-                        p^.location.registerhigh:=hregister2;
                      end
                    else
-                     { if on the right the register then swap }
-                     if not(noswap) and (p^.right^.location.loc=LOC_REGISTER) then
-                       begin
-                          swap_location(p^.location,p^.right^.location);
-
-                          { newly swapped also set swapped flag }
-                          p^.swaped:=not(p^.swaped);
-                       end;
-                   { at this point, p^.location.loc should be LOC_REGISTER }
-                   { and p^.location.register should be a valid register   }
-                   { containing the left result                            }
-
-                    if p^.right^.location.loc<>LOC_REGISTER then
                      begin
-                        if (p^.treetype=subn) and p^.swaped then
+                        { left and right no register?  }
+                        { then one must be demanded    }
+                        if (p^.left^.location.loc<>LOC_REGISTER) and
+                           (p^.right^.location.loc<>LOC_REGISTER) then
                           begin
-                             if p^.right^.location.loc=LOC_CREGISTER then
+                             { register variable ? }
+                             if (p^.left^.location.loc=LOC_CREGISTER) then
                                begin
-                                  emit_reg_reg(A_MOV,opsize,p^.right^.location.register,R_EDI);
-                                  emit_reg_reg(op,opsize,p^.location.register,R_EDI);
-                                  emit_reg_reg(A_MOV,opsize,R_EDI,p^.location.register);
+                                  { it is OK if this is the destination }
+                                  if is_in_dest then
+                                    begin
+                                       hregister:=p^.location.registerlow;
+                                       hregister2:=p^.location.registerhigh;
+                                       emit_reg_reg(A_MOV,S_L,p^.left^.location.registerlow,
+                                         hregister);
+                                       emit_reg_reg(A_MOV,S_L,p^.left^.location.registerlow,
+                                         hregister2);
+                                    end
+                                  else
+                                  if cmpop then
+                                    begin
+                                       { do not disturb the register }
+                                       hregister:=p^.location.registerlow;
+                                       hregister2:=p^.location.registerhigh;
+                                    end
+                                  else
+                                    begin
+                                       hregister:=getregister32;
+                                       hregister2:=getregister32;
+                                       emit_reg_reg(A_MOV,S_L,p^.left^.location.registerlow,
+                                         hregister);
+                                       emit_reg_reg(A_MOV,S_L,p^.left^.location.registerhigh,
+                                         hregister2);
+                                    end
                                end
                              else
                                begin
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
-                                    newreference(p^.right^.location.reference),R_EDI)));
-                                  exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,p^.location.register,R_EDI)));
-                                  exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,opsize,R_EDI,p^.location.register)));
-                                  ungetiftemp(p^.right^.location.reference);
-                                  del_reference(p^.right^.location.reference);
+                                  ungetiftemp(p^.left^.location.reference);
+                                  del_reference(p^.left^.location.reference);
+                                  if is_in_dest then
+                                    begin
+                                       hregister:=p^.location.registerlow;
+                                       hregister2:=p^.location.registerhigh;
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                         newreference(p^.left^.location.reference),hregister)));
+                                       hr:=newreference(p^.left^.location.reference);
+                                       inc(hr^.offset,4);
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                         hr,hregister2)));
+                                    end
+                                  else
+                                    begin
+                                       hregister:=getregister32;
+                                       hregister2:=getregister32;
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                         newreference(p^.left^.location.reference),hregister)));
+                                       hr:=newreference(p^.left^.location.reference);
+                                       inc(hr^.offset,4);
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                         hr,hregister2)));
+                                    end;
                                end;
+                             clear_location(p^.location);
+                             p^.location.loc:=LOC_REGISTER;
+                             p^.location.registerlow:=hregister;
+                             p^.location.registerhigh:=hregister2;
                           end
-                        else if cmpop then
-                          begin
-                             if (p^.right^.location.loc=LOC_CREGISTER) then
-                               begin
-                                  emit_reg_reg(A_CMP,S_L,p^.right^.location.registerhigh,
-                                     p^.location.registerhigh);
-                                  emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
-
-                                  emit_reg_reg(A_CMP,S_L,p^.right^.location.registerlow,
-                                     p^.location.registerlow);
-                                  emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
-
-                                  emitl(A_JMP,falselabel);
-                               end
-                             else
-                               begin
-                                  hr:=newreference(p^.right^.location.reference);
-                                  inc(hr^.offset,4);
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_CMP,S_L,
-                                    hr,p^.location.registerhigh)));
-                                  emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
-
-                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_CMP,S_L,newreference(
-                                    p^.right^.location.reference),p^.location.registerlow)));
-                                  emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+                        else
+                          { if on the right the register then swap }
+                          if not(noswap) and (p^.right^.location.loc=LOC_REGISTER) then
+                            begin
+                               swap_location(p^.location,p^.right^.location);
 
-                                  emitl(A_JMP,falselabel);
+                               { newly swapped also set swapped flag }
+                               p^.swaped:=not(p^.swaped);
+                            end;
+                        { at this point, p^.location.loc should be LOC_REGISTER }
+                        { and p^.location.register should be a valid register   }
+                        { containing the left result                            }
 
-                                  ungetiftemp(p^.right^.location.reference);
-                                  del_reference(p^.right^.location.reference);
-                               end;
-                          end
-                        else
+                         if p^.right^.location.loc<>LOC_REGISTER then
                           begin
-                             {
-                             if (p^.right^.treetype=ordconstn) and
-                                (op=A_CMP) and
-                                (p^.right^.value=0) then
+                             if (p^.treetype=subn) and p^.swaped then
                                begin
-                                  exprasmlist^.concat(new(pai386,op_reg_reg(A_TEST,opsize,p^.location.register,
-                                    p^.location.register)));
-                               end
-                             else if (p^.right^.treetype=ordconstn) and
-                                (op=A_IMUL) and
-                                (ispowerof2(p^.right^.value,power)) then
-                               begin
-                                  exprasmlist^.concat(new(pai386,op_const_reg(A_SHL,opsize,power,
-                                    p^.location.register)));
+                                  if p^.right^.location.loc=LOC_CREGISTER then
+                                    begin
+                                       emit_reg_reg(A_MOV,opsize,p^.right^.location.register,R_EDI);
+                                       emit_reg_reg(op,opsize,p^.location.register,R_EDI);
+                                       emit_reg_reg(A_MOV,opsize,R_EDI,p^.location.register);
+                                    end
+                                  else
+                                    begin
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
+                                         newreference(p^.right^.location.reference),R_EDI)));
+                                       exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,p^.location.register,R_EDI)));
+                                       exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,opsize,R_EDI,p^.location.register)));
+                                       ungetiftemp(p^.right^.location.reference);
+                                       del_reference(p^.right^.location.reference);
+                                    end;
                                end
-                             else
-                             }
+                             else if cmpop then
                                begin
                                   if (p^.right^.location.loc=LOC_CREGISTER) then
                                     begin
-                                       emit_reg_reg(op,S_L,p^.right^.location.registerlow,
-                                          p^.location.registerlow);
-                                       emit_reg_reg(op2,S_L,p^.right^.location.registerhigh,
+                                       emit_reg_reg(A_CMP,S_L,p^.right^.location.registerhigh,
                                           p^.location.registerhigh);
+                                       emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+
+                                       emit_reg_reg(A_CMP,S_L,p^.right^.location.registerlow,
+                                          p^.location.registerlow);
+                                       emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+
+                                       emitl(A_JMP,falselabel);
                                     end
                                   else
                                     begin
-                                       exprasmlist^.concat(new(pai386,op_ref_reg(op,S_L,newreference(
-                                         p^.right^.location.reference),p^.location.registerlow)));
                                        hr:=newreference(p^.right^.location.reference);
                                        inc(hr^.offset,4);
-                                       exprasmlist^.concat(new(pai386,op_ref_reg(op2,S_L,
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_CMP,S_L,
                                          hr,p^.location.registerhigh)));
+                                       emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_CMP,S_L,newreference(
+                                         p^.right^.location.reference),p^.location.registerlow)));
+                                       emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+
+                                       emitl(A_JMP,falselabel);
+
                                        ungetiftemp(p^.right^.location.reference);
                                        del_reference(p^.right^.location.reference);
                                     end;
+                               end
+                             else
+                               begin
+                                  {
+                                  if (p^.right^.treetype=ordconstn) and
+                                     (op=A_CMP) and
+                                     (p^.right^.value=0) then
+                                    begin
+                                       exprasmlist^.concat(new(pai386,op_reg_reg(A_TEST,opsize,p^.location.register,
+                                         p^.location.register)));
+                                    end
+                                  else if (p^.right^.treetype=ordconstn) and
+                                     (op=A_IMUL) and
+                                     (ispowerof2(p^.right^.value,power)) then
+                                    begin
+                                       exprasmlist^.concat(new(pai386,op_const_reg(A_SHL,opsize,power,
+                                         p^.location.register)));
+                                    end
+                                  else
+                                  }
+                                    begin
+                                       if (p^.right^.location.loc=LOC_CREGISTER) then
+                                         begin
+                                            emit_reg_reg(op,S_L,p^.right^.location.registerlow,
+                                               p^.location.registerlow);
+                                            emit_reg_reg(op2,S_L,p^.right^.location.registerhigh,
+                                               p^.location.registerhigh);
+                                         end
+                                       else
+                                         begin
+                                            exprasmlist^.concat(new(pai386,op_ref_reg(op,S_L,newreference(
+                                              p^.right^.location.reference),p^.location.registerlow)));
+                                            hr:=newreference(p^.right^.location.reference);
+                                            inc(hr^.offset,4);
+                                            exprasmlist^.concat(new(pai386,op_ref_reg(op2,S_L,
+                                              hr,p^.location.registerhigh)));
+                                            ungetiftemp(p^.right^.location.reference);
+                                            del_reference(p^.right^.location.reference);
+                                         end;
+                                    end;
                                end;
-                          end;
-                     end
-                   else
-                     begin
-                        { when swapped another result register }
-                        if (p^.treetype=subn) and p^.swaped then
-                          begin
-                             exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,
-                               p^.location.register,p^.right^.location.register)));
-                               swap_location(p^.location,p^.right^.location);
-                               { newly swapped also set swapped flag }
-                               { just to maintain ordering           }
-                               p^.swaped:=not(p^.swaped);
-                          end
-                        else if cmpop then
-                          begin
-                             exprasmlist^.concat(new(pai386,op_reg_reg(A_CMP,S_L,
-                               p^.right^.location.registerhigh,
-                               p^.location.registerhigh)));
-                             emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
-                             exprasmlist^.concat(new(pai386,op_reg_reg(A_CMP,S_L,
-                               p^.right^.location.registerlow,
-                               p^.location.registerlow)));
-                             emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
-                             emitl(A_JMP,falselabel);
                           end
                         else
                           begin
-                             exprasmlist^.concat(new(pai386,op_reg_reg(op,S_L,
-                               p^.right^.location.registerlow,
-                               p^.location.registerlow)));
-                             exprasmlist^.concat(new(pai386,op_reg_reg(op2,S_L,
-                               p^.right^.location.registerhigh,
-                               p^.location.registerhigh)));
+                             { when swapped another result register }
+                             if (p^.treetype=subn) and p^.swaped then
+                               begin
+                                  exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,
+                                    p^.location.register,p^.right^.location.register)));
+                                    swap_location(p^.location,p^.right^.location);
+                                    { newly swapped also set swapped flag }
+                                    { just to maintain ordering           }
+                                    p^.swaped:=not(p^.swaped);
+                               end
+                             else if cmpop then
+                               begin
+                                  exprasmlist^.concat(new(pai386,op_reg_reg(A_CMP,S_L,
+                                    p^.right^.location.registerhigh,
+                                    p^.location.registerhigh)));
+                                  emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+                                  exprasmlist^.concat(new(pai386,op_reg_reg(A_CMP,S_L,
+                                    p^.right^.location.registerlow,
+                                    p^.location.registerlow)));
+                                  emitl(flag_2_jmp[getresflags(p,unsigned)],truelabel);
+                                  emitl(A_JMP,falselabel);
+                               end
+                             else
+                               begin
+                                  exprasmlist^.concat(new(pai386,op_reg_reg(op,S_L,
+                                    p^.right^.location.registerlow,
+                                    p^.location.registerlow)));
+                                  exprasmlist^.concat(new(pai386,op_reg_reg(op2,S_L,
+                                    p^.right^.location.registerhigh,
+                                    p^.location.registerhigh)));
+                               end;
+                             ungetregister32(p^.right^.location.registerlow);
+                             ungetregister32(p^.right^.location.registerhigh);
                           end;
-                        ungetregister32(p^.right^.location.registerlow);
-                        ungetregister32(p^.right^.location.registerhigh);
-                     end;
 
-                   if cmpop then
-                     begin
-                        ungetregister32(p^.location.registerlow);
-                        ungetregister32(p^.location.registerhigh);
-                     end;
+                        if cmpop then
+                          begin
+                             ungetregister32(p^.location.registerlow);
+                             ungetregister32(p^.location.registerhigh);
+                          end;
 
-                   { only in case of overflow operations }
-                   { produce overflow code }
-                   { we must put it here directly, because sign of operation }
-                   { is in unsigned VAR!!                                    }
-                   if mboverflow then
-                    begin
-                      if cs_check_overflow in aktlocalswitches  then
-                       begin
-                         getlabel(hl4);
-                         if unsigned then
-                          emitl(A_JNB,hl4)
-                         else
-                          emitl(A_JNO,hl4);
-                         emitcall('FPC_OVERFLOW',true);
-                         emitl(A_LABEL,hl4);
-                       end;
-                    end;
-                   { we have LOC_JUMP as result }
-                   if cmpop then
-                     begin
-                        clear_location(p^.location);
-                        p^.location.loc:=LOC_JUMP;
-                        cmpop:=false;
+                        { only in case of overflow operations }
+                        { produce overflow code }
+                        { we must put it here directly, because sign of operation }
+                        { is in unsigned VAR!!                                    }
+                        if mboverflow then
+                         begin
+                           if cs_check_overflow in aktlocalswitches  then
+                            begin
+                              getlabel(hl4);
+                              if unsigned then
+                               emitl(A_JNB,hl4)
+                              else
+                               emitl(A_JNO,hl4);
+                              emitcall('FPC_OVERFLOW',true);
+                              emitl(A_LABEL,hl4);
+                            end;
+                         end;
+                        { we have LOC_JUMP as result }
+                        if cmpop then
+                          begin
+                             clear_location(p^.location);
+                             p^.location.loc:=LOC_JUMP;
+                             cmpop:=false;
+                          end;
                      end;
                 end
               else
@@ -1697,7 +1733,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.35  1998-12-11 23:36:06  florian
+  Revision 1.36  1998-12-19 00:23:40  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.35  1998/12/11 23:36:06  florian
     + again more stuff for int64/qword:
          - comparision operators
          - code generation for: str, read(ln), write(ln)

+ 45 - 4
compiler/cg386cal.pas

@@ -177,6 +177,7 @@ implementation
          opsize : topsize;
          op     : tasmop;
          hreg   : tregister;
+
       begin
          { push from left to right if specified }
          if push_from_left_to_right and assigned(p^.right) then
@@ -736,7 +737,7 @@ implementation
     procedure secondcalln(var p : ptree);
       var
          unusedregisters : tregisterset;
-         pushed : tpushed;
+         pushed,pushedregs : tpushed;
          hr,funcretref : treference;
          hregister,hregister2 : tregister;
          oldpushedparasize : longint;
@@ -764,6 +765,7 @@ implementation
          { we must pop this size also after !! }
 {         must_pop : boolean; }
          pop_size : longint;
+         oldrl : plinkedlist;
 
       label
          dont_call;
@@ -777,6 +779,10 @@ implementation
          no_virtual_call:=false;
          unusedregisters:=unused;
 
+         { save old ansi string release list }
+         oldrl:=temptoremove;
+         temptoremove:=new(plinkedlist,init);
+
          if not assigned(p^.procdefinition) then
           exit;
          if (p^.procdefinition^.options and poinline)<>0 then
@@ -1331,7 +1337,10 @@ implementation
               stringdispose(p^.location.reference.symbol);
               p^.location.reference:=funcretref;
            end;
-         if (p^.resulttype<>pdef(voiddef)) and p^.return_value_used then
+         { we have only to handle the result if it is used, but        }
+         { ansi/widestrings must be registered, so we can dispose them }
+         if (p^.resulttype<>pdef(voiddef)) and (p^.return_value_used or
+           is_ansistring(p^.resulttype) or is_widestring(p^.resulttype)) then
            begin
               { a contructor could be a function with boolean result }
               if (p^.right=nil) and
@@ -1459,9 +1468,32 @@ implementation
                          is_widestring(p^.resulttype) then
                          begin
                             gettempansistringreference(hr);
-                            {temptoremove^.concat(new(ptemptodestroy,init(hr,p^.resulttype)));}
                             exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,p^.location.register,
                               newreference(hr))));
+                            { unnessary ansi/wide strings are imm. disposed }
+                            if not(p^.return_value_used) then
+                              begin
+                                 pushusedregisters(pushedregs,$ff);
+                                 emitpushreferenceaddr(exprasmlist,hr);
+                                 if is_ansistring(p^.resulttype) then
+                                   begin
+                                      exprasmlist^.concat(new(pai386,
+                                        op_csymbol(A_CALL,S_NO,newcsymbol('FPC_ANSISTR_DECR_REF',0))));
+                                      if not (cs_compilesystem in aktmoduleswitches) then
+                                      concat_external('FPC_ANSISTR_DECR_REF',EXT_NEAR);
+                                   end
+                                 else
+                                   begin
+                                      exprasmlist^.concat(new(pai386,
+                                        op_csymbol(A_CALL,S_NO,newcsymbol('FPC_WIDESTR_DECR_REF',0))));
+                                      if not (cs_compilesystem in aktmoduleswitches) then
+                                      concat_external('FPC_WIDESTR_DECR_REF',EXT_NEAR);
+                                   end;
+
+                                 popusedregisters(pushedregs);
+                              end
+                            else
+                              oldrl^.concat(new(ptemptodestroy,init(hr,p^.resulttype)));
                          end;
                     end;
                 end;
@@ -1476,6 +1508,12 @@ implementation
            end;
          if pop_size>0 then
            exprasmlist^.concat(new(pai386,op_const_reg(A_ADD,S_L,pop_size,R_ESP)));
+
+         { release temp. ansi strings }
+         removetemps(exprasmlist,temptoremove);
+         dispose(temptoremove,done);
+         temptoremove:=oldrl;
+
          { restore registers }
          popusedregisters(pushed);
 
@@ -1627,7 +1665,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.53  1998-12-11 00:02:47  peter
+  Revision 1.54  1998-12-19 00:23:41  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.53  1998/12/11 00:02:47  peter
     + globtype,tokens,version unit splitted from globals
 
   Revision 1.52  1998/12/10 14:39:29  florian

+ 32 - 21
compiler/cg386cnv.pas

@@ -475,9 +475,15 @@ implementation
 
 {$endif}
 
+    var
+       ltemptoremove : plinkedlist;
+       destroys : boolean;
+
     procedure second_string_to_string(pto,pfrom : ptree;convtyp : tconverttype);
+
       var
          pushed : tpushed;
+
       begin
          { does anybody know a better solution than this big case statement ? }
          { ok, a proc table would do the job                                  }
@@ -488,11 +494,7 @@ implementation
                  st_shortstring:
                    begin
                       stringdispose(pto^.location.reference.symbol);
-{$ifdef TempAnsi}
-                      gettempansistringreference(pto^.location.reference);
-{$else : not TempAnsi}
                       gettempofsizereference(pto^.resulttype^.size,pto^.location.reference);
-{$endif : not TempAnsi}
                       del_reference(pfrom^.location.reference);
                       copyshortstring(pto^.location.reference,pfrom^.location.reference,
                         pstringdef(pto^.resulttype)^.len,false);
@@ -505,14 +507,10 @@ implementation
                    end;
                  st_ansistring:
                    begin
-{$ifdef TempAnsi}
-                      clear_reference(pto^.location.reference);
-                      gettempansistringreference(pto^.location.reference);
-                      loadansi2short(pfrom,pto);
-{$else : not TempAnsi}
                       gettempofsizereference(pto^.resulttype^.size,pto^.location.reference);
                       loadansi2short(pfrom,pto);
-{$endif : not TempAnsi}
+                      removetemps(exprasmlist,temptoremove);
+                      destroys:=true;
                    end;
                  st_widestring:
                    begin
@@ -547,11 +545,8 @@ implementation
                       clear_location(pto^.location);
                       pto^.location.loc:=LOC_REFERENCE;
                       clear_reference(pto^.location.reference);
-{$ifdef TempAnsi}
-                      gettempansistringreference(pto^.location.reference);
-{$else : not TempAnsi}
                       gettempofsizereference(pto^.resulttype^.size,pto^.location.reference);
-{$endif : not TempAnsi}
+                      temptoremove^.concat(new(ptemptodestroy,init(pto^.location.reference,pto^.resulttype)));
                       exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_L,0,newreference(pto^.location.reference))));
                       pushusedregisters(pushed,$ff);
                       emit_push_lea_loc(pfrom^.location);
@@ -559,6 +554,7 @@ implementation
                       emitcall('FPC_SHORTSTR_TO_ANSISTR',true);
                       maybe_loadesi;
                       popusedregisters(pushed);
+
                       ungetiftemp(pfrom^.location.reference);
                    end;
                  st_longstring:
@@ -749,12 +745,8 @@ implementation
              end;
            st_ansistring :
              begin
-{$ifdef TempAnsi}
-               gettempansistringreference(p^.location.reference);
-{$else not TempAnsi}
                gettempofsizereference(4,pto^.location.reference);
-{$endif not TempAnsi}
-               {temptoremove^.concat(new(ptemptodestroy,init(pto^.location.reference,pto^.resulttype)));}
+               temptoremove^.concat(new(ptemptodestroy,init(pto^.location.reference,pto^.resulttype)));
                exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_L,0,newreference(pto^.location.reference))));
                pushusedregisters(pushed,$ff);
                emit_pushw_loc(pfrom^.location);
@@ -1339,7 +1331,15 @@ implementation
            second_pchar_to_string,
            second_nothing);
 {$endif}
+      var
+         oldrl : plinkedlist;
+
       begin
+         { the ansi string disposing is a little bit hairy: }
+         destroys:=false;
+         oldrl:=temptoremove;
+         temptoremove:=new(plinkedlist,init);
+
          { this isn't good coding, I think tc_bool_2_int, shouldn't be }
          { type conversion (FK)                                        }
 
@@ -1352,8 +1352,16 @@ implementation
               if codegenerror then
                exit;
            end;
+         { the helper routines need access to the release list }
+         ltemptoremove:=temptoremove;
          {the second argument only is for maybe_range_checking !}
-         secondconvert[p^.convtyp](p,p^.left,p^.convtyp)
+         secondconvert[p^.convtyp](p,p^.left,p^.convtyp);
+
+         { are the temp. ansistrings been destroyed ? }
+         if not destroys then
+           oldrl^.concatlist(temptoremove);
+         dispose(temptoremove,done);
+         temptoremove:=oldrl;
       end;
 
 
@@ -1466,7 +1474,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.41  1998-11-30 19:48:54  peter
+  Revision 1.42  1998-12-19 00:23:42  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.41  1998/11/30 19:48:54  peter
     * some more rangecheck fixes
 
   Revision 1.40  1998/11/30 09:43:02  pierre

+ 4 - 11
compiler/cg386flw.pas

@@ -116,11 +116,8 @@ implementation
 
       var
          hl,otlabel,oflabel : plabel;
-         oldrl : plinkedlist;
 
       begin
-         oldrl:=temptoremove;
-         temptoremove:=new(plinkedlist,init);
          otlabel:=truelabel;
          oflabel:=falselabel;
          getlabel(truelabel);
@@ -131,7 +128,6 @@ implementation
          if assigned(p^.right) then
            begin
               emitl(A_LABEL,truelabel);
-              removetemps(exprasmlist,temptoremove);
               cleartempgen;
               secondpass(p^.right);
            end;
@@ -145,7 +141,6 @@ implementation
                    emitl(A_JMP,hl);
                 end;
               emitl(A_LABEL,falselabel);
-              removetemps(exprasmlist,temptoremove);
               cleartempgen;
               secondpass(p^.t1);
               if assigned(p^.right) then
@@ -154,20 +149,15 @@ implementation
          else
            begin
               emitl(A_LABEL,falselabel);
-              removetemps(exprasmlist,temptoremove);
            end;
          if not(assigned(p^.right)) then
            begin
               emitl(A_LABEL,truelabel);
-              removetemps(exprasmlist,temptoremove);
            end;
          freelabel(truelabel);
          freelabel(falselabel);
          truelabel:=otlabel;
          falselabel:=oflabel;
-         releasedata(temptoremove);
-         dispose(temptoremove,done);
-         temptoremove:=oldrl;
       end;
 
 
@@ -787,7 +777,10 @@ do_jmp:
 end.
 {
   $Log$
-  Revision 1.25  1998-11-30 09:43:03  pierre
+  Revision 1.26  1998-12-19 00:23:44  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.25  1998/11/30 09:43:03  pierre
     * some range check bugs fixed (still not working !)
     + added DLL writing support for win32 (also accepts variables)
     + TempAnsi for code that could be used for Temporary ansi strings

+ 11 - 1
compiler/cg386ld.pas

@@ -278,7 +278,11 @@ implementation
          hregister : tregister;
          loc : tloc;
          r : preference;
+         oldrl : plinkedlist;
+
       begin
+         oldrl:=temptoremove;
+         temptoremove:=new(plinkedlist,init);
          otlabel:=truelabel;
          oflabel:=falselabel;
          getlabel(truelabel);
@@ -551,6 +555,9 @@ implementation
                                   newreference(p^.left^.location.reference))));
                            end;
          end;
+         removetemps(exprasmlist,temptoremove);
+         dispose(temptoremove,done);
+         temptoremove:=oldrl;
          freelabel(truelabel);
          freelabel(falselabel);
          truelabel:=otlabel;
@@ -727,7 +734,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.38  1998-12-11 00:02:51  peter
+  Revision 1.39  1998-12-19 00:23:45  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.38  1998/12/11 00:02:51  peter
     + globtype,tokens,version unit splitted from globals
 
   Revision 1.37  1998/12/10 09:47:17  florian

+ 11 - 2
compiler/i386.pas

@@ -225,8 +225,14 @@ unit i386;
         differ from processor to processor.}
        accumulator = R_EAX;
 
-    type
+       firstregister = R_EAX;
+       lastregister = R_MM7;
+
+       general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
+
+       registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
 
+    type
        pai_labeled = ^tai_labeled;
 
        tai_labeled = object(tai)
@@ -1763,7 +1769,10 @@ unit i386;
 end.
 {
   $Log$
-  Revision 1.22  1998-12-18 17:24:51  peter
+  Revision 1.23  1998-12-19 00:23:49  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.22  1998/12/18 17:24:51  peter
     * don't include intel list if not necessary
 
   Revision 1.20  1998/12/11 16:10:09  florian

+ 6 - 2
compiler/pass_2.pas

@@ -81,6 +81,7 @@ implementation
 
 
     procedure secondstatement(var p : ptree);
+
       var
          hp : ptree;
          oldrl : plinkedlist;
@@ -95,8 +96,8 @@ implementation
                oldrl:=temptoremove;
                temptoremove:=new(plinkedlist,init);
                secondpass(hp^.right);
+               { release temp. ansi strings }
                removetemps(exprasmlist,temptoremove);
-               releasedata(temptoremove);
                dispose(temptoremove,done);
                temptoremove:=oldrl;
              end;
@@ -498,7 +499,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.11  1998-12-11 00:03:28  peter
+  Revision 1.12  1998-12-19 00:23:51  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.11  1998/12/11 00:03:28  peter
     + globtype,tokens,version unit splitted from globals
 
   Revision 1.10  1998/11/18 15:44:14  peter

+ 6 - 2
compiler/symdef.inc

@@ -27,6 +27,7 @@
     const
        { if you change one of the following contants, }
        { you have also to change the typinfo unit     }
+       { and the rtl/[i386,template/rttip.inc files   }
        tkUnknown       = 0;
        tkInteger       = 1;
        tkChar          = 2;
@@ -2291,7 +2292,7 @@
            dispose(parast,done);
          if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
            dispose(localst,done);
-         if assigned(code) and ((options and poinline) <> 0) then
+         if ((options and poinline) <> 0) and assigned(code) then
            disposetree(ptree(code));
          if
 {$ifdef tp}
@@ -3259,7 +3260,10 @@
 
 {
   $Log$
-  Revision 1.81  1998-12-11 08:57:22  pierre
+  Revision 1.82  1998-12-19 00:23:52  florian
+    * ansistring memory leaks fixed
+
+  Revision 1.81  1998/12/11 08:57:22  pierre
    * internal gdb types for booleans and 64bit integers
 
   Revision 1.80  1998/12/10 09:47:26  florian