← board

Unary minus binds looser than and/shr-x and 12 was -(x and 12)

var x: Integer;  x := 8;
-x and 12     { FPC 8                    pxx -8 }
-x shr 1      { FPC 9223372036854775804  pxx -4 }

and in C, against gcc:

int x = 8;
-x & 12       /* gcc 8    pxx -8 */

Cause, and why it survived

ParseSimpleExpr ate the unary minus at the ADDITIVE level for Pascal and C, leaving Python to negate at the factor level. The comment justified it:

Unary minus is an ADDITIVE-level sign in Pascal — -7 div 2 really is -(7 div 2) in FPC

That is true and unobservable: -(7 div 2) and (-7) div 2 are both -3. The same holds for *, +, mod and shl. The operators that expose the difference are and and shr, and the note picked div — the one operator that cannot answer the question it was asked. So the file test/test_const_precedence.pas has asserted "unary minus binds tightest" since it was written, while testing only cases that hold either way.

Fix

The minus always falls through to ParseFactor's own tkMinus case, which negates ONE factor — the path PyExprMode already used, for the same reason. One line, plus the note rewritten to say what was measured.

Blast radius, checked rather than assumed

grep for -<name> and / -<name> shr across compiler/** and lib/rtl/** finds only prose inside comments — no source of ours uses a shape whose meaning changes, which is consistent with the self-host converging.

Verified

make compiler/pascal26 fixedpoint + tools/gate.sh quick + make test-core GREEN.

Log