* fix overflow errors in case coverage code

git-svn-id: trunk@42059 -
This commit is contained in:
Jonas Maebe 2019-05-13 20:30:28 +00:00
parent 6649fab22d
commit b291d17fc5

View File

@ -131,6 +131,8 @@ interface
procedure addelseblock(instr:tnode); procedure addelseblock(instr:tnode);
property labelcnt: cardinal read getlabelcnt; property labelcnt: cardinal read getlabelcnt;
{ returns one less than the covered case range, so that it
does not overflow for a fully covered qword range }
property labelcoverage: qword read getlabelcoverage; property labelcoverage: qword read getlabelcoverage;
protected protected
flabels : pcaselabel; flabels : pcaselabel;
@ -1095,13 +1097,20 @@ implementation
procedure tcasenode.updatecoverage; procedure tcasenode.updatecoverage;
var var
isord: boolean; isord, first: boolean;
procedure count(p : pcaselabel); procedure count(p : pcaselabel);
begin begin
inc(flabelcnt); inc(flabelcnt);
if isord then if isord then
inc(flabelcoverage, (p^._high.svalue - p^._low.svalue) + 1); begin
flabelcoverage:=flabelcoverage + (p^._high - p^._low);
{ ensure we don't overflow in case it covers the
full range of qword }
if not first then
inc(flabelcoverage);
first:=false;
end;
if assigned(p^.less) then if assigned(p^.less) then
count(p^.less); count(p^.less);
if assigned(p^.greater) then if assigned(p^.greater) then
@ -1112,6 +1121,7 @@ implementation
isord:=is_ordinal(left.resultdef); isord:=is_ordinal(left.resultdef);
flabelcnt:=0; flabelcnt:=0;
flabelcoverage:=0; flabelcoverage:=0;
first:=true;
count(flabels); count(flabels);
fcountsuptodate:=true; fcountsuptodate:=true;
end; end;
@ -1133,10 +1143,12 @@ implementation
dec(packedbitsize); dec(packedbitsize);
if is_signed(def) then if is_signed(def) then
begin begin
{$push}{$q-}
if def.low<>(-(int64(1) shl packedbitsize)) then if def.low<>(-(int64(1) shl packedbitsize)) then
exit; exit;
if def.high<>((int64(1) shl packedbitsize)-1) then if def.high<>((int64(1) shl packedbitsize)-1) then
exit; exit;
{$pop}
end end
else else
begin begin
@ -1155,7 +1167,7 @@ implementation
begin begin
{ Check label type coverage for enumerations and small types } { Check label type coverage for enumerations and small types }
getrange(left.resultdef,lv,hv); getrange(left.resultdef,lv,hv);
typcount:=hv.svalue-lv.svalue+1; typcount:=hv-lv;
if not assigned(elseblock) then if not assigned(elseblock) then
begin begin
{ unless cs_check_all_case_coverage is set, only check for enums, booleans and { unless cs_check_all_case_coverage is set, only check for enums, booleans and