diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index b16c02ef9b..f575485505 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -148,8 +148,8 @@ implementation end; end; arraydef : begin - { string to array of char, the length check is done by the firstpass of this node } - if is_equal(parraydef(def_from)^.definition,cchardef) then + { array of char to string, the length check is done by the firstpass of this node } + if is_chararray(def_from) then begin doconv:=tc_chararray_2_string; if (not(cs_ansistrings in aktlocalswitches) and @@ -233,7 +233,7 @@ implementation begin case def_from^.deftype of pointerdef : begin - if (parraydef(def_to)^.lowrange=0) and + if is_zero_based_array(def_to) and is_equal(ppointerdef(def_from)^.definition,parraydef(def_to)^.definition) then begin doconv:=tc_pointer_2_array; @@ -241,8 +241,9 @@ implementation end; end; stringdef : begin - { array of char to string } - if is_equal(parraydef(def_to)^.definition,cchardef) then + { string to array of char} + if (not(is_special_array(def_to)) or is_open_array(def_to)) and + is_equal(parraydef(def_to)^.definition,cchardef) then begin doconv:=tc_string_2_chararray; b:=1; @@ -275,7 +276,7 @@ implementation end; arraydef : begin { chararray to pointer } - if (parraydef(def_from)^.lowrange=0) and + if is_zero_based_array(def_from) and is_equal(parraydef(def_from)^.definition,ppointerdef(def_to)^.definition) then begin doconv:=tc_array_2_pointer; @@ -648,7 +649,15 @@ implementation end. { $Log$ - Revision 1.24 1999-05-06 10:10:02 peter + Revision 1.25 1999-05-19 20:40:12 florian + * fixed a couple of array related bugs: + - var a : array[0..1] of char; p : pchar; p:=a+123; works now + - open arrays with an odd size doesn't work: movsb wasn't generated + - introduced some new array type helper routines (is_special_array) etc. + - made the array type checking in isconvertable more strict, often + open array can be used where is wasn't allowed etc... + + Revision 1.24 1999/05/06 10:10:02 peter * overloaded conversion has lower priority Revision 1.23 1999/04/26 09:30:47 peter diff --git a/compiler/tcadd.pas b/compiler/tcadd.pas index 1cd04ab6c5..03c92957a5 100644 --- a/compiler/tcadd.pas +++ b/compiler/tcadd.pas @@ -921,15 +921,23 @@ implementation end else - if (rd^.deftype=pointerdef) then + if (rd^.deftype=pointerdef) or + is_zero_based_array(rd) then begin + if is_zero_based_array(rd) then + begin + p^.resulttype:=new(ppointerdef,init(parraydef(rd)^.definition)); + p^.right:=gentypeconvnode(p^.right,p^.resulttype); + firstpass(p^.right); + end; p^.location.loc:=LOC_REGISTER; p^.left:=gentypeconvnode(p^.left,s32bitdef); firstpass(p^.left); calcregisters(p,1,0,0); if p^.treetype=addn then begin - if not(cs_extsyntax in aktmoduleswitches) then + if not(cs_extsyntax in aktmoduleswitches) or + (not(is_pchar(ld)) and (m_tp in aktmodeswitches)) then CGMessage(type_e_mismatch); end else @@ -938,8 +946,15 @@ implementation end else - if (ld^.deftype=pointerdef) then + if (ld^.deftype=pointerdef) or + is_zero_based_array(ld) then begin + if is_zero_based_array(ld) then + begin + p^.resulttype:=new(ppointerdef,init(parraydef(ld)^.definition)); + p^.left:=gentypeconvnode(p^.left,p^.resulttype); + firstpass(p^.left); + end; p^.location.loc:=LOC_REGISTER; p^.right:=gentypeconvnode(p^.right,s32bitdef); firstpass(p^.right); @@ -1082,7 +1097,15 @@ implementation end. { $Log$ - Revision 1.30 1999-05-11 00:47:02 peter + Revision 1.31 1999-05-19 20:40:14 florian + * fixed a couple of array related bugs: + - var a : array[0..1] of char; p : pchar; p:=a+123; works now + - open arrays with an odd size doesn't work: movsb wasn't generated + - introduced some new array type helper routines (is_special_array) etc. + - made the array type checking in isconvertable more strict, often + open array can be used where is wasn't allowed etc... + + Revision 1.30 1999/05/11 00:47:02 peter + constant operations on enums, only in fpc mode Revision 1.29 1999/05/06 09:05:32 peter diff --git a/compiler/types.pas b/compiler/types.pas index a2c9e7d9e7..d1fd2a638e 100644 --- a/compiler/types.pas +++ b/compiler/types.pas @@ -34,6 +34,9 @@ interface { true if we must never copy this parameter } never_copy_const_param : boolean = false; +{***************************************************************************** + Basic type functions + *****************************************************************************} { returns true, if def defines an ordinal type } function is_ordinal(def : pdef) : boolean; @@ -50,8 +53,20 @@ interface { true if p is a char } function is_char(def : pdef) : boolean; - { true if p points to an open string def } - function is_open_string(p : pdef) : boolean; + { true if p is a smallset def } + function is_smallset(p : pdef) : boolean; + + { returns true, if def defines a signed data type (only for ordinal types) } + function is_signed(def : pdef) : boolean; + +{***************************************************************************** + Array helper functions + *****************************************************************************} + + { true, if p points to a zero based (non special like open or + dynamic array def, mainly this is used to see if the array + is convertable to a pointer } + function is_zero_based_array(p : pdef) : boolean; { true if p points to an open array def } function is_open_array(p : pdef) : boolean; @@ -59,6 +74,25 @@ interface { true, if p points to an array of const def } function is_array_constructor(p : pdef) : boolean; + { true, if p points to a variant array } + function is_variant_array(p : pdef) : boolean; + + { true, if p points to an array of const } + function is_array_of_const(p : pdef) : boolean; + + { true, if p points any kind of special array } + function is_special_array(p : pdef) : boolean; + + { true if p is a char array def } + function is_chararray(p : pdef) : boolean; + +{***************************************************************************** + String helper functions + *****************************************************************************} + + { true if p points to an open string def } + function is_open_string(p : pdef) : boolean; + { true if p is an ansi string def } function is_ansistring(p : pdef) : boolean; @@ -71,18 +105,9 @@ interface { true if p is a short string def } function is_shortstring(p : pdef) : boolean; - { true if p is a char array def } - function is_chararray(p : pdef) : boolean; - { true if p is a pchar def } function is_pchar(p : pdef) : boolean; - { true if p is a smallset def } - function is_smallset(p : pdef) : boolean; - - { returns true, if def defines a signed data type (only for ordinal types) } - function is_signed(def : pdef) : boolean; - { returns true, if def uses FPU } function is_fpu(def : pdef) : boolean; @@ -281,15 +306,25 @@ implementation end; + { true, if p points to a zero based array def } + function is_zero_based_array(p : pdef) : boolean; + begin + is_zero_based_array:=(p^.deftype=arraydef) and + (parraydef(p)^.lowrange=0) and + not(is_special_array(p)); + end; + { true, if p points to an open array def } function is_open_array(p : pdef) : boolean; begin is_open_array:=(p^.deftype=arraydef) and (parraydef(p)^.lowrange=0) and (parraydef(p)^.highrange=-1) and - not(is_array_constructor(p)); - end; + not(parraydef(p)^.IsConstructor) and + not(parraydef(p)^.IsVariant) and + not(parraydef(p)^.IsArrayOfConst); + end; { true, if p points to an array of const def } function is_array_constructor(p : pdef) : boolean; @@ -298,6 +333,30 @@ implementation (parraydef(p)^.IsConstructor); end; + { true, if p points to a variant array } + function is_variant_array(p : pdef) : boolean; + begin + is_variant_array:=(p^.deftype=arraydef) and + (parraydef(p)^.IsVariant); + end; + + { true, if p points to an array of const } + function is_array_of_const(p : pdef) : boolean; + begin + is_array_of_const:=(p^.deftype=arraydef) and + (parraydef(p)^.IsArrayOfConst); + end; + + { true, if p points to a special array } + function is_special_array(p : pdef) : boolean; + begin + is_special_array:=(p^.deftype=arraydef) and + ((parraydef(p)^.IsVariant) or + (parraydef(p)^.IsArrayOfConst) or + (parraydef(p)^.IsConstructor) or + is_open_array(p) + ); + end; { true if p is an ansi string def } function is_ansistring(p : pdef) : boolean; @@ -334,7 +393,8 @@ implementation function is_chararray(p : pdef) : boolean; begin is_chararray:=(p^.deftype=arraydef) and - is_equal(parraydef(p)^.definition,cchardef); + is_equal(parraydef(p)^.definition,cchardef) and + not(is_special_array(p)); end; @@ -528,6 +588,7 @@ implementation if (cs_mmx_saturation in aktlocalswitches) then begin is_mmx_able_array:=(p^.deftype=arraydef) and + not(is_special_array(p) and ( ( (parraydef(p)^.definition^.deftype=orddef) and @@ -822,7 +883,15 @@ implementation end. { $Log$ - Revision 1.62 1999-05-19 16:48:29 florian + Revision 1.63 1999-05-19 20:40:15 florian + * fixed a couple of array related bugs: + - var a : array[0..1] of char; p : pchar; p:=a+123; works now + - open arrays with an odd size doesn't work: movsb wasn't generated + - introduced some new array type helper routines (is_special_array) etc. + - made the array type checking in isconvertable more strict, often + open array can be used where is wasn't allowed etc... + + Revision 1.62 1999/05/19 16:48:29 florian * tdef.typename: returns a now a proper type name for the most types Revision 1.61 1999/05/19 10:31:56 florian