I found a inconsistent behaviour for the **shr **operator: The output of the following program

`Smallint: -1 Longint: 2147483647 Int64: 9223372036854775807`

Since shr is a logical shift right

Rules:

1. shr operation is always a logical shift (unsigned).

2. shr operation is 32 bits for the size of the operands <= 32 bits and 64 bits otherwise.

Now details:

vs := cs shr 1;

cs is SmallInt ($FFFF) are sign extended to 32 bit ($FFFFFFFF). Now it shifted without sign ($7FFFFFFF). Now it's needed store to SmallInt. If {$RANGECHECKS ON} will be range error (very big for SmallInt), otherwize only last 16 bits saved ($FFFF). Result is -1.

vl := cl shr 1;

cl is not changed (already 32), signed, so simple unsigned shift ($7FFFFFFF). Because result is fit in vl, so it's simple 2147483647.

Same behaviour for 64 bit integer.

It's all Delphi compatible (including range error).

What about vs := vs shr 1? With optimization, compiler coded this as in-place operation (which ignore rule 2), but do range check as by rule 2 (range error). It's NOT Delphi compatible. Delphi always convert to 32 bit (and result is -1). Without optimization FPC result is -1.

PS: for constants shr operation make by compiler itself, and result can be arithmetic shift or using large size operand (not documented and version depended).