Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 18, 2014 RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Hi, I got this thing working and I think it's about time I get some comments on it. I've been wanting to extend Value Rang Propagation (VRE) for some time now. Mostly because of the fix to the troublesome "signed-unsigned comparisons" issue. Enabling VRE for if-else and "&&" will fix many of the false-positive warnings given out by the fix to bug 259 by allowing code like this: if (signed > 0 && signed < unsigned) { .. } Have a look at the branch: https://github.com/lionello/dmd/compare/if-else-range There, I've also added a __traits(intrange, <expression>) which returns a tuple with the min and max for the given expression. It's used in the test case as follows: const i = foo ? -1 : 33; if (i) static assert(__traits(intrange, i) == Tuple!(-1, 33)); else { //static assert(i == 0); TODO static assert(__traits(intrange, i) == Tuple!(0, 0)); } if (i == 33) { //static assert(i == 33); TODO static assert(__traits(intrange, i) == Tuple!(33, 33)); } else static assert(__traits(intrange, i) == Tuple!(-1, 32)); if (10 <= i) static assert(__traits(intrange, i) == Tuple!(10, 33)); else static assert(__traits(intrange, i) == Tuple!(-1, 9)); It would be nice if this can be used by CTFE as well. Destroy? L. |
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lionello Lunesu | Lionello Lunesu: > I've also added a __traits(intrange, <expression>) which returns a tuple with the min and max for the given expression. I'd like a name like integral_range, and perhaps it's better for it to return a T[2] (fixed size array) instead of a tuple. Such __traits(integral_range, exp) could work on core.checkedint values too, or it could be used by them to remove some overflow tests and increase their performance. > It's used in the test case as follows: I presume your proposal allows this code to compile: int x = 100; void main() { if (x >= 0 && x <= ubyte.max) { ubyte y = x; } } If your proposal is extended to contracts, you can also write: ubyte foo(immutable int x) in { assert(x >= 0 && x <= ubyte.max); } body { return x; } void main() {} Bye, bearophile |
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > I'd like a name like integral_range,
"value_range" seems better, more general.
Bye,
bearophile
|
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 18/06/14 15:53, bearophile wrote: >> I've also added a __traits(intrange, <expression>) which returns a >> tuple with the min and max for the given expression. > > I'd like a name like integral_range, and perhaps it's better for it to > return a T[2] (fixed size array) instead of a tuple. Most other traits return tuples, so it seemed like a good fit. > I presume your proposal allows this code to compile: > > int x = 100; > void main() { > if (x >= 0 && x <= ubyte.max) { > ubyte y = x; > } > } Yes, provided 'x' is immutable or const. It can be extended for mutable values as well, but then mutations/gotos must be tracked. > If your proposal is extended to contracts, you can also write: > > > ubyte foo(immutable int x) > in { > assert(x >= 0 && x <= ubyte.max); > } body { > return x; > } Yeah, I wanted to support "assert" as well, but it doesn't create a scope so it'll be a bit trickier to implement. L. |
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lionello Lunesu | Lionello Lunesu:
>> ubyte foo(immutable int x)
>> in {
>> assert(x >= 0 && x <= ubyte.max);
>> } body {
>> return x;
>> }
>
> Yeah, I wanted to support "assert" as well, but it doesn't create a scope so it'll be a bit trickier to implement.
If you have an assert in a pre-condition and the argument is const, then the body{} is the scope you look for.
Bye,
bearophile
|
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lionello Lunesu | > There, I've also added a __traits(intrange, <expression>) which Very cool. With your new trait I can simplify and, in turn, reduce compilation time for usages of https://github.com/nordlow/justd/blob/master/bound.d I'm looking forward to the merge :) |
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | Am 18.06.2014 09:54, schrieb bearophile:
>> I'd like a name like integral_range,
>
> "value_range" seems better, more general.
>
> Bye,
> bearophile
Or even better, "valueRange", to be consistent with the general naming convention.
|
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | > Very cool. With your new trait I can simplify and, in turn, reduce compilation time for usages of
Actually, if I'm not mistaken, with this trait, we can inhibit range value range checking in run-time when and get all the benefits Ada range types currently delivers.
Yet another sales point for D!
|
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | Nordlöw:
> Actually, if I'm not mistaken, with this trait, we can inhibit range value range checking in run-time when and get all the benefits Ada range types currently delivers.
I'd like to see and discuss how this could happen.
Bye,
bearophile
|
June 18, 2014 Re: RFC: Value range propagation for if-else | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > I'd like to see and discuss how this could happen.
Certainly! I'm available later on this evening at, say, 20.00 CET.
/Per
|
Copyright © 1999-2021 by the D Language Foundation