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
mseide-msegui-talk@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mseide-msegui-talk

Reply via email to