فهرست منبع

* 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 سال پیش
والد
کامیت
a3f17a9e74
3فایلهای تغییر یافته به همراه127 افزوده شده و 26 حذف شده
  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