From 60a07770f12b60f372d75fd164f1d6b2591e1860 Mon Sep 17 00:00:00 2001 From: svenbarth <pascaldragon@googlemail.com> Date: Fri, 21 Feb 2014 22:49:19 +0000 Subject: [PATCH] Fix cycling after addition of the new case simplification. nset.pas, tcasenode.simplify: don't assume a specific order of the case labels + added test based on ppu.pas, tppu.getaint where no matching case label was found because of the ordering git-svn-id: trunk@26825 - --- .gitattributes | 1 + compiler/nset.pas | 35 ++++++++++++++++++++--------------- tests/tbs/tb0605.pp | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 tests/tbs/tb0605.pp diff --git a/.gitattributes b/.gitattributes index 650c9abdb0..c909095e70 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10161,6 +10161,7 @@ tests/tbs/tb0601.pp svneol=native#text/pascal tests/tbs/tb0602.pp svneol=native#text/plain tests/tbs/tb0603.pp svneol=native#text/pascal tests/tbs/tb0604.pp svneol=native#text/pascal +tests/tbs/tb0605.pp svneol=native#text/pascal tests/tbs/tb205.pp svneol=native#text/plain tests/tbs/tbs0594.pp svneol=native#text/pascal tests/tbs/ub0060.pp svneol=native#text/plain diff --git a/compiler/nset.pas b/compiler/nset.pas index 23582e866c..44c2730a6d 100644 --- a/compiler/nset.pas +++ b/compiler/nset.pas @@ -844,27 +844,32 @@ implementation function tcasenode.simplify(forinline:boolean):tnode; var tmp: pcaselabel; + walkup: boolean; begin result:=nil; if left.nodetype=ordconstn then begin tmp:=labels; - { walk the case labels as long as the upper bound is smaller than - the constant } - while assigned(tmp) and (tmp^._high<tordconstnode(left).value) do - tmp:=tmp^.greater; - { check whether the constant is inside the range } - if assigned(tmp) and - (tmp^._low<=tordconstnode(left).value) and - (tmp^._high>=tordconstnode(left).value) then + { check all case labels until we find one that fits } + walkup:=assigned(tmp^.greater); + while assigned(tmp) do begin - if tmp^.blockid>=blocks.count then - internalerror(2014022101); - result:=pcaseblock(blocks[tmp^.blockid])^.statement; - if not assigned(result) then - internalerror(2014022102); - result:=result.getcopy; - exit; + if (tmp^._low<=tordconstnode(left).value) and + (tmp^._high>=tordconstnode(left).value) then + begin + if tmp^.blockid>=blocks.count then + internalerror(2014022101); + result:=pcaseblock(blocks[tmp^.blockid])^.statement; + if not assigned(result) then + internalerror(2014022102); + result:=result.getcopy; + exit; + end; + + if walkup then + tmp:=tmp^.greater + else + tmp:=tmp^.less; end; { no label did match; use the else block if available } if assigned(elseblock) then diff --git a/tests/tbs/tb0605.pp b/tests/tbs/tb0605.pp new file mode 100644 index 0000000000..1fd3936af6 --- /dev/null +++ b/tests/tbs/tb0605.pp @@ -0,0 +1,42 @@ +program tb0605; + +{$mode objfpc} + +type + aint = longint; + +function getint64: int64; +begin + Result := 64; +end; + +function getlongint: longint; +begin + Result := 32; +end; + +function getword: word; +begin + result := 16; +end; + +function getbyte: byte; +begin + result := 8; +end; + +function getaint: longint; +begin + result:=4; + case sizeof(aint) of + 8: result:=getint64; + 4: result:=getlongint; + 2: result:=smallint(getword); + 1: result:=shortint(getbyte); + end; +end; + +begin + if getaint <> 32 then + Halt(1); +end.