On 5/13/24 22:16, HAO CHEN GUI wrote:
Hi Aldy,
Thanks for your review comments.
在 2024/5/13 19:18, Aldy Hernandez 写道:
+//Implement range operator for CFN_BUILT_IN_ISFINITE
+class cfn_isfinite : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ virtual bool fold_range (irange &r, tree type, const frange &op1,
+ const irange &, relation_trio) const override
+ {
+ if (op1.undefined_p ())
+ return false;
+
+ if (op1.known_isfinite ())
+ {
+ r.set_nonzero (type);
+ return true;
+ }
+
+ if (op1.known_isnan ()
+ || op1.known_isinf ())
+ {
+ r.set_zero (type);
+ return true;
+ }
+
+ return false;
I think the canonical API behaviour sets R to varying and returns true
instead of just returning false if nothing is known about the range.
Correct. If we know it's varying, we just set varying and return
true. Returning false is usually reserved for "I have no idea".
However, every caller of fold_range() should know to ignore a return
of false, so you should be safe.
So it's better to set varying here and return true?
In general, returning TRUE and VARYING is preferable for supported
types. Returning FALSE usually means you are trying to fold a statement
which produced a type which is unsupported. Or at least there is
something in the statement we don't understand or want to deal with.
The primary functional difference is that when we have a chain of
operations (which is more common with op1_range and op2_range calls) ,
we will often continue processing and feed a VARYING result into the
next operation. FALSE will usually terminate further processing.
That said, we probably aren't super consistent because there are grey
areas, but we probably should try to follow that model. In the end, you
are unlikely to see much real difference between the 2 options.
Andrew