mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 09:19:39 +01:00 
			
		
		
		
	* changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
* in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck") * in cgai386: also small fixes to emitrangecheck
This commit is contained in:
		
							parent
							
								
									228829bd86
								
							
						
					
					
						commit
						1e6d667c3b
					
				@ -338,25 +338,91 @@ implementation
 | 
			
		||||
                                       emitcall('FPC_WRITE_TEXT_'+float_name[pfloatdef(pararesult)^.typ],true);
 | 
			
		||||
                                   end;
 | 
			
		||||
                          orddef : begin
 | 
			
		||||
 {in the range checking code, hp^.left is stil the current parameter, since
 | 
			
		||||
  hp only gets modified when doread is false (JM)}
 | 
			
		||||
                                     case porddef(pararesult)^.typ of
 | 
			
		||||
                                          u8bit : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_BYTE',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                      emitcall('FPC_READ_TEXT_BYTE',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      If (porddef(pararesult)^.low <> 0) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> 255) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End;
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
 | 
			
		||||
                                          s8bit : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_SHORTINT',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                      emitcall('FPC_READ_TEXT_SHORTINT',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      If (porddef(pararesult)^.low <> -128) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> 127) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End;
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                         u16bit : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_WORD',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                      emitcall('FPC_READ_TEXT_WORD',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      If (porddef(pararesult)^.low <> 0) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> 65535) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End;
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                         s16bit : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_INTEGER',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                      emitcall('FPC_READ_TEXT_INTEGER',true);
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      If (porddef(pararesult)^.low <> -32768) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> 32767) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End;
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                         s32bit : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_LONGINT',true)
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                      emitcall('FPC_READ_TEXT_LONGINT',true)
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      ;If (porddef(pararesult)^.low <> $80000000) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> $7fffffff) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                  else
 | 
			
		||||
                                                    emitcall('FPC_WRITE_TEXT_LONGINT',true);
 | 
			
		||||
                                         u32bit : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_CARDINAL',true)
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                      emitcall('FPC_READ_TEXT_CARDINAL',true)
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      ;If (porddef(pararesult)^.low <> $0) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> $ffffffff) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                  else
 | 
			
		||||
                                                    emitcall('FPC_WRITE_TEXT_CARDINAL',true);
 | 
			
		||||
                                          uchar : if doread then
 | 
			
		||||
                                                    emitcall('FPC_READ_TEXT_CHAR',true)
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                    Begin
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                        emitcall('FPC_READ_TEXT_CHAR',true)
 | 
			
		||||
{$IfDef ReadRangeCheck}
 | 
			
		||||
                                                      ;If (porddef(pararesult)^.low <> 0) or
 | 
			
		||||
                                                         (porddef(pararesult)^.high <> 255) Then
 | 
			
		||||
                                                        emitrangecheck(hp^.left,pararesult);
 | 
			
		||||
                                                    End
 | 
			
		||||
{$EndIf ReadRangeCheck}
 | 
			
		||||
                                                  else
 | 
			
		||||
                                                    emitcall('FPC_WRITE_TEXT_CHAR',true);
 | 
			
		||||
                                         s64bitint:
 | 
			
		||||
@ -535,7 +601,7 @@ implementation
 | 
			
		||||
             exit;
 | 
			
		||||
 | 
			
		||||
           if is_real then
 | 
			
		||||
             emitcall(procedureprefix++float_name[pfloatdef(hp^.resulttype)^.typ],true)
 | 
			
		||||
             emitcall(procedureprefix+float_name[pfloatdef(hp^.resulttype)^.typ],true)
 | 
			
		||||
           else
 | 
			
		||||
             case porddef(hp^.resulttype)^.typ of
 | 
			
		||||
                u32bit:
 | 
			
		||||
@ -553,6 +619,216 @@ implementation
 | 
			
		||||
           popusedregisters(pushed);
 | 
			
		||||
        end;
 | 
			
		||||
 | 
			
		||||
{$IfDef ValIntern}
 | 
			
		||||
 | 
			
		||||
        Procedure Handle_Val;
 | 
			
		||||
 | 
			
		||||
        var
 | 
			
		||||
           hp,node, code_para, dest_para : ptree;
 | 
			
		||||
           hreg: TRegister;
 | 
			
		||||
           hdef: POrdDef;
 | 
			
		||||
           pushed2: TPushed;
 | 
			
		||||
           procedureprefix : string;
 | 
			
		||||
           hr: TReference;
 | 
			
		||||
           dummycoll : tdefcoll;
 | 
			
		||||
           has_code, has_32bit_code, oldregisterdef: boolean;
 | 
			
		||||
 | 
			
		||||
          begin
 | 
			
		||||
          {save the register variables}
 | 
			
		||||
           pushusedregisters(pushed,$ff);
 | 
			
		||||
           node:=p^.left;
 | 
			
		||||
           hp:=node;
 | 
			
		||||
           node:=node^.right;
 | 
			
		||||
           hp^.right:=nil;
 | 
			
		||||
           has_32bit_code := false;
 | 
			
		||||
          {if we have 3 parameters, we have a code parameter}
 | 
			
		||||
           has_code := Assigned(node^.right);
 | 
			
		||||
           reset_reference(hr);
 | 
			
		||||
           hreg := R_NO;
 | 
			
		||||
 | 
			
		||||
          {the function result will be in EAX, so we need to reserve it so
 | 
			
		||||
           that secondpass(dest_para^.left) and secondpass(code_para^.left)
 | 
			
		||||
           won't use it}
 | 
			
		||||
           hreg := getexplicitregister32(R_EAX);
 | 
			
		||||
          {if EAX is already in use, it's a register variable (ok, we've saved
 | 
			
		||||
           those with pushusedregisters). Since we don't need another
 | 
			
		||||
           register besides EAX, release it}
 | 
			
		||||
           If hreg <> R_EAX Then ungetregister32(hreg);
 | 
			
		||||
 | 
			
		||||
           If has_code then
 | 
			
		||||
             Begin
 | 
			
		||||
               {code is an orddef, that's checked in tcinl}
 | 
			
		||||
               If (porddef(hp^.left^.resulttype)^.typ in [u32bit,s32bit]) Then
 | 
			
		||||
                 Begin
 | 
			
		||||
                   has_32bit_code := true;
 | 
			
		||||
                   code_para := hp;
 | 
			
		||||
                   hp:=node;
 | 
			
		||||
                   node:=node^.right;
 | 
			
		||||
                   hp^.right:=nil;
 | 
			
		||||
                 End
 | 
			
		||||
               Else
 | 
			
		||||
                 Begin
 | 
			
		||||
                   secondpass(hp^.left);
 | 
			
		||||
                   code_para := hp;
 | 
			
		||||
                   hp := node;
 | 
			
		||||
                   node:=node^.right;
 | 
			
		||||
                   hp^.right:=nil;
 | 
			
		||||
                 End;
 | 
			
		||||
             End;
 | 
			
		||||
           {hp = destination now, save for later use}
 | 
			
		||||
           dest_para := hp;
 | 
			
		||||
           secondpass(dest_para^.left);
 | 
			
		||||
 | 
			
		||||
          {unget EAX (if we got it before), since otherwise pushusedregisters
 | 
			
		||||
           will push it on the stack. No more registers are allocated before
 | 
			
		||||
           the function call that will also have to be accessed afterwards,
 | 
			
		||||
           so if EAX is allocated now before the function call, it doesn't
 | 
			
		||||
           matter.}
 | 
			
		||||
           If (hreg = R_EAX) then Ungetregister32(R_EAX);
 | 
			
		||||
 | 
			
		||||
          {(if necessary) save the address loading of code_para and dest_para}
 | 
			
		||||
 | 
			
		||||
           pushusedregisters(pushed2,$ff);
 | 
			
		||||
 | 
			
		||||
          {now that we've already pushed the results from
 | 
			
		||||
           secondpass(code_para^.left) and secondpass(dest_para^.left) on the
 | 
			
		||||
           stack, we can put the real parameters on the stack}
 | 
			
		||||
 | 
			
		||||
           If has_32bit_code Then
 | 
			
		||||
             Begin
 | 
			
		||||
               dummycoll.paratyp:=vs_var;
 | 
			
		||||
               dummycoll.data:=code_para^.resulttype;
 | 
			
		||||
               secondcallparan(code_para,@dummycoll,false,false,0);
 | 
			
		||||
               if codegenerror then
 | 
			
		||||
                 exit;
 | 
			
		||||
               Disposetree(code_para);
 | 
			
		||||
             End
 | 
			
		||||
           Else
 | 
			
		||||
             Begin
 | 
			
		||||
           {only 32bit code parameter is supported, so fake one}
 | 
			
		||||
               GetTempOfSizeReference(4,hr);
 | 
			
		||||
               emitpushreferenceaddr(exprasmlist,hr);
 | 
			
		||||
             End;
 | 
			
		||||
 | 
			
		||||
           Case dest_para^.resulttype^.deftype of
 | 
			
		||||
             floatdef: procedureprefix := 'FPC_VAL_REAL_';
 | 
			
		||||
             orddef:
 | 
			
		||||
               Case PordDef(dest_para^.resulttype)^.typ of
 | 
			
		||||
                 u8bit,u16bit,u32bit{,u64bit}: procedureprefix := 'FPC_VAL_UINT_';
 | 
			
		||||
                 s8bit,s16bit,s32bit{,s64bitint}: procedureprefix := 'FPC_VAL_SINT_';
 | 
			
		||||
               End;
 | 
			
		||||
           End;
 | 
			
		||||
 | 
			
		||||
          {node = first parameter = string}
 | 
			
		||||
           dummycoll.paratyp:=vs_const;
 | 
			
		||||
           dummycoll.data:=node^.resulttype;
 | 
			
		||||
           secondcallparan(node,@dummycoll,false,false,0);
 | 
			
		||||
           if codegenerror then
 | 
			
		||||
             exit;
 | 
			
		||||
 | 
			
		||||
           {if we are converting to a signed number, we have to include the
 | 
			
		||||
            size of the destination, so the Val function can extend the sign
 | 
			
		||||
            of the result to allow proper range checking}
 | 
			
		||||
           If (dest_para^.resulttype^.deftype = orddef) Then
 | 
			
		||||
              Case PordDef(dest_para^.resulttype)^.typ of
 | 
			
		||||
                s8bit: exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,1)));
 | 
			
		||||
                s16bit: exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,2)));
 | 
			
		||||
                s32bit: exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,4)));
 | 
			
		||||
              End;
 | 
			
		||||
 | 
			
		||||
           case pstringdef(node^.resulttype)^.string_typ of
 | 
			
		||||
              st_widestring:
 | 
			
		||||
                emitcall(procedureprefix+'STRWIDE',true);
 | 
			
		||||
              st_ansistring:
 | 
			
		||||
                emitcall(procedureprefix+'STRANSI',true);
 | 
			
		||||
              st_shortstring:
 | 
			
		||||
                emitcall(procedureprefix+'SSTRING',true);
 | 
			
		||||
              st_longstring:
 | 
			
		||||
                emitcall(procedureprefix+'STRLONG',true);
 | 
			
		||||
           end;
 | 
			
		||||
           disposetree(node);
 | 
			
		||||
           p^.left := nil;
 | 
			
		||||
 | 
			
		||||
          {restore the addresses loaded by secondpass}
 | 
			
		||||
           popusedregisters(pushed2);
 | 
			
		||||
          {reload esi in case the dest_para/code_para is a class variable or so}
 | 
			
		||||
           maybe_loadesi;
 | 
			
		||||
 | 
			
		||||
           If has_code and Not(has_32bit_code) Then
 | 
			
		||||
             {only 16bit code is possible}
 | 
			
		||||
             Begin
 | 
			
		||||
               exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,NewReference(hr),R_EDI)));
 | 
			
		||||
               emit_mov_reg_loc(R_DI,code_para^.left^.location);
 | 
			
		||||
               Disposetree(code_para);
 | 
			
		||||
             End;
 | 
			
		||||
 | 
			
		||||
          {save the function result in the destinatin variable}
 | 
			
		||||
           Case dest_para^.left^.resulttype^.deftype of
 | 
			
		||||
             floatdef: floatstore(PFloatDef(dest_para^.left^.resulttype)^.typ,
 | 
			
		||||
                                   dest_para^.left^.location.reference);
 | 
			
		||||
             orddef:
 | 
			
		||||
               Case PordDef(dest_para^.left^.resulttype)^.typ of
 | 
			
		||||
                 u8bit,s8bit:
 | 
			
		||||
                   emit_mov_reg_loc(R_AL,dest_para^.left^.location);
 | 
			
		||||
                 u16bit,s16bit:
 | 
			
		||||
                   emit_mov_reg_loc(R_AX,dest_para^.left^.location);
 | 
			
		||||
                 u32bit,s32bit:
 | 
			
		||||
                   emit_mov_reg_loc(R_EAX,dest_para^.left^.location);
 | 
			
		||||
                 {u64bit,s64bitint: ???}
 | 
			
		||||
               End;
 | 
			
		||||
           End;
 | 
			
		||||
           If (cs_check_range in aktlocalswitches) and
 | 
			
		||||
              (dest_para^.left^.resulttype^.deftype = orddef) and
 | 
			
		||||
            {the following has to be changed to 64bit checking, once Val
 | 
			
		||||
             returns 64 bit values (unless a special Val function is created
 | 
			
		||||
             for that}
 | 
			
		||||
            {no need to rangecheck longints or cardinals on 32bit processors}
 | 
			
		||||
               not((porddef(dest_para^.left^.resulttype)^.typ = s32bit) and
 | 
			
		||||
                   (porddef(dest_para^.left^.resulttype)^.low = $80000000) and
 | 
			
		||||
                   (porddef(dest_para^.left^.resulttype)^.high = $7fffffff)) and
 | 
			
		||||
               not((porddef(dest_para^.left^.resulttype)^.typ = u32bit) and
 | 
			
		||||
                   (porddef(dest_para^.left^.resulttype)^.low = 0) and
 | 
			
		||||
                   (porddef(dest_para^.left^.resulttype)^.high = $ffffffff)) then
 | 
			
		||||
             Begin
 | 
			
		||||
               If has_32bit_code then
 | 
			
		||||
               {we don't have temporary variable space yet}
 | 
			
		||||
                 GetTempOfSizeReference(4,hr);
 | 
			
		||||
              {save the result in a temp variable, because EAX may be
 | 
			
		||||
               overwritten by popusedregs()}
 | 
			
		||||
               exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EAX,NewReference(hr))));
 | 
			
		||||
              {clean up the stack, so a backtrace is possible if range check
 | 
			
		||||
               fails}
 | 
			
		||||
               popusedregisters(pushed);
 | 
			
		||||
              {create a temporary 32bit location for the returned value}
 | 
			
		||||
               hp := getcopy(dest_para^.left);
 | 
			
		||||
               hp^.location.loc := LOC_REFERENCE;
 | 
			
		||||
               hp^.location.reference := hr;
 | 
			
		||||
              {do not register this temporary def}
 | 
			
		||||
               OldRegisterDef := RegisterDef;
 | 
			
		||||
               RegisterDef := False;
 | 
			
		||||
               Case PordDef(dest_para^.left^.resulttype)^.typ of
 | 
			
		||||
                 u8bit,u16bit,u32bit: new(hdef,init(u32bit,0,$fffffff));
 | 
			
		||||
                 s8bit,s16bit,s32bit: new(hdef,init(s32bit,$fffffff,$7ffffff));
 | 
			
		||||
               end;
 | 
			
		||||
               hp^.resulttype := hdef;
 | 
			
		||||
               emitrangecheck(hp,dest_para^.left^.resulttype);
 | 
			
		||||
               hp^.right := nil;
 | 
			
		||||
               Dispose(hp^.resulttype, Done);
 | 
			
		||||
               RegisterDef := OldRegisterDef;
 | 
			
		||||
               disposetree(hp);
 | 
			
		||||
              {it's possible that the range cheking was handled by a
 | 
			
		||||
               procedure that has destroyed ESI}
 | 
			
		||||
               maybe_loadesi;
 | 
			
		||||
             End
 | 
			
		||||
           Else
 | 
			
		||||
            {clean up the stack}
 | 
			
		||||
             popusedregisters(pushed);
 | 
			
		||||
          {dest_para^right is already nil}
 | 
			
		||||
           disposetree(dest_para);
 | 
			
		||||
           UnGetIfTemp(hr);
 | 
			
		||||
        end;
 | 
			
		||||
{$EndIf ValIntern}
 | 
			
		||||
 | 
			
		||||
      var
 | 
			
		||||
         r : preference;
 | 
			
		||||
         hp : ptree;
 | 
			
		||||
@ -943,6 +1219,12 @@ implementation
 | 
			
		||||
                 handle_str;
 | 
			
		||||
                 maybe_loadesi;
 | 
			
		||||
              end;
 | 
			
		||||
{$IfDef ValIntern}
 | 
			
		||||
            in_val_x :
 | 
			
		||||
              Begin
 | 
			
		||||
                handle_val;
 | 
			
		||||
              End;
 | 
			
		||||
{$EndIf ValIntern}
 | 
			
		||||
            in_include_x_y,
 | 
			
		||||
            in_exclude_x_y:
 | 
			
		||||
              begin
 | 
			
		||||
@ -1027,7 +1309,12 @@ implementation
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.29  1999-02-25 21:02:27  peter
 | 
			
		||||
  Revision 1.30  1999-03-16 17:52:56  jonas
 | 
			
		||||
    * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
 | 
			
		||||
    * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
 | 
			
		||||
    * in cgai386: also small fixes to emitrangecheck
 | 
			
		||||
 | 
			
		||||
  Revision 1.29  1999/02/25 21:02:27  peter
 | 
			
		||||
    * ag386bin updates
 | 
			
		||||
    + coff writer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -417,6 +417,29 @@ unit pexpr;
 | 
			
		||||
              pd:=voiddef;
 | 
			
		||||
            end;
 | 
			
		||||
 | 
			
		||||
{$IfDef ValIntern}
 | 
			
		||||
          in_val_x:
 | 
			
		||||
            Begin
 | 
			
		||||
              consume(LKLAMMER);
 | 
			
		||||
              in_args := true;
 | 
			
		||||
              p1:= gencallparanode(comp_expr(true), nil);
 | 
			
		||||
              Must_be_valid := False;
 | 
			
		||||
              consume(COMMA);
 | 
			
		||||
              p2 := gencallparanode(comp_expr(true),p1);
 | 
			
		||||
              if (token = COMMA) then
 | 
			
		||||
                Begin
 | 
			
		||||
                  consume(COMMA);
 | 
			
		||||
                  p2 := gencallparanode(comp_expr(true),p2)
 | 
			
		||||
                End;
 | 
			
		||||
              consume(RKLAMMER);
 | 
			
		||||
              p2 := geninlinenode(l,false,p2);
 | 
			
		||||
              do_firstpass(p2);
 | 
			
		||||
              statement_syssym := p2;
 | 
			
		||||
              pd := voiddef;
 | 
			
		||||
            End;
 | 
			
		||||
{$EndIf ValIntern}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
          in_include_x_y,
 | 
			
		||||
          in_exclude_x_y :
 | 
			
		||||
            begin
 | 
			
		||||
@ -1936,7 +1959,12 @@ unit pexpr;
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.86  1999-03-04 13:55:44  pierre
 | 
			
		||||
  Revision 1.87  1999-03-16 17:52:52  jonas
 | 
			
		||||
    * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
 | 
			
		||||
    * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
 | 
			
		||||
    * in cgai386: also small fixes to emitrangecheck
 | 
			
		||||
 | 
			
		||||
  Revision 1.86  1999/03/04 13:55:44  pierre
 | 
			
		||||
    * some m68k fixes (still not compilable !)
 | 
			
		||||
    * new(tobj) does not give warning if tobj has no VMT !
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,9 @@ begin
 | 
			
		||||
  p^.insert(new(psyssym,init('INC',in_inc_x)));
 | 
			
		||||
  p^.insert(new(psyssym,init('STR',in_str_x_string)));
 | 
			
		||||
  p^.insert(new(psyssym,init('ASSERT',in_assert_x_y)));
 | 
			
		||||
{$IfDef ValIntern}
 | 
			
		||||
  p^.insert(new(psyssym,init('VAL',in_val_x)));
 | 
			
		||||
{$EndIf ValIntern}
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -253,7 +256,12 @@ end;
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.16  1999-03-02 02:56:17  peter
 | 
			
		||||
  Revision 1.17  1999-03-16 17:52:54  jonas
 | 
			
		||||
    * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
 | 
			
		||||
    * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
 | 
			
		||||
    * in cgai386: also small fixes to emitrangecheck
 | 
			
		||||
 | 
			
		||||
  Revision 1.16  1999/03/02 02:56:17  peter
 | 
			
		||||
    + stabs support for binary writers
 | 
			
		||||
    * more fixes and missing updates from the previous commit :(
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -106,6 +106,9 @@ implementation
 | 
			
		||||
         count_ref:=false;
 | 
			
		||||
         if not (p^.inlinenumber in [in_read_x,in_readln_x,in_sizeof_x,
 | 
			
		||||
            in_typeof_x,in_ord_x,in_str_x_string,
 | 
			
		||||
{$IfDef ValIntern}
 | 
			
		||||
            in_val_x,
 | 
			
		||||
{$EndIf ValIntern}
 | 
			
		||||
            in_reset_typedfile,in_rewrite_typedfile]) then
 | 
			
		||||
           must_be_valid:=true
 | 
			
		||||
         else
 | 
			
		||||
@ -807,6 +810,73 @@ implementation
 | 
			
		||||
                  { calc registers }
 | 
			
		||||
                  left_right_max(p);
 | 
			
		||||
               end;
 | 
			
		||||
{$IfDef ValIntern}
 | 
			
		||||
 | 
			
		||||
             in_val_x :
 | 
			
		||||
               begin
 | 
			
		||||
                  procinfo.flags:=procinfo.flags or pi_do_call;
 | 
			
		||||
                  p^.resulttype:=voiddef;
 | 
			
		||||
                  { check the amount of parameters }
 | 
			
		||||
                  if not(assigned(p^.left)) or
 | 
			
		||||
                     not(assigned(p^.left^.right)) then
 | 
			
		||||
                   begin
 | 
			
		||||
                     CGMessage(parser_e_wrong_parameter_size);
 | 
			
		||||
                     exit;
 | 
			
		||||
                   end;
 | 
			
		||||
                  If Assigned(p^.left^.right^.right) Then
 | 
			
		||||
                   {there is a "code" parameter}
 | 
			
		||||
                     Begin
 | 
			
		||||
                  { first pass just the code parameter for first local use}
 | 
			
		||||
                       hp := p^.left^.right;
 | 
			
		||||
                       p^.left^.right := nil;
 | 
			
		||||
                       must_be_valid := false;
 | 
			
		||||
                       count_ref := true;
 | 
			
		||||
                       firstcallparan(p^.left, nil);
 | 
			
		||||
                       if codegenerror then exit;
 | 
			
		||||
                       p^.left^.right := hp;
 | 
			
		||||
                     {code has to be a var parameter}
 | 
			
		||||
                       if (p^.left^.left^.location.loc<>LOC_REFERENCE) then
 | 
			
		||||
                         CGMessage(type_e_variable_id_expected)
 | 
			
		||||
                       else
 | 
			
		||||
                         if (p^.left^.left^.resulttype^.deftype <> orddef) or
 | 
			
		||||
                            not(porddef(p^.left^.left^.resulttype)^.typ in
 | 
			
		||||
                                [u16bit,s16bit,u32bit,s32bit]) then
 | 
			
		||||
                           CGMessage(type_e_mismatch);
 | 
			
		||||
                       hpp := p^.left^.right
 | 
			
		||||
                     End
 | 
			
		||||
                  Else hpp := p^.left;
 | 
			
		||||
                  {now hpp = the destination value tree}
 | 
			
		||||
                  { first pass just the destination parameter for first local use}
 | 
			
		||||
                  hp:=hpp^.right;
 | 
			
		||||
                  must_be_valid:=false;
 | 
			
		||||
                  count_ref:=true;
 | 
			
		||||
                  hpp^.right:=nil;
 | 
			
		||||
                 {hpp = destination}
 | 
			
		||||
                  firstcallparan(hpp,nil);
 | 
			
		||||
                  if codegenerror then exit;
 | 
			
		||||
                  hpp^.right := hp;
 | 
			
		||||
                  if (hpp^.left^.location.loc<>LOC_REFERENCE) then
 | 
			
		||||
                    CGMessage(type_e_variable_id_expected)
 | 
			
		||||
                  else
 | 
			
		||||
                    If Not((hpp^.left^.resulttype^.deftype = floatdef) or
 | 
			
		||||
                           ((hpp^.left^.resulttype^.deftype = orddef) And
 | 
			
		||||
                            (POrdDef(hpp^.left^.resulttype)^.typ in
 | 
			
		||||
                              [u32bit,s32bit,{s64bitint,u64bit, -- not supported yet in RTL}
 | 
			
		||||
                               u8bit,s8bit,u16bit,s16bit])))
 | 
			
		||||
                        Then CGMessage(type_e_mismatch);
 | 
			
		||||
                  must_be_valid:=true;
 | 
			
		||||
                 {hp = source (String)}
 | 
			
		||||
                  count_ref := false;
 | 
			
		||||
                  must_be_valid := true;
 | 
			
		||||
                  firstcallparan(hp,nil);
 | 
			
		||||
                  if codegenerror then exit;
 | 
			
		||||
                  If (hp^.resulttype^.deftype<>stringdef) then
 | 
			
		||||
                    CGMessage(type_e_mismatch);
 | 
			
		||||
{                  firstcallparan(p^.left,nil);}
 | 
			
		||||
                  { calc registers }
 | 
			
		||||
                  left_right_max(p);
 | 
			
		||||
               end;
 | 
			
		||||
{$EndIf ValIntern}
 | 
			
		||||
            in_include_x_y,
 | 
			
		||||
            in_exclude_x_y:
 | 
			
		||||
              begin
 | 
			
		||||
@ -978,7 +1048,12 @@ implementation
 | 
			
		||||
end.
 | 
			
		||||
{
 | 
			
		||||
  $Log$
 | 
			
		||||
  Revision 1.19  1999-02-22 12:36:34  florian
 | 
			
		||||
  Revision 1.20  1999-03-16 17:52:55  jonas
 | 
			
		||||
    * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
 | 
			
		||||
    * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
 | 
			
		||||
    * in cgai386: also small fixes to emitrangecheck
 | 
			
		||||
 | 
			
		||||
  Revision 1.19  1999/02/22 12:36:34  florian
 | 
			
		||||
    + warning for lo/hi(longint/dword) in -So and -Sd mode added
 | 
			
		||||
 | 
			
		||||
  Revision 1.18  1999/02/22 02:15:49  peter
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user