diff --git a/.gitattributes b/.gitattributes index 09cdf130a8..eb70025a08 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8025,6 +8025,7 @@ tests/webtbs/tw8222a.pp svneol=native#text/plain tests/webtbs/tw8222b.pp svneol=native#text/plain tests/webtbs/tw8229.pp svneol=native#text/plain tests/webtbs/tw8232.pp svneol=native#text/plain +tests/webtbs/tw8258.pp svneol=native#text/plain tests/webtbs/tw8264.pp svneol=native#text/plain tests/webtbs/ub1873.pp svneol=native#text/plain tests/webtbs/ub1883.pp svneol=native#text/plain diff --git a/compiler/ncgset.pas b/compiler/ncgset.pas index b5bc6c2757..c310f97e04 100644 --- a/compiler/ncgset.pas +++ b/compiler/ncgset.pas @@ -151,8 +151,9 @@ implementation { be caught when range checking is on! (JM) } { cg.a_op_const_reg(list,OP_AND,31,bitnumber); } - if bitsize<>ressize then + if tcgsize2unsigned[bitsize]<>tcgsize2unsigned[ressize] then begin + internalerror(2007020401); { FIX ME! We're not allowed to modify the value register here! } { shift value register "bitnumber" bits to the right } @@ -232,7 +233,7 @@ implementation begin { check if we can use smallset operation using btl which is limited to 32 bits, the left side may also not contain higher values !! } - use_small:=(tsetdef(right.resultdef).settype=smallset) and + use_small:=(tsetdef(right.resultdef).settype=smallset) and not is_signed(left.resultdef) and ((left.resultdef.typ=orddef) and (torddef(left.resultdef).high<=32) or (left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max<=32)); @@ -262,17 +263,26 @@ implementation pleftreg : tregister; setparts : Tsetparts; opsize : tcgsize; + uopsize : tcgsize; + orgopsize : tcgsize; genjumps, use_small : boolean; i,numparts : byte; - + l, l2 : tasmlabel; + needslabel : Boolean; begin { We check first if we can generate jumps, this can be done because the resultdef is already set in firstpass } genjumps := checkgenjumps(setparts,numparts,use_small); - opsize:=OS_32; + orgopsize := def_cgsize(left.resultdef); + uopsize := OS_INT; + if is_signed(left.resultdef) then + opsize := tcgsize(ord(uopsize)+(ord(OS_S8)-ord(OS_8))) + else + opsize := uopsize; + needslabel := false; { calculate both operators } { the complex one first } @@ -307,7 +317,7 @@ implementation { use fact that a <= x <= b <=> aword(x-a) <= aword(b-a) } begin { is the range different from all legal values? } - if (setparts[i].stop-setparts[i].start <> 255) then + if (setparts[i].stop-setparts[i].start <> 255) or not (orgopsize = OS_8) then begin { yes, is the lower bound <> 0? } if (setparts[i].start <> 0) then @@ -364,7 +374,7 @@ implementation {*****************************************************************} begin { location is always LOC_REGISTER } - location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); + location_reset(location, LOC_REGISTER, uopsize{def_cgsize(resultdef)}); { We will now generated code to check the set itself, no jmps, handle smallsets separate, because it allows faster checks } @@ -373,17 +383,17 @@ implementation {**************************** SMALL SET **********************} if left.nodetype=ordconstn then begin - location_force_reg(current_asmdata.CurrAsmList,right.location,opsize,true); + location_force_reg(current_asmdata.CurrAsmList, right.location, uopsize, true); location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size); { first SHR the register } - cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,opsize,tordconstnode(left).value and 31,right.location.register,location.register); + cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, uopsize, tordconstnode(left).value and 31, right.location.register, location.register); { then extract the lowest bit } - cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,opsize,1,location.register); + cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_AND, uopsize, 1, location.register); end else begin location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false); - location_force_reg(current_asmdata.CurrAsmList,right.location,opsize,false); + location_force_reg(current_asmdata.CurrAsmList, right.location, uopsize, false); { allocate a register for the result } location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size); { emit bit test operation } @@ -409,26 +419,30 @@ implementation else hr := left.location.register; { load right in register } - hr2:=cg.getintregister(current_asmdata.CurrAsmList,opsize); - cg.a_load_const_reg(current_asmdata.CurrAsmList,opsize,right.location.value,hr2); + hr2:=cg.getintregister(current_asmdata.CurrAsmList, uopsize); + cg.a_load_const_reg(current_asmdata.CurrAsmList, uopsize, right.location.value, hr2); { emit bit test operation } - emit_bit_test_reg_reg(current_asmdata.CurrAsmList,left.location.size,left.location.register,hr2,opsize,hr2); + emit_bit_test_reg_reg(current_asmdata.CurrAsmList, left.location.size, left.location.register, hr2, uopsize, hr2); { if left > 31 then hr := 0 else hr := $ffffffff } - cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,opsize,32,left.location.register,hr); - cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,opsize,31,hr); + cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SUB, uopsize, 32, left.location.register, hr); + cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SAR, uopsize, 31, hr); { if left > 31, then result := 0 else result := result of bit test } - cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_AND,opsize,hr,hr2); + cg.a_op_reg_reg(current_asmdata.CurrAsmList, OP_AND, uopsize, hr, hr2); { allocate a register for the result } location.register := cg.getintregister(current_asmdata.CurrAsmList,location.size); - cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,location.size,hr2,location.register); + cg.a_load_reg_reg(current_asmdata.CurrAsmList, uopsize, location.size, hr2, location.register); end { of right.location.loc=LOC_CONSTANT } { do search in a normal set which could have >32 elementsm but also used if the left side contains higher values > 32 } else if left.nodetype=ordconstn then begin + if (tordconstnode(left).value < 0) or ((tordconstnode(left).value shr 3) >= right.resultdef.size) then + {should be caught earlier } + internalerror(2007020402); + { use location.register as scratch register here } if (target_info.endian = endian_little) then inc(right.location.reference.offset,tordconstnode(left).value shr 3) @@ -444,38 +458,73 @@ implementation end else begin - location_force_reg(current_asmdata.CurrAsmList,left.location,OS_INT,true); + location_force_reg(current_asmdata.CurrAsmList, left.location, opsize, true); pleftreg := left.location.register; location_freetemp(current_asmdata.CurrAsmList,left.location); - hr := cg.getaddressregister(current_asmdata.CurrAsmList); - cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,5,pleftreg,hr); - cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHL,OS_INT,2,hr); - href := right.location.reference; - if (href.base = NR_NO) then - href.base := hr - else if (right.location.reference.index = NR_NO) then - href.index := hr - else - begin - hr2 := cg.getaddressregister(current_asmdata.CurrAsmList); - cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href, hr2); - reference_reset_base(href,hr2,0); - href.index := hr; - end; { allocate a register for the result } - location.register := cg.getintregister(current_asmdata.CurrAsmList,opsize); - cg.a_load_ref_reg(current_asmdata.CurrAsmList,opsize,opsize,href,location.register); + location.register := cg.getintregister(current_asmdata.CurrAsmList, uopsize); - hr := cg.getintregister(current_asmdata.CurrAsmList,opsize); - cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_AND,opsize,31,pleftreg,hr); - cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_SHR,opsize,hr,location.register); - cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,opsize,1,location.register); + if (opsize >= OS_S8) or { = if signed } + ((left.resultdef.typ=orddef) and (torddef(left.resultdef).high >= tsetdef(right.resultdef).setmax)) or + ((left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max >= tsetdef(right.resultdef).setmax)) then + begin + current_asmdata.getjumplabel(l); + current_asmdata.getjumplabel(l2); + needslabel := True; + + cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, opsize, OC_BE, tsetdef(right.resultdef).setmax, pleftreg, l); + + cg.a_load_const_reg(current_asmdata.CurrAsmList, opsize, 0, location.register); + cg.a_jmp_always(current_asmdata.CurrAsmList, l2); + + cg.a_label(current_asmdata.CurrAsmList, l); + end; + + case right.location.loc of + LOC_REGISTER, LOC_CREGISTER : + begin + cg.a_load_reg_reg(current_asmdata.CurrAsmList, uopsize, uopsize, right.location.register, location.register); + end; + LOC_CREFERENCE, LOC_REFERENCE : + begin + hr := cg.getaddressregister(current_asmdata.CurrAsmList); + cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SHR, uopsize, 5, pleftreg, hr); + cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SHL, uopsize, 2, hr); + + href := right.location.reference; + if (href.base = NR_NO) then + href.base := hr + else if (right.location.reference.index = NR_NO) then + href.index := hr + else + begin + hr2 := cg.getaddressregister(current_asmdata.CurrAsmList); + cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList, href, hr2); + reference_reset_base(href, hr2, 0); + href.index := hr; + end; + cg.a_load_ref_reg(current_asmdata.CurrAsmList, uopsize, uopsize, href, location.register); + end + else + internalerror(2007020403); + end; + + hr := cg.getintregister(current_asmdata.CurrAsmList, uopsize); + cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_AND, uopsize, 31, pleftreg, hr); + cg.a_op_reg_reg(current_asmdata.CurrAsmList, OP_SHR, uopsize, hr, location.register); + cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_AND, uopsize, 1, location.register); + + if needslabel then + cg.a_label(current_asmdata.CurrAsmList, l2); end; end; end; - location_freetemp(current_asmdata.CurrAsmList,right.location); + location_freetemp(current_asmdata.CurrAsmList, right.location); + + location.size := def_cgsize(resultdef); + location.register := cg.makeregsize(current_asmdata.CurrAsmList, location.register, location.size); end; {***************************************************************************** diff --git a/compiler/nset.pas b/compiler/nset.pas index 1227a7f0b2..4612d74655 100644 --- a/compiler/nset.pas +++ b/compiler/nset.pas @@ -240,7 +240,7 @@ implementation if not assigned(left.resultdef) then internalerror(20021126); - if (m_fpc in current_settings.modeswitches) then + if (m_tp7 in current_settings.modeswitches) then begin { insert a hint that a range check error might occur on non-byte elements with the in operator. @@ -254,18 +254,20 @@ implementation (left.resultdef.typ = enumdef) and (tenumdef(left.resultdef).maxval > 255) ) - then + then CGMessage(type_h_in_range_check); { type conversion/check } if assigned(tsetdef(right.resultdef).elementdef) then inserttypeconv(left,tsetdef(right.resultdef).elementdef); end - else + else if not is_ordinal(left.resultdef) or (left.resultdef.size > uinttype.size) then begin - { insert explicit type conversion/check } - if assigned(tsetdef(right.resultdef).elementdef) then - inserttypeconv_internal(left,tsetdef(right.resultdef).elementdef); + CGMessage(type_h_in_range_check); + if is_signed(left.resultdef) then + inserttypeconv(left,sinttype) + else + inserttypeconv(left,uinttype); end; { empty set then return false } @@ -280,21 +282,31 @@ implementation end; { constant evaluation } - if (left.nodetype=ordconstn) and (right.nodetype=setconstn) then - begin - t:=cordconstnode.create(byte(tordconstnode(left).value in Tsetconstnode(right).value_set^), - booltype,true); - typecheckpass(t); - result:=t; - exit; - end; + if (left.nodetype=ordconstn) then + begin + if (right.nodetype=setconstn) then + begin + t:=cordconstnode.create(byte(tordconstnode(left).value in Tsetconstnode(right).value_set^), + booltype,true); + typecheckpass(t); + result:=t; + exit; + end + else + begin + if (is_signed(left.resultdef) and (tordconstnode(left).value < 0)) or + (TConstExprUInt(tordconstnode(left).value) > tsetdef(right.resultdef).setmax) then + begin + t:=cordconstnode.create(0, booltype, true); + typecheckpass(t); + result:=t; + exit; + end; + end; + end; end; - { Warning : This is the first pass for the generic version } - { the only difference is mainly the result location which } - { is changed, compared to the i386 version. } - { ALSO REGISTER ALLOC IS WRONG? } function tinnode.pass_1 : tnode; begin result:=nil; @@ -316,8 +328,8 @@ implementation begin { a smallset needs maybe an misc. register } if (left.nodetype<>ordconstn) and - not(right.expectloc in [LOC_CREGISTER,LOC_REGISTER]) and - (right.registersint<1) then + not(right.expectloc in [LOC_CREGISTER,LOC_REGISTER]) and + (right.registersint<1) then inc(registersint); end; end; diff --git a/compiler/x86/nx86set.pas b/compiler/x86/nx86set.pas index 02799a3fe7..ba044ad5cd 100644 --- a/compiler/x86/nx86set.pas +++ b/compiler/x86/nx86set.pas @@ -87,6 +87,7 @@ implementation hreg,hreg2, pleftreg : tregister; opsize : tcgsize; + orgopsize : tcgsize; setparts : array[1..8] of Tsetpart; i,numparts : byte; adjustment : longint; @@ -144,12 +145,6 @@ implementation setparts[numparts].start:=setparts[numparts].stop; setparts[numparts].stop:=i; ranges := true; - { there's only one compare per range anymore. Only a } - { sub is added, but that's much faster than a } - { cmp/jcc combo so neglect its effect } -{ inc(compares); - if compares>maxcompares then - exit; } end else begin @@ -165,8 +160,8 @@ implementation because the resultdef is already set in firstpass } { check if we can use smallset operation using btl which is limited - to 32 bits, the left side may also not contain higher values !! } - use_small:=(tsetdef(right.resultdef).settype=smallset) and + to 32 bits, the left side may also not contain higher values or be signed !! } + use_small:=(tsetdef(right.resultdef).settype=smallset) and not is_signed(left.resultdef) and ((left.resultdef.typ=orddef) and (torddef(left.resultdef).high<=32) or (left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max<=32)); @@ -189,42 +184,31 @@ implementation if nf_swapped in flags then swapleftright; + orgopsize := def_cgsize(left.resultdef); + opsize := OS_INT; + if is_signed(left.resultdef) then + opsize := tcgsize(ord(opsize)+(ord(OS_S8)-ord(OS_8))); + if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) then - location_force_reg(current_asmdata.CurrAsmList,left.location,OS_INT,true); + location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true); + if genjumps then begin { It gives us advantage to check for the set elements separately instead of using the SET_IN_BYTE procedure. To do: Build in support for LOC_JUMP } - opsize := def_cgsize(left.resultdef); - { If register is used, use only lower 8 bits } + { load and zero or sign extend as necessary } if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then begin - { for ranges we always need a 32bit register, because then we } - { use the register as base in a reference (JM) } - if ranges then - begin - pleftreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,OS_INT); - cg.a_load_reg_reg(current_asmdata.CurrAsmList,left.location.size,OS_INT,left.location.register,pleftreg); - if opsize<>OS_INT then - cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,OS_INT,255,pleftreg); - opsize:=OS_INT; - end - else - { otherwise simply use the lower 8 bits (no "and" } - { necessary this way) (JM) } - begin - pleftreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,OS_8); - opsize := OS_8; - end; + pleftreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,opsize); + cg.a_load_reg_reg(current_asmdata.CurrAsmList,left.location.size,opsize,left.location.register,pleftreg); end else begin { load the value in a register } - pleftreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); - opsize:=OS_32; - cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_8,OS_32,left.location.reference,pleftreg); + pleftreg:=cg.getintregister(current_asmdata.CurrAsmList,opsize); + cg.a_load_ref_reg(current_asmdata.CurrAsmList,left.location.size,opsize,left.location.reference,pleftreg); end; { Get a label to jump to the end } @@ -248,17 +232,16 @@ implementation { use fact that a <= x <= b <=> cardinal(x-a) <= cardinal(b-a) } begin { is the range different from all legal values? } - if (setparts[i].stop-setparts[i].start <> 255) then + if (setparts[i].stop-setparts[i].start <> 255) or not (orgopsize = OS_8) then begin { yes, is the lower bound <> 0? } if (setparts[i].start <> 0) then begin if (left.location.loc = LOC_CREGISTER) then begin - hreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); - cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,OS_INT,pleftreg,hreg); + hreg:=cg.getintregister(current_asmdata.CurrAsmList,opsize); + cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,pleftreg,hreg); pleftreg:=hreg; - opsize:=OS_INT; end; cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,opsize,setparts[i].start-adjustment,pleftreg); end; @@ -296,7 +279,7 @@ implementation { if the last one was a range, the carry flag is already } { set appropriately } not(setparts[numparts].range) then - current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO)); + current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO)); { To compensate for not doing a second pass } right.location.reference.symbol:=nil; { Now place the end label } @@ -384,15 +367,15 @@ implementation { load constants to a register } if left.nodetype=ordconstn then - location_force_reg(current_asmdata.CurrAsmList,left.location,OS_INT,true); + location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true); case left.location.loc of LOC_REGISTER, LOC_CREGISTER: begin - hreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,OS_32); - cg.a_load_reg_reg(current_asmdata.CurrAsmList,left.location.size,OS_32,left.location.register,hreg); - cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_32,OC_BE,31,hreg,l); + hreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,opsize); + cg.a_load_reg_reg(current_asmdata.CurrAsmList,left.location.size,opsize,left.location.register,hreg); + cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_BE,31,hreg,l); { reset carry flag } current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO)); cg.a_jmp_always(current_asmdata.CurrAsmList,l2); @@ -405,18 +388,7 @@ implementation end; else begin -{$ifdef CORRECT_SET_IN_FPC} - if m_tp in current_settings.modeswitches then - begin - {***WARNING only correct if - reference is 32 bits (PM) *****} - emit_const_ref(A_CMP,S_L,31,reference_copy(left.location.reference)); - end - else -{$endif CORRECT_SET_IN_FPC} - begin - emit_const_ref(A_CMP,S_B,31,left.location.reference); - end; + emit_const_ref(A_CMP,TCGSize2OpSize[orgopsize],31,left.location.reference); cg.a_jmp_flags(current_asmdata.CurrAsmList,F_BE,l); { reset carry flag } current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO)); @@ -434,9 +406,13 @@ implementation cg.a_label(current_asmdata.CurrAsmList,l2); end { of right.location.loc=LOC_CONSTANT } { do search in a normal set which could have >32 elementsm - but also used if the left side contains higher values > 32 } + but also used if the left side contains values > 32 or < 0 } else if left.nodetype=ordconstn then begin + if (tordconstnode(left).value < 0) or ((tordconstnode(left).value shr 3) >= right.resultdef.size) then + {should be caught earlier } + internalerror(2007020201); + location.resflags:=F_NE; inc(right.location.reference.offset,tordconstnode(left).value shr 3); emit_const_ref(A_TEST,S_B,1 shl (tordconstnode(left).value and 7),right.location.reference); @@ -444,14 +420,57 @@ implementation else begin if (left.location.loc=LOC_REGISTER) then - pleftreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,OS_32) + pleftreg:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,opsize) else - pleftreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); - cg.a_load_loc_reg(current_asmdata.CurrAsmList,OS_32,left.location,pleftreg); + pleftreg:=cg.getintregister(current_asmdata.CurrAsmList,opsize); + + cg.a_load_loc_reg(current_asmdata.CurrAsmList,opsize,left.location,pleftreg); location_freetemp(current_asmdata.CurrAsmList,left.location); - emit_reg_ref(A_BT,S_L,pleftreg,right.location.reference); - { tg.ungetiftemp(current_asmdata.CurrAsmList,right.location.reference) happens below } - location.resflags:=F_C; + + if (opsize >= OS_S8) or { = if signed } + ((left.resultdef.typ=orddef) and (torddef(left.resultdef).high >= tsetdef(right.resultdef).setmax)) or + ((left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max >= tsetdef(right.resultdef).setmax)) then + begin + + { we have to check if the value is < 0 or > setmax } + + current_asmdata.getjumplabel(l); + current_asmdata.getjumplabel(l2); + + { BE will be false for negative values } + cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_BE,tsetdef(right.resultdef).setmax,pleftreg,l); + { reset carry flag } + current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO)); + cg.a_jmp_always(current_asmdata.CurrAsmList,l2); + + cg.a_label(current_asmdata.CurrAsmList,l); + + case right.location.loc of + LOC_REGISTER, LOC_CREGISTER : + emit_reg_reg(A_BT,S_L,pleftreg,right.location.register); + LOC_CREFERENCE, LOC_REFERENCE : + emit_reg_ref(A_BT,S_L,pleftreg,right.location.reference); + else + internalerror(2007020301); + end; + + cg.a_label(current_asmdata.CurrAsmList,l2); + + location.resflags:=F_C; + + end + else + begin + case right.location.loc of + LOC_REGISTER, LOC_CREGISTER : + emit_reg_reg(A_BT,S_L,pleftreg,right.location.register); + LOC_CREFERENCE, LOC_REFERENCE : + emit_reg_ref(A_BT,S_L,pleftreg,right.location.reference); + else + internalerror(2007020302); + end; + location.resflags:=F_C; + end; end; end; end; diff --git a/tests/webtbs/tw8258.pp b/tests/webtbs/tw8258.pp new file mode 100644 index 0000000000..7af9d3bc26 --- /dev/null +++ b/tests/webtbs/tw8258.pp @@ -0,0 +1,1256 @@ +program SetTests; + +{$APPTYPE CONSOLE} + +{$IFDEF FPC} + {$mode delphi} +{$ENDIF} + +{$R+} +{$Q+} + +uses + SysUtils; + +var + u8 : Byte; + s8 : ShortInt; + u16 : Word; + s16 : SmallInt; + u32 : LongWord; + s32 : LongInt; + u64 : QWord; + s64 : Int64; + + LargeSet : set of Byte; + SmallSet : set of 0..31; + + Error : Boolean; + +procedure CheckResult(const s: string; aIs, aExpected: Boolean); overload; +begin + if aIs <> aExpected then begin + WriteLn(s, aIs, ' <> ', aExpected, ' * * * ERROR * * * ERROR * * * ERROR * * *'); + Error := True; + end else + WriteLn(s, aIs); +end; + +procedure CheckResult(const s: string; aIs: Boolean); overload; +begin + WriteLn(s, aIs, ' <> EXCEPTION * * * ERROR * * * ERROR * * * ERROR * * *'); + Error := True; +end; + + +begin + Error := False; + + WriteLn('--- Variable against constant set [0, 2, 8..20, 99..192] ---' ); + WriteLn; + + u8 := 100; + s8 := 100; + u16 := 100; + s16 := 100; + u32 := 100; + s32 := 100; + u64 := 100; + s64 := 100; + + WriteLn('100, should be true'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20, 99..192], True); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20, 99..192], True); + CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], True); + CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], True); + CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], True); + CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], True); + CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], True); + CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], True); + WriteLn; + + u8 := 98; + s8 := 98; + u16 := 98; + s16 := 98; + u32 := 98; + s32 := 98; + u64 := 98; + s64 := 98; + + WriteLn('98, should be false'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20, 99..192], False); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20, 99..192], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], False); + CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], False); + WriteLn; + + u8 := 193; +// s8 := 193; + u16 := 193; + s16 := 193; + u32 := 193; + s32 := 193; + u64 := 193; + s64 := 193; + + WriteLn('193, should be false'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20, 99..192], False); +// CheckResult(' s8 -> ', s8 in [0, 2, 8..20, 99..192], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], False); + CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], False); + WriteLn; + +// u8 := 256; +// s8 := 256; + u16 := 256; + s16 := 256; + u32 := 256; + s32 := 256; + u64 := 256; + s64 := 256; + + WriteLn('256, should be false'); +// CheckResult(' u8 -> ', u8 in [0, 2, 8..20, 99..192], False); +// CheckResult(' s8 -> ', s8 in [0, 2, 8..20, 99..192], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], False); + CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192], False); + WriteLn; + + u8 := High(u8); + s8 := High(s8); + u16 := High(u16); + s16 := High(s16); + u32 := High(u32); + s32 := High(s32); + u64 := High(u64); + s64 := High(s64); + + WriteLn('High(type), s8 should be true, u64/s64 should cause range check'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20, 99..192], False); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20, 99..192], True); + CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False); + try + CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192]); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try + CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + u8 := Low(u8); + s8 := Low(s8); + u16 := Low(u16); + s16 := Low(s16); + u32 := Low(u32); + s32 := Low(s32); + u64 := Low(u64); + s64 := Low(s64); + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error'); + CheckResult('u8 -> ', u8 in [0, 2, 8..20, 99..192], True); + CheckResult('s8 -> ', s8 in [0, 2, 8..20, 99..192], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20, 99..192], True); + CheckResult('s16 -> ', s16 in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20, 99..192], True); + CheckResult('s32 -> ', s32 in [0, 2, 8..20, 99..192], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20, 99..192], True); + + try + CheckResult('s64 -> ', s64 in [0, 2, 8..20, 99..192]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- Variable against set of byte with value [0, 2, 8..20, 99..192] ---' ); + WriteLn; + + LargeSet := [0, 2, 8..20, 99..192]; + + u8 := 100; + s8 := 100; + u16 := 100; + s16 := 100; + u32 := 100; + s32 := 100; + u64 := 100; + s64 := 100; + + WriteLn('100, should be true'); + CheckResult(' u8 -> ', u8 in LargeSet, True); + CheckResult(' s8 -> ', s8 in LargeSet, True); + CheckResult('u16 -> ', u16 in LargeSet, True); + CheckResult('s16 -> ', s16 in LargeSet, True); + CheckResult('u32 -> ', u32 in LargeSet, True); + CheckResult('s32 -> ', s32 in LargeSet, True); + CheckResult('u64 -> ', u64 in LargeSet, True); + CheckResult('s64 -> ', s64 in LargeSet, True); + WriteLn; + + u8 := 98; + s8 := 98; + u16 := 98; + s16 := 98; + u32 := 98; + s32 := 98; + u64 := 98; + s64 := 98; + + WriteLn('98, should be false'); + CheckResult(' u8 -> ', u8 in LargeSet, False); + CheckResult(' s8 -> ', s8 in LargeSet, False); + CheckResult('u16 -> ', u16 in LargeSet, False); + CheckResult('s16 -> ', s16 in LargeSet, False); + CheckResult('u32 -> ', u32 in LargeSet, False); + CheckResult('s32 -> ', s32 in LargeSet, False); + CheckResult('u64 -> ', u64 in LargeSet, False); + CheckResult('s64 -> ', s64 in LargeSet, False); + WriteLn; + + u8 := 193; +// s8 := 193; + u16 := 193; + s16 := 193; + u32 := 193; + s32 := 193; + u64 := 193; + s64 := 193; + + WriteLn('193, should be false'); + CheckResult(' u8 -> ', u8 in LargeSet, False); +// CheckResult(' s8 -> ', s8 in LargeSet, False); + CheckResult('u16 -> ', u16 in LargeSet, False); + CheckResult('s16 -> ', s16 in LargeSet, False); + CheckResult('u32 -> ', u32 in LargeSet, False); + CheckResult('s32 -> ', s32 in LargeSet, False); + CheckResult('u64 -> ', u64 in LargeSet, False); + CheckResult('s64 -> ', s64 in LargeSet, False); + WriteLn; + +// u8 := 256; +// s8 := 256; + u16 := 256; + s16 := 256; + u32 := 256; + s32 := 256; + u64 := 256; + s64 := 256; + + WriteLn('256, should be false'); +// CheckResult(' u8 -> ', u8 in LargeSet, False); +// CheckResult(' s8 -> ', s8 in LargeSet, False); + CheckResult('u16 -> ', u16 in LargeSet, False); + CheckResult('s16 -> ', s16 in LargeSet, False); + CheckResult('u32 -> ', u32 in LargeSet, False); + CheckResult('s32 -> ', s32 in LargeSet, False); + CheckResult('u64 -> ', u64 in LargeSet, False); + CheckResult('s64 -> ', s64 in LargeSet, False); + WriteLn; + + u8 := High(u8); + s8 := High(s8); + u16 := High(u16); + s16 := High(s16); + u32 := High(u32); + s32 := High(s32); + u64 := High(u64); + s64 := High(s64); + + WriteLn('High(type), s8 should be true, u64/s64 should cause range check'); + CheckResult(' u8 -> ', u8 in LargeSet, False); + CheckResult(' s8 -> ', s8 in LargeSet, True); + CheckResult('u16 -> ', u16 in LargeSet, False); + CheckResult('s16 -> ', s16 in LargeSet, False); + CheckResult('u32 -> ', u32 in LargeSet, False); + CheckResult('s32 -> ', s32 in LargeSet, False); + try + CheckResult('u64 -> ', u64 in LargeSet); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try + CheckResult('s64 -> ', s64 in LargeSet); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + u8 := Low(u8); + s8 := Low(s8); + u16 := Low(u16); + s16 := Low(s16); + u32 := Low(u32); + s32 := Low(s32); + u64 := Low(u64); + s64 := Low(s64); + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error'); + CheckResult('u8 -> ', u8 in LargeSet, True); + CheckResult('s8 -> ', s8 in LargeSet, False); + CheckResult('u16 -> ', u16 in LargeSet, True); + CheckResult('s16 -> ', s16 in LargeSet, False); + CheckResult('u32 -> ', u32 in LargeSet, True); + CheckResult('s32 -> ', s32 in LargeSet, False); + CheckResult('u64 -> ', u64 in LargeSet, True); + + try + CheckResult('s64 -> ', s64 in LargeSet); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- constant value against constant set [0, 2, 8..20, 99..192] ---' ); + WriteLn; + + WriteLn('100, should be true'); + CheckResult('100 -> ', 100 in [0, 2, 8..20, 99..192], True); + WriteLn; + + WriteLn('98, should be false'); + CheckResult(' 98 -> ', 98 in [0, 2, 8..20, 99..192], False); + WriteLn; + + WriteLn('193, should be false'); + CheckResult('193 -> ', 193 in [0, 2, 8..20, 99..192], False); + WriteLn; + + WriteLn('256, should be false'); + CheckResult('256 -> ', 256 in [0, 2, 8..20, 99..192], False); + WriteLn; + + WriteLn('High(type), s8 should be true, u64/s64 should cause range check at compile time'); + CheckResult(' u8 -> ', High(u8) in [0, 2, 8..20, 99..192], False); + CheckResult(' s8 -> ', High(s8) in [0, 2, 8..20, 99..192], True); + CheckResult('u16 -> ', High(u16) in [0, 2, 8..20, 99..192], False); + CheckResult('s16 -> ', High(s16) in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', High(u32) in [0, 2, 8..20, 99..192], False); + CheckResult('s32 -> ', High(s32) in [0, 2, 8..20, 99..192], False); + try +// CheckResult('u64 -> ', High(u64) in [0, 2, 8..20, 99..192]); + WriteLn('u64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try +// CheckResult('s64 -> ', High(s64) in [0, 2, 8..20, 99..192]); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error at compile time'); + CheckResult('u8 -> ', Low(u8) in [0, 2, 8..20, 99..192], True); + CheckResult('s8 -> ', Low(s8) in [0, 2, 8..20, 99..192], False); + CheckResult('u16 -> ', Low(u16) in [0, 2, 8..20, 99..192], True); + CheckResult('s16 -> ', Low(s16) in [0, 2, 8..20, 99..192], False); + CheckResult('u32 -> ', Low(u32) in [0, 2, 8..20, 99..192], True); + CheckResult('s32 -> ', Low(s32) in [0, 2, 8..20, 99..192], False); + CheckResult('u64 -> ', Low(u64) in [0, 2, 8..20, 99..192], True); + + try +// CheckResult('s64 -> ', Low(s64) in [0, 2, 8..20, 99..192]); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- constant value against set of byte with value [0, 2, 8..20, 99..192] ---' ); + WriteLn; + + LargeSet := [0, 2, 8..20, 99..192]; + + WriteLn('100, should be true'); + CheckResult('100 -> ', 100 in LargeSet, True); + WriteLn; + + WriteLn('98, should be false'); + CheckResult(' 98 -> ', 98 in LargeSet, False); + WriteLn; + + WriteLn('193, should be false'); + CheckResult('193 -> ', 193 in LargeSet, False); + WriteLn; + + WriteLn('256, should be false'); + CheckResult('256 -> ', 256 in LargeSet, False); + WriteLn; + + WriteLn('High(type), s8 should be true, u64/s64 should cause range check at compile time'); + CheckResult(' u8 -> ', High(u8) in LargeSet, False); + CheckResult(' s8 -> ', High(s8) in LargeSet, True); + CheckResult('u16 -> ', High(u16) in LargeSet, False); + CheckResult('s16 -> ', High(s16) in LargeSet, False); + CheckResult('u32 -> ', High(u32) in LargeSet, False); + CheckResult('s32 -> ', High(s32) in LargeSet, False); + try +// CheckResult('u64 -> ', High(u64) in LargeSet); + WriteLn('u64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try +// CheckResult('s64 -> ', High(s64) in LargeSet); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error at compile time'); + CheckResult(' u8 -> ', Low(u8) in LargeSet, True); + CheckResult(' s8 -> ', Low(s8) in LargeSet, False); + CheckResult('u16 -> ', Low(u16) in LargeSet, True); + CheckResult('s16 -> ', Low(s16) in LargeSet, False); + CheckResult('u32 -> ', Low(u32) in LargeSet, True); + CheckResult('s32 -> ', Low(s32) in LargeSet, False); + CheckResult('u64 -> ', Low(u64) in LargeSet, True); + try +// CheckResult('s64 -> ', Low(s64) in LargeSet); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- Variable against constant set [0, 2, 8..20] ---' ); + WriteLn; + + u8 := 10; + s8 := 10; + u16 := 10; + s16 := 10; + u32 := 10; + s32 := 10; + u64 := 10; + s64 := 10; + + WriteLn('10, should be true'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20], True); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20], True); + CheckResult('u16 -> ', u16 in [0, 2, 8..20], True); + CheckResult('s16 -> ', s16 in [0, 2, 8..20], True); + CheckResult('u32 -> ', u32 in [0, 2, 8..20], True); + CheckResult('s32 -> ', s32 in [0, 2, 8..20], True); + CheckResult('u64 -> ', u64 in [0, 2, 8..20], True); + CheckResult('s64 -> ', s64 in [0, 2, 8..20], True); + WriteLn; + + u8 := 7; + s8 := 7; + u16 := 7; + s16 := 7; + u32 := 7; + s32 := 7; + u64 := 7; + s64 := 7; + + WriteLn('7, should be false'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20], False); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20], False); + CheckResult('s64 -> ', s64 in [0, 2, 8..20], False); + WriteLn; + + u8 := 30; + s8 := 30; + u16 := 30; + s16 := 30; + u32 := 30; + s32 := 30; + u64 := 30; + s64 := 30; + + WriteLn('30, should be false'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20], False); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20], False); + CheckResult('s64 -> ', s64 in [0, 2, 8..20], False); + WriteLn; + +// u8 := 256; +// s8 := 256; + u16 := 256; + s16 := 256; + u32 := 256; + s32 := 256; + u64 := 256; + s64 := 256; + + WriteLn('256, should be false'); +// CheckResult(' u8 -> ', u8 in [0, 2, 8..20], False); +// CheckResult(' s8 -> ', s8 in [0, 2, 8..20], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20], False); + CheckResult('s64 -> ', s64 in [0, 2, 8..20], False); + WriteLn; + + u8 := High(u8); + s8 := High(s8); + u16 := High(u16); + s16 := High(s16); + u32 := High(u32); + s32 := High(s32); + u64 := High(u64); + s64 := High(s64); + + WriteLn('High(type), should be false, u64/s64 should cause range check'); + CheckResult(' u8 -> ', u8 in [0, 2, 8..20], False); + CheckResult(' s8 -> ', s8 in [0, 2, 8..20], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20], False); + CheckResult('s16 -> ', s16 in [0, 2, 8..20], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20], False); + CheckResult('s32 -> ', s32 in [0, 2, 8..20], False); + try + CheckResult('u64 -> ', u64 in [0, 2, 8..20]); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try + CheckResult('s64 -> ', s64 in [0, 2, 8..20]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + u8 := Low(u8); + s8 := Low(s8); + u16 := Low(u16); + s16 := Low(s16); + u32 := Low(u32); + s32 := Low(s32); + u64 := Low(u64); + s64 := Low(s64); + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error'); + CheckResult('u8 -> ', u8 in [0, 2, 8..20], True); + CheckResult('s8 -> ', s8 in [0, 2, 8..20], False); + CheckResult('u16 -> ', u16 in [0, 2, 8..20], True); + CheckResult('s16 -> ', s16 in [0, 2, 8..20], False); + CheckResult('u32 -> ', u32 in [0, 2, 8..20], True); + CheckResult('s32 -> ', s32 in [0, 2, 8..20], False); + CheckResult('u64 -> ', u64 in [0, 2, 8..20], True); + + try + CheckResult('s64 -> ', s64 in [0, 2, 8..20]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- Variable against set of 0..31 with value [0, 2, 8..20] ---' ); + WriteLn; + + SmallSet := [0, 2, 8..20]; + + u8 := 10; + s8 := 10; + u16 := 10; + s16 := 10; + u32 := 10; + s32 := 10; + u64 := 10; + s64 := 10; + + WriteLn('10, should be true'); + CheckResult(' u8 -> ', u8 in SmallSet, True); + CheckResult(' s8 -> ', s8 in SmallSet, True); + CheckResult('u16 -> ', u16 in SmallSet, True); + CheckResult('s16 -> ', s16 in SmallSet, True); + CheckResult('u32 -> ', u32 in SmallSet, True); + CheckResult('s32 -> ', s32 in SmallSet, True); + CheckResult('u64 -> ', u64 in SmallSet, True); + CheckResult('s64 -> ', s64 in SmallSet, True); + WriteLn; + + u8 := 7; + s8 := 7; + u16 := 7; + s16 := 7; + u32 := 7; + s32 := 7; + u64 := 7; + s64 := 7; + + WriteLn('7, should be false'); + CheckResult(' u8 -> ', u8 in SmallSet, False); + CheckResult(' s8 -> ', s8 in SmallSet, False); + CheckResult('u16 -> ', u16 in SmallSet, False); + CheckResult('s16 -> ', s16 in SmallSet, False); + CheckResult('u32 -> ', u32 in SmallSet, False); + CheckResult('s32 -> ', s32 in SmallSet, False); + CheckResult('u64 -> ', u64 in SmallSet, False); + CheckResult('s64 -> ', s64 in SmallSet, False); + WriteLn; + + u8 := 30; + s8 := 30; + u16 := 30; + s16 := 30; + u32 := 30; + s32 := 30; + u64 := 30; + s64 := 30; + + WriteLn('30, should be false'); + CheckResult(' u8 -> ', u8 in SmallSet, False); + CheckResult(' s8 -> ', s8 in SmallSet, False); + CheckResult('u16 -> ', u16 in SmallSet, False); + CheckResult('s16 -> ', s16 in SmallSet, False); + CheckResult('u32 -> ', u32 in SmallSet, False); + CheckResult('s32 -> ', s32 in SmallSet, False); + CheckResult('u64 -> ', u64 in SmallSet, False); + CheckResult('s64 -> ', s64 in SmallSet, False); + WriteLn; + +// u8 := 256; +// s8 := 256; + u16 := 256; + s16 := 256; + u32 := 256; + s32 := 256; + u64 := 256; + s64 := 256; + + WriteLn('256, should be false'); +// CheckResult(' u8 -> ', u8 in SmallSet, False); +// CheckResult(' s8 -> ', s8 in SmallSet, False); + CheckResult('u16 -> ', u16 in SmallSet, False); + CheckResult('s16 -> ', s16 in SmallSet, False); + CheckResult('u32 -> ', u32 in SmallSet, False); + CheckResult('s32 -> ', s32 in SmallSet, False); + CheckResult('u64 -> ', u64 in SmallSet, False); + CheckResult('s64 -> ', s64 in SmallSet, False); + WriteLn; + + u8 := High(u8); + s8 := High(s8); + u16 := High(u16); + s16 := High(s16); + u32 := High(u32); + s32 := High(s32); + u64 := High(u64); + s64 := High(s64); + + WriteLn('High(type), should be false, u64/s64 should cause range check'); + CheckResult(' u8 -> ', u8 in SmallSet, False); + CheckResult(' s8 -> ', s8 in SmallSet, False); + CheckResult('u16 -> ', u16 in SmallSet, False); + CheckResult('s16 -> ', s16 in SmallSet, False); + CheckResult('u32 -> ', u32 in SmallSet, False); + CheckResult('s32 -> ', s32 in SmallSet, False); + try + CheckResult('u64 -> ', u64 in SmallSet); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try + CheckResult('s64 -> ', s64 in SmallSet); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + u8 := Low(u8); + s8 := Low(s8); + u16 := Low(u16); + s16 := Low(s16); + u32 := Low(u32); + s32 := Low(s32); + u64 := Low(u64); + s64 := Low(s64); + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error'); + CheckResult('u8 -> ', u8 in SmallSet, True); + CheckResult('s8 -> ', s8 in SmallSet, False); + CheckResult('u16 -> ', u16 in SmallSet, True); + CheckResult('s16 -> ', s16 in SmallSet, False); + CheckResult('u32 -> ', u32 in SmallSet, True); + CheckResult('s32 -> ', s32 in SmallSet, False); + CheckResult('u64 -> ', u64 in SmallSet, True); + + try + CheckResult('s64 -> ', s64 in SmallSet); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- constant value against constant set [0, 2, 8..20] ---' ); + WriteLn; + + WriteLn('10, should be true'); + CheckResult('10 -> ', 10 in [0, 2, 8..20], True); + WriteLn; + + WriteLn('7, should be false'); + CheckResult(' 7 -> ', 7 in [0, 2, 8..20], False); + WriteLn; + + WriteLn('30, should be false'); + CheckResult('30 -> ', 30 in [0, 2, 8..20], False); + WriteLn; + + WriteLn('256, should be false'); + CheckResult('256 -> ', 256 in [0, 2, 8..20], False); + WriteLn; + + WriteLn('High(type), should be false, u64/s64 should cause range check at compile time'); + CheckResult(' u8 -> ', High(u8) in [0, 2, 8..20], False); + CheckResult(' s8 -> ', High(s8) in [0, 2, 8..20], False); + CheckResult('u16 -> ', High(u16) in [0, 2, 8..20], False); + CheckResult('s16 -> ', High(s16) in [0, 2, 8..20], False); + CheckResult('u32 -> ', High(u32) in [0, 2, 8..20], False); + CheckResult('s32 -> ', High(s32) in [0, 2, 8..20], False); + try +// CheckResult('u64 -> ', High(u64) in [0, 2, 8..20]); + WriteLn('u64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try +// CheckResult('s64 -> ', High(s64) in [0, 2, 8..20]); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error at compile time'); + CheckResult('u8 -> ', Low(u8) in [0, 2, 8..20], True); + CheckResult('s8 -> ', Low(s8) in [0, 2, 8..20], False); + CheckResult('u16 -> ', Low(u16) in [0, 2, 8..20], True); + CheckResult('s16 -> ', Low(s16) in [0, 2, 8..20], False); + CheckResult('u32 -> ', Low(u32) in [0, 2, 8..20], True); + CheckResult('s32 -> ', Low(s32) in [0, 2, 8..20], False); + CheckResult('u64 -> ', Low(u64) in [0, 2, 8..20], True); + + try +// CheckResult('s64 -> ', Low(s64) in [0, 2, 8..20]); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- constant value against set of 0..31 with value [0, 2, 8..20] ---' ); + WriteLn; + + SmallSet := [0, 2, 8..20]; + + WriteLn('10, should be true'); + CheckResult('10 -> ', 10 in SmallSet, True); + WriteLn; + + WriteLn('7, should be false'); + CheckResult(' 7 -> ', 7 in SmallSet, False); + WriteLn; + + WriteLn('30, should be false'); + CheckResult('30 -> ', 30 in SmallSet, False); + WriteLn; + + WriteLn('256, should be false'); + CheckResult('256 -> ', 256 in SmallSet, False); + WriteLn; + + WriteLn('High(type), all false, u64/s64 should cause range check at compile time'); + CheckResult(' u8 -> ', High(u8) in SmallSet, False); + CheckResult(' s8 -> ', High(s8) in SmallSet, False); + CheckResult('u16 -> ', High(u16) in SmallSet, False); + CheckResult('s16 -> ', High(s16) in SmallSet, False); + CheckResult('u32 -> ', High(u32) in SmallSet, False); + CheckResult('s32 -> ', High(s32) in SmallSet, False); + try +// CheckResult('u64 -> ', High(u64) in SmallSet); + WriteLn('u64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try +// CheckResult('s64 -> ', High(s64) in SmallSet); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + + WriteLn('Low(type), all unsigned true, all signed false, except s64 -> range check error at compile time'); + CheckResult(' u8 -> ', Low(u8) in SmallSet, True); + CheckResult(' s8 -> ', Low(s8) in SmallSet, False); + CheckResult('u16 -> ', Low(u16) in SmallSet, True); + CheckResult('s16 -> ', Low(s16) in SmallSet, False); + CheckResult('u32 -> ', Low(u32) in SmallSet, True); + CheckResult('s32 -> ', Low(s32) in SmallSet, False); + CheckResult('u64 -> ', Low(u64) in SmallSet, True); + try +// CheckResult('s64 -> ', Low(s64) in SmallSet); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- Variable against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41] ---' ); + WriteLn; + + u8 := 25; + s8 := 25; + u16 := 25; + s16 := 25; + u32 := 25; + s32 := 25; + u64 := 25; + s64 := 25; + + WriteLn('25, should be true'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + WriteLn; + + u8 := 26; + s8 := 26; + u16 := 26; + s16 := 26; + u32 := 26; + s32 := 26; + u64 := 26; + s64 := 26; + + WriteLn('26, should be false'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn; + + u8 := 49; + s8 := 49; + u16 := 49; + s16 := 49; + u32 := 49; + s32 := 49; + u64 := 49; + s64 := 49; + + WriteLn('49, should be false'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn; + +// u8 := 256; +// s8 := 256; + u16 := 256; + s16 := 256; + u32 := 256; + s32 := 256; + u64 := 256; + s64 := 256; + + WriteLn('256, should be false'); +// CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); +// CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn; + + u8 := High(u8); + s8 := High(s8); + u16 := High(u16); + s16 := High(s16); + u32 := High(u32); + s32 := High(s32); + u64 := High(u64); + s64 := High(s64); + + WriteLn('High(type), should be false, u64/s64 should cause range check'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + try + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + u8 := Low(u8); + s8 := Low(s8); + u16 := Low(u16); + s16 := Low(s16); + u32 := Low(u32); + s32 := Low(s32); + u64 := Low(u64); + s64 := Low(s64); + + WriteLn('Low(type), all false, except s64 -> range check error'); + CheckResult('u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + + try + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- constant value against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41] ---' ); + WriteLn; + + WriteLn('25, should be true'); + CheckResult('25 -> ', 25 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], True); + WriteLn; + + WriteLn('26, should be false'); + CheckResult(' 26 -> ', 26 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn; + + WriteLn('49, should be false'); + CheckResult('49 -> ', 49 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn; + + WriteLn('256, should be false'); + CheckResult('256 -> ', 256 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn; + + WriteLn('High(type), should be false, u64/s64 should cause range check at compile time'); + CheckResult(' u8 -> ', High(u8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult(' s8 -> ', High(s8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', High(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', High(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', High(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', High(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + try +// CheckResult('u64 -> ', High(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn('u64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try +// CheckResult('s64 -> ', High(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('Low(type), all false, except s64 -> range check error at compile time'); + CheckResult('u8 -> ', Low(u8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s8 -> ', Low(s8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u16 -> ', Low(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s16 -> ', Low(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u32 -> ', Low(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('s32 -> ', Low(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + CheckResult('u64 -> ', Low(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + + try +// CheckResult('s64 -> ', Low(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41], False); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- Variable against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29] ---' ); + WriteLn; + + u8 := 25; + s8 := 25; + u16 := 25; + s16 := 25; + u32 := 25; + s32 := 25; + u64 := 25; + s64 := 25; + + WriteLn('25, should be true'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + WriteLn; + + u8 := 26; + s8 := 26; + u16 := 26; + s16 := 26; + u32 := 26; + s32 := 26; + u64 := 26; + s64 := 26; + + WriteLn('26, should be false'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn; + + u8 := 30; + s8 := 30; + u16 := 30; + s16 := 30; + u32 := 30; + s32 := 30; + u64 := 30; + s64 := 30; + + WriteLn('30, should be false'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn; + +// u8 := 256; +// s8 := 256; + u16 := 256; + s16 := 256; + u32 := 256; + s32 := 256; + u64 := 256; + s64 := 256; + + WriteLn('256, should be false'); +// CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); +// CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn; + + u8 := High(u8); + s8 := High(s8); + u16 := High(u16); + s16 := High(s16); + u32 := High(u32); + s32 := High(s32); + u64 := High(u64); + s64 := High(s64); + + WriteLn('High(type), should be false, u64/s64 should cause range check'); + CheckResult(' u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult(' s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + try + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + u8 := Low(u8); + s8 := Low(s8); + u16 := Low(u16); + s16 := Low(s16); + u32 := Low(u32); + s32 := Low(s32); + u64 := Low(u64); + s64 := Low(s64); + + WriteLn('Low(type), all false, except s64 -> range check error'); + CheckResult('u8 -> ', u8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s8 -> ', s8 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', u16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', s16 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', u32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', s32 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u64 -> ', u64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + + try + CheckResult('s64 -> ', s64 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('--- constant value against constant set [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29] ---' ); + WriteLn; + + WriteLn('25, should be true'); + CheckResult('25 -> ', 25 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], True); + WriteLn; + + WriteLn('26, should be false'); + CheckResult(' 26 -> ', 26 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn; + + WriteLn('30, should be false'); + CheckResult('30 -> ', 30 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn; + + WriteLn('256, should be false'); + CheckResult('256 -> ', 256 in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn; + + WriteLn('High(type), should be false, u64/s64 should cause range check at compile time'); + CheckResult(' u8 -> ', High(u8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult(' s8 -> ', High(s8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', High(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', High(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', High(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', High(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + try +// CheckResult('u64 -> ', High(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn('u64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('u64 -> ', E.Classname,': ',E.Message); + end; + try +// CheckResult('s64 -> ', High(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + WriteLn('Low(type), all false, except s64 -> range check error at compile time'); + CheckResult('u8 -> ', Low(u8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s8 -> ', Low(s8) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u16 -> ', Low(u16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s16 -> ', Low(s16) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u32 -> ', Low(u32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('s32 -> ', Low(s32) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + CheckResult('u64 -> ', Low(u64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + + try +// CheckResult('s64 -> ', Low(s64) in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29], False); + WriteLn('s64 -> Error: range check error while evaluating constants'); + except + on E: Exception do + WriteLn('s64 -> ', E.Classname,': ',E.Message); + end; + WriteLn; + + if Error then begin + WriteLn('* * * ERROR * * * ERROR * * * ERROR * * * ERROR * * * ERROR * * * ERROR * * *'); + Halt(1); + end else + Halt(0); +end.