Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Version 1.07.0
- sf.net #893: 'Suffixes are only valid in -lang' error message showing incorrect -lang options allowed
- fbc uses '-march=armv8-a' instead of invalid option '-march=aarch64' when passing options to gcc/LLVM (czsgaba)
- rtlib: sys/io.h incorrectly included on systems that do not provide it. It is used only for x86, x86_64 and is unnecessary for all other linux targets (armhf ,arm64, mips ....)
- SELECT CASE AS CONST checks for ranges that would produce unreasonably large jump tables (greater than 8192 entries)


Version 1.06.0
Expand Down
29 changes: 27 additions & 2 deletions src/compiler/parser-compound-select-const.bas
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ sub cSelConstStmtNext( byval stk as FB_CMPSTMTSTK ptr )

'' first case?
if( swtbase = ctx.base ) then
'' we initially set the bias to the first value minus
'' FB_MAXJUMPTBSLOTS. This allows us to compare range values
'' (fromvalue <= tovalue ) and check if ranges are too
'' large. Later, in cSelConstStmtEnd() we will adjust the
'' bias to the lowest valid range value seen.

'' In terms of values used by the user:
'' minimum := bias
'' initial := bias + FB_MAXJUMPTBSLOTS
'' maximum := bias + FB_MAXJUMPTBSLOTS*2

stk->select.const_.bias = value - FB_MAXJUMPTBSLOTS
end if

Expand Down Expand Up @@ -253,10 +264,17 @@ sub cSelConstStmtNext( byval stk as FB_CMPSTMTSTK ptr )
continue do
end if

assert( value <= (FB_MAXJUMPTBSLOTS*2) )
assert( tovalue <= (FB_MAXJUMPTBSLOTS*2) )
assert( tovalue >= value )

'' check if emitted jump table would be too large. Even without this check,
'' emitter can still build a valid jump table, as it will fill in gaps
'' between ranges, however we limit the size here, as it might end up
'' unreasonably large.
if( (value >= FB_MAXJUMPTBSLOTS*2) or (tovalue >= FB_MAXJUMPTBSLOTS*2) ) then
errReport( FB_ERRMSG_RANGETOOLARGE )
continue do
end if

'' Add Case values in range
do
if( hSelConstAddCase( swtbase, value, label ) = FALSE ) then
Expand Down Expand Up @@ -323,6 +341,13 @@ sub cSelConstStmtEnd( byval stk as FB_CMPSTMTSTK ptr )
stk->select.const_.bias += adjust_bias
end if

'' Jump table too large? We haven't overflowed any internal structures
'' and the emitter will produce valid code, but to be consistent with
'' limits and documentation, report an error.
if( span >= FB_MAXJUMPTBSLOTS ) then
errReport( FB_ERRMSG_TOOMANYLABELS )
end if

astAdd( astBuildJMPTB( stk->select.sym, _
@ctx.casevalues(stk->select.const_.base), _
@ctx.caselabels(stk->select.const_.base), _
Expand Down
6 changes: 6 additions & 0 deletions tests/compound/select-const-large-range-1.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
' TEST_MODE : COMPILE_ONLY_FAIL

dim x as integer
select case as const x
case 1 to 8193
end select
8 changes: 8 additions & 0 deletions tests/compound/select-const-large-range-2.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
' TEST_MODE : COMPILE_ONLY_FAIL

dim x as integer
select case as const x
case 8192
case 8193
case 1
end select