<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>The main problem, Jonas, is that there will be times where the
enumeration will take on a value that is outside of its domain,
and often through ways that we cannot help, such as external data
being in the wrong format. I'm all for compiler optimisations
assuming that the value is in range for case blocks and
conditional shortcutting, but there needs to be a reliable way to
get a "Yes" or "No" answer as to if it's valid or not that won't
fall foul of these assumptions, hence my suggestion of an
intrinsic or, as with Ondrej's patch, the "is" operator.</p>
<p>I suppose with the bitpacked version... admittedly I can't think
of a construct off-hand that would break it, but if someone knows
of one, then I can definitely evaluate it.</p>
<p>All in all though, we need <i>something</i>, because one can
argue about language semantics until the cows come home, but here
is a reproducible situation that cannot be reliably accounted for
without ditching enumerations entirely, which will only serve to
obfuscate third-party code for no obvious reason.</p>
<p>Gareth aka. Kit<br>
</p>
<p><br>
</p>
<div class="moz-cite-prefix">On 02/07/2019 22:34, Jonas Maebe wrote:<br>
</div>
<blockquote type="cite"
cite="mid:976f1032-dc51-036b-f0ce-8cb48c454274@freepascal.org">
<pre class="moz-quote-pre" wrap="">On 02/07/2019 22:31, Ondrej Pokorny wrote:
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">var
Value: TEnumType;
begin
Value := TEnumType(-1);
IsValid := Value is TEnumType; // IsValid gains false
The compiler may not do any optimizations here (like return always true
if the left side value is the enum type at the right side). This should
be clearly stated and documented if the feature is added to FPC.
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">
Whenever you need an exception like this, it means that the behaviour
does not fit in the language. As a result, it would make the language
(more) inconsistent and harder to reason about, even independently of
optimizations. E.g. if Value is inside a bitpacked array or record,
IsValid will may well be true instead of false, because a bunch of bits
were thrown away during the assignment. This shows that the only place
where the checking can reliably happen, is during the initial conversion
(which should have been done with "as" in this scenario).
And yes, it also complicates compilers/optimizers, because you have to
make sure you handle this special case everywhere, now and forever. E.g.
it would make it impossible to add range annotations for enum types in
LLVM bitcode without adding volatile load hacks all over the place.
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">This is similar to the object-is operator that gets evaluated as well
even if the type of the left-side value is the type at right side:
var
Value: TPersistent;
begin
Value := TPersistent(TObject.Create);
IsValid := Value is TPersistent; // IsValid gains false
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">
This is an invalid program. If you compile with -CR, the program will
abort with an error when the typecast is performed, because it will get
replaced by an "as" operation. In that sense, "integer as enum" would
indeed be somewhat similar, and -CR might even be extended to perform
the same replacement of explicit typecasts with "as" operators for these
types.
As an example of an operation on the resulting "Value" that is already
undefined: if you would call a TPersistent virtual method on it, and
whole-program optimization devirtualised that call, it may call the
"correct" method of TPersistent instead of using the VMT of whatever
other class instance type Value points to.
Invalid data means undefined behaviour, always. "is" is not a special
case that is immune to this. And e.g. in the context of generics,
simplifying/removing such checks where possible would probably be quite
desirable.
As to your patch itself: why do you not directly compare the
tconstexprint values directly, and use the svalue/uvalue fields instead?
Jonas
_______________________________________________
fpc-devel maillist - <a class="moz-txt-link-abbreviated" href="mailto:fpc-devel@lists.freepascal.org">fpc-devel@lists.freepascal.org</a>
<a class="moz-txt-link-freetext" href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>
</pre>
</blockquote>
<div id="DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2"><br />
<table style="border-top: 1px solid #D3D4DE;">
<tr>
<td style="width: 55px; padding-top: 13px;"><a href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient" target="_blank"><img src="https://ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif" alt="" width="46" height="29" style="width: 46px; height: 29px;" /></a></td>
<td style="width: 470px; padding-top: 12px; color: #41424e; font-size: 13px; font-family: Arial, Helvetica, sans-serif; line-height: 18px;">Virus-free. <a href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient" target="_blank" style="color: #4453ea;">www.avast.com</a>
</td>
</tr>
</table><a href="#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1" height="1"> </a></div></body>
</html>