use "constref" if you always want by reference.
...
It may be a side-effect, but that side effect changed the const param (if it is passed by ref). And (according to the doc) you promised to the compiler, that you would write the code in such way that this would not happen (neither directly nor by side effect).
Once again, the problem is that in code that does not know how it will be used (with the same parameter or not) no protection (warn at compile time) that it cannot be used when using the -gt option.
Constref does not solve the problem, and there are no compiler warnings.
Constref was about the inconsistency (32 vs 64 bit results).
As for solving your "Test", do not use any const at all.
Again: Currently your code
only fails with -gt.
But there is no saying that the exact same code, without -gt will work in future versions of fpc. Maybe some optimization that future fpc will apply makes this exact same code crash.
The problem is in the code (unless you stick with current fpc forever), with or without -gt. -gt just makes you aware of the problem.
As I understand now there is no such way, and if someone gets an obvious error using my code, then I will explain to him that so use the procedure is not very good, because it is not reflected in the language and documentation as a bad side effect.
The problem that may not be documented (well it may, but I am not aware off) is how the "out" param works.
That is, that out
can (in some cases) pass in the callers variable. So the result of the out param is assigned to the receiving variable while still inside the called procedure; rather than after/at the return from that procedure. In that it acts like a var param.
Yes, -gt doc may also need to be corrected.
======
Maybe there generally is room to lobby for a note/hint from the compiler for
any case where the same variable is passed twice or more by reference to the same procedure.
function Foo(var a: TBaz; b: TBaz);
...
Foo(x,x);
Probably will also not be "as expected", because inside of Foo any assignment to "a" will also change "b", and vice versa.
In case of out params, it may even be possible to ask, that fpc should generate code passing in a temp variable, whenever it detects that the out-receiver is passed in at least one more by ref param.
Though passing a temp will change behaviour... (not sure if the documented behaviour would allow for this, did not check that part of the docs)