Browse Source

* 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...

florian 26 years ago
parent
commit
a3f17a9e74
3 changed files with 127 additions and 26 deletions
  1. 16 7
      compiler/htypechk.pas
  2. 27 4
      compiler/tcadd.pas
  3. 84 15
      compiler/types.pas

+ 16 - 7
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

+ 27 - 4
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

+ 84 - 15
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