Browse Source

* properly calculate the size of enumeration types having negative elements and a max. value exceeding the upper bound of
the elsewhere matching signed type, resolves #41019

florian 8 months ago
parent
commit
04a56e2900
2 changed files with 47 additions and 5 deletions
  1. 3 5
      compiler/symdef.pas
  2. 44 0
      tests/webtbs/tw41019.pp

+ 3 - 5
compiler/symdef.pas

@@ -1054,8 +1054,6 @@ interface
        end;
        tstringdefclass = class of tstringdef;
 
-       { tenumdef }
-
        tenumdef = class(tstoreddef)
           minval,
           maxval    : asizeint;
@@ -3064,16 +3062,16 @@ implementation
     procedure tenumdef.calcsavesize(packenum: shortint);
       begin
 {$IFNDEF cpu64bitaddr} {$push}{$warnings off} {$ENDIF} //comparison always false warning
-        if (packenum=8) or (int64(min)<low(longint)) or (int64(max)>high(cardinal)) then
+        if (packenum=8) or (int64(min)<low(longint)) or (int64(max)>high(cardinal)) or ((min<0) and (max>high(longint))) then
          savesize:=8
 {$IFNDEF cpu64bitaddr} {$pop} {$ENDIF}
         else
 {$IFDEF cpu16bitaddr} {$push}{$warnings off} {$ENDIF} //comparison always false warning
-         if (packenum=4) or (min<low(smallint)) or (max>high(word)) then
+         if (packenum=4) or (min<low(smallint)) or (max>high(word)) or ((min<0) and (max>high(smallint))) then
           savesize:=4
 {$IFDEF cpu16bitaddr} {$pop} {$ENDIF}
         else
-         if (packenum=2) or (min<low(shortint)) or (max>high(byte)) then
+         if (packenum=2) or (min<low(shortint)) or (max>high(byte)) or ((min<0) and (max>high(shortint))) then
           savesize:=2
         else
          savesize:=1;

+ 44 - 0
tests/webtbs/tw41019.pp

@@ -0,0 +1,44 @@
+{$packenum 1}
+type
+  tA = (an1 = -1, a255 = 255);
+  tB = (bn1 = -1, b128 = 128);
+  tC = (cn127 = -127, c128 = 128);
+  tD = (dn1= -1, d65535 = 65535);
+var
+  a: tA; b: tB; c: tC; d: tD;
+  size, failures: integer;
+begin
+  failures := 0;
+  size := sizeOf(tA);
+  if size <> sizeof(smallint) then
+    inc( failures); // size = 1
+  a := a255;
+  if ord(a) <> 255 then
+    inc( failures); // (a = -1)
+
+  size := sizeOf(tB);
+  if size <> sizeof(smallint) then
+    inc( failures); // size = 1
+  b := b128;
+  if ord(b) <> 128 then
+    inc( failures); // (b = -128)
+
+  size := sizeOf(tC);
+  if size <> sizeof(smallint) then
+    inc( failures); // size = 1
+  c := c128;
+  if ord(c) <> 128 then
+    inc( failures); // (c = -128)
+
+  size := sizeOf(tD);
+  if size <> sizeof(longint) then
+    inc( failures); // size = 2
+  d := d65535;
+  if ord(d) <> 65535 then
+    inc( failures); // (d = -1)
+
+  assert( failures = 0); // (failures = 8)
+  if failures>0 then
+    halt(1);
+  writeln('ok');
+end.