Hello fredvs,
you wrote on Sun, 29 Mar 2020 08:36:10 -0700 (MST):
> So, about those famous 2 last warnings:
>
> I propose this to make the compiler happy:
...
> > msedatalist.pas(891,18) Warning: (4110) Range check error while
> > evaluating constants (-193 must be between 0 and 255)
>
> Point to:
> foldlevelmask = byte(not (foldhiddenmask or currentfoldhiddenmask));
>
> I propose this instead (see abs()):
> foldlevelmask = byte(abs(not (foldhiddenmask or
> currentfoldhiddenmask)));
I'm rather afraid that this will _not_ result in the intended value.
I.e. a statement testing an expression of either "foldhiddenmask" or
"currentfoldhiddenmask" against the value of "foldlevelmask" will _not_
neccessarily always fail (it should fail because of the "not").
This seems to derive from an uncanny mixture of signed and unsigned values,
perhaps due to a range overflow during evaluation of the expression,
triggering an unwanted sign extension and thus turning an unsigned value
"negative".
-193 is $FFFFFF3F(32bit), byte ($3F) = 63, NOT $3F = $C0 = 192.
So it seems the expression ors together bit 6 & 7 of a byte-size type, and
the compiler's evaluator sign extends the result, regarding a set bit 7 as
a negative sign bit... A rather weird compiler error, not a program error.
> - Last warning:
>
> > mseactions.pas(762,34) Warning: (4110) Range check error while
> > evaluating constants (-63489 must be between 0 and 65535)
>
> Point to:
> result:= (key <> 0) and (key <> word(not modmask));
>
> I propose this instead (see abs()):
> result:= (key <> 0) and (key <> word(abs(not modmask)));
>
> What do you think?
About the same as for the case above, Same analysis as above yields:
-63489 = $FFFF07FF, word ($07FF) = 2047, NOT $07FF = $F800 = 63488.
Here, a lot more bits are involved, but this may also derive from a
masking or combining operation, setting the 16-bit-value "sign bit" (bit
15) and triggering a - false - sign extension by the compiler.
It _may be_ that it's sufficient to just mask off any unused bits within
the evaluation expression _before_ casting the result to the destination
size. So
foldlevelmask = byte(not (foldhiddenmask or currentfoldhiddenmask));
might become
foldlevelmask =
byte (not (foldhiddenmask or currentfoldhiddenmask) AND $FF);
and
result:= (key <> 0) and (key <> word(not modmask));
might become
result:= (key <> 0) and (key <> word ((not modmask) AND $FFFF));
And yes,
you wrote on Sun, 29 Mar 2020 09:37:10 -0700 (MST):
> What is very strange is that I get also a warning with this (see abs()
> added):
>
> const
> foldhiddenbit = 7;
^
This is the place that could trigger such a sign extension.
> foldhiddenmask = abs(1 shl foldhiddenbit);
And it's even used indirectly to produce a value "of indeterminate size",
and with indeterminate signedness above that.
> currentfoldhiddenbit = 6;
> currentfoldhiddenmask = abs(1 shl currentfoldhiddenbit);
On the other hand, this sequence does not produce a borderline value, and
thus won't trigger any unexpected (mis-) behaviour.
I suspect a similar situation with the other warning.
Should the second case _not_ arise from such a borderline situation, you
might attempt to report a serious compiler error on the fpc bug tracker.
(There's not any reason to regard every 4th bit as a sign bit! Bit 11, the
probable culprit in the second case above, has no such function at all.)
--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------
_______________________________________________
mseide-msegui-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mseide-msegui-talk