[fpc-devel] Dangerous optimization in CASE..OF
Martok
listbox at martoks-place.de
Sun Jul 2 14:30:28 CEST 2017
> Yes, checking the data. I can easily create a similar problem as above with the "range checks" for
> the jump table by reading a negative value into the enum. Unfortunately, the checks are unsigned ...
Actually, fun fact, *fortunately* the checks are unsigned. Having a negative
value (or generally a value before the first element when that has a value
assignment) underflows on the check, and so gets caught by the CMP/JA as well.
Yes, I tried that, your code is safer than you think ;-)
Also, for sparse enums the "gaps" are filled with pointers to else-block, so the
check that is already there turns out to be always safe.
enum = (ela = 5, elb, elc, eld, ele);
1) enum value too small ( = 1):
mov 1,%al
sub 5,%al # al = -4 = $fb
cmp (9-5),%al # $fb > 4
ja $#ELSE-BLOCK # branches
and $ff,%eax
jmp *0x40c000(,%eax,4)
2) enum value in range or in gap (= 7 = elc)
mov 7,%al
sub 5,%al # al = 2
cmp (9-5),%al # 2 <= 4
ja $#ELSE-BLOCK # no branch
and $ff,%eax
jmp *0x40c000(,%eax,4)
3) enum value too large ( = 20)
mov 20,%al
sub 5,%al # al = 15
cmp (9-5),%al # 15 > 4
ja $#ELSE-BLOCK # branches
and $ff,%eax
jmp *0x40c000(,%eax,4)
Same thing on x86_64, where instead of al and eax we use eax and rax, with the
same underflow characteristics.
More information about the fpc-devel
mailing list