When all elements of an enumeration type appear in a case statement, FPC should produce code as if the last one would be an "else".
Here is the simplest example I could think of.
program project1;
type TNo=(zero,one);
function version1(const input:TNo):sizeuint;
begin
result:=0;
case input of
zero: inc(result);
one: inc(result);
end;
end;
function version2(const input:TNo):sizeuint;
begin
result:=0;
case input of
zero: inc(result);
else inc(result); //Instead of "one: inc(result);"
end;
end;
var
x:TNo;
begin
if paramcount=0 then x:=zero else x:=one;
writeln(version1(x));
writeln(version2(x));
end.
Here is the code produced with maximum level of optimizations.
.section .text.n_p$project1_$$_version1$tno$$qword,"ax"
.balign 16,0x90
.globl P$PROJECT1_$$_VERSION1$TNO$$QWORD
.type P$PROJECT1_$$_VERSION1$TNO$$QWORD,@function
P$PROJECT1_$$_VERSION1$TNO$$QWORD:
.Lc2:
# Var input located in register edi
# [project1.lpr]
# [6] begin
# Var $result located in register rax
.Ll1:
# [7] result:=0;
xorl %eax,%eax
.Ll2:
# [8] case input of
testl %edi,%edi
je .Lj6
subl $1,%edi
je .Lj7
ret
.balign 16,0x90
.Lj6:
.Ll3:
# [9] zero: inc(result);
addq $1,%rax
ret
.balign 16,0x90
.Lj7:
.Ll4:
# [10] one: inc(result);
addq $1,%rax
.balign 16,0x90
.Lc3:
.Ll5:
# [12] end;
ret
.Lc1:
.Lt2:
.Le0:
.size P$PROJECT1_$$_VERSION1$TNO$$QWORD, .Le0 - P$PROJECT1_$$_VERSION1$TNO$$QWORD
.Ll6:
.section .text.n_p$project1_$$_version2$tno$$qword,"ax"
.balign 16,0x90
.globl P$PROJECT1_$$_VERSION2$TNO$$QWORD
.type P$PROJECT1_$$_VERSION2$TNO$$QWORD,@function
P$PROJECT1_$$_VERSION2$TNO$$QWORD:
.Lc5:
# Var input located in register edi
# [15] begin
# Var $result located in register rax
.Ll7:
# [16] result:=0;
xorl %eax,%eax
.Ll8:
# [17] case input of
testl %edi,%edi
jne .Lj11
.Ll9:
# [18] zero: inc(result);
addq $1,%rax
ret
.p2align 4,,10
.p2align 3
.Lj11:
.Ll10:
# [19] else inc(result);
addq $1,%rax
.Lc6:
.Ll11:
# [21] end;
ret
.Lc4:
.Lt3:
.Le1:
.size P$PROJECT1_$$_VERSION2$TNO$$QWORD, .Le1 - P$PROJECT1_$$_VERSION2$TNO$$QWORD
.Ll12:
The compiler should produce the same code for both versions of the function. Notice that in version2 "one:" is replaced with "else". FPC produces a useless conditional jump for the last one, making the code bigger and slower.
This optimization can't be safely done by a programmer by hand because an addition to the enumeration type would automatically introduce bugs at the "else" parts.