From 04a63ea278537b2ebd75e0b6c3b0fe10a9499548 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Tue, 22 Jun 2010 19:15:08 +0000 Subject: [PATCH] * fixed range/overflow checking for succ/pred (mantis #16770) git-svn-id: trunk@15474 - --- .gitattributes | 1 + compiler/ncginl.pas | 2 -- compiler/ninl.pas | 44 +++++++++++++++++++++++++++++++++++++++++ tests/webtbs/tw16770.pp | 23 +++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 tests/webtbs/tw16770.pp diff --git a/.gitattributes b/.gitattributes index c67657f5a8..8974f339d7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10508,6 +10508,7 @@ tests/webtbs/tw1658.pp svneol=native#text/plain tests/webtbs/tw16668.pp svneol=native#text/plain tests/webtbs/tw16700.pp svneol=native#text/plain tests/webtbs/tw1677.pp svneol=native#text/plain +tests/webtbs/tw16770.pp svneol=native#text/plain tests/webtbs/tw1681.pp svneol=native#text/plain tests/webtbs/tw1696.pp svneol=native#text/plain tests/webtbs/tw1699.pp svneol=native#text/plain diff --git a/compiler/ncginl.pas b/compiler/ncginl.pas index 6b24fd045f..effe7bc99b 100644 --- a/compiler/ncginl.pas +++ b/compiler/ncginl.pas @@ -394,8 +394,6 @@ implementation else {$endif not cpu64bitalu} cg.a_op_const_reg(current_asmdata.CurrAsmList,cgop,location.size,1,location.register); - - cg.g_rangecheck(current_asmdata.CurrAsmList,location,resultdef,resultdef); end; diff --git a/compiler/ninl.pas b/compiler/ninl.pas index dfb06e62b0..3f732b6b3a 100644 --- a/compiler/ninl.pas +++ b/compiler/ninl.pas @@ -2661,6 +2661,50 @@ implementation in_succ_x: begin expectloc:=LOC_REGISTER; + { in case of range/overflow checking, use a regular addnode + because it's too complex to handle correctly otherwise } + if ([cs_check_overflow,cs_check_range]*current_settings.localswitches)<>[] then + begin + { create constant 1 } + hp:=cordconstnode.create(1,left.resultdef,false); + typecheckpass(hp); + if not is_integer(hp.resultdef) then + inserttypeconv_internal(hp,sinttype); + + { avoid type errors from the addn/subn } + if not is_integer(left.resultdef) then + inserttypeconv_internal(left,sinttype); + + { addition/substraction depending on succ/pred } + if inlinenumber=in_succ_x then + hp:=caddnode.create(addn,left,hp) + else + hp:=caddnode.create(subn,left,hp); + { assign result of addition } + if not(is_integer(resultdef)) then + inserttypeconv(hp,torddef.create( +{$ifdef cpu64bitaddr} + s64bit, +{$else cpu64bitaddr} + s32bit, +{$endif cpu64bitaddr} + get_min_value(resultdef), + get_max_value(resultdef))) + else + inserttypeconv(hp,resultdef); + + { avoid any possible errors/warnings } + inserttypeconv_internal(hp,resultdef); + + { firstpass it } + firstpass(hp); + + { left is reused } + left:=nil; + + { return new node } + result:=hp; + end; end; in_setlength_x, diff --git a/tests/webtbs/tw16770.pp b/tests/webtbs/tw16770.pp new file mode 100644 index 0000000000..12209c67ec --- /dev/null +++ b/tests/webtbs/tw16770.pp @@ -0,0 +1,23 @@ +{ %result=201 } + +{$mode delphi} +{$r+} +procedure Test; +var + Count: Word; + I: Integer; + +begin + Count := 0; + + for I := 0 to Pred(Count) do + begin + WriteLn(I); + break; + end; +end; + +begin + test; +end. +