Bug 13010 – Use variable range propagation (VRP) for static assert

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-06-30T11:03:35Z
Last change time
2024-12-13T18:21:50Z
Keywords
pull
Assigned to
No Owner
Creator
Lionello Lunesu
Moved to GitHub: dmd#18844 →

Comments

Comment #0 by lio+bugzilla — 2014-06-30T11:03:35Z
This code should work: void testvrp(ubyte l) { immutable int i = l; static assert(i + 1); }
Comment #1 by lio+bugzilla — 2014-06-30T11:08:47Z
Comment #2 by k.hara.pg — 2014-06-30T11:31:08Z
(In reply to Lionello Lunesu from comment #0) > This code should work: > > void testvrp(ubyte l) > { > immutable int i = l; > static assert(i + 1); > } To me the code looks very weird, because: 1. static assert condition is *always* evaluated in compile time. 2. but the expression i + 1 cannot be evaluated at compile time. These items are contradict each other, so I think it should not be compiled. Could you please show me an *actual* use case of this enhancement?
Comment #3 by lio+bugzilla — 2014-06-30T17:02:52Z
(In reply to Kenji Hara from comment #2) > (In reply to Lionello Lunesu from comment #0) > > This code should work: > > > > void testvrp(ubyte l) > > { > > immutable int i = l; > > static assert(i + 1); > > } > > To me the code looks very weird, because: > > 1. static assert condition is *always* evaluated in compile time. > 2. but the expression i + 1 cannot be evaluated at compile time. > > These items are contradict each other, so I think it should not be compiled. > > Could you please show me an *actual* use case of this enhancement? How do you feel about it when the code is changed to this: void testvrp(ubyte l) { immutable int i = l; static assert(i >= 0); }
Comment #4 by k.hara.pg — 2014-07-01T07:09:47Z
(In reply to Lionello Lunesu from comment #3) > How do you feel about it when the code is changed to this: > > void testvrp(ubyte l) > { > immutable int i = l; > static assert(i >= 0); > } Looks not bad. In my thought, the value of i is not known at compile time, but i >= 0 could be determined to true at compile time with VRP. And, it should be handled in const-folding phase. By advancing the thought, compiler will be able to generate "statement is not reachable" warning in else branch of the code. void test(ubyte n) { immutable int i = n; if (i >= 0) // const-folding with VRP will optimize the condition to true. { ... } else { ... } // so the else branch could be determined to "not reachable" }
Comment #5 by braddr — 2014-07-02T00:19:22Z
--- Comment originally from [email protected] --- (In reply to Kenji Hara from comment #4) > By advancing the thought, compiler will be able to generate "statement is > not reachable" warning in else branch of the code. > > void test(ubyte n) > { > immutable int i = n; > if (i >= 0) // const-folding with VRP will optimize the condition to > true. > { ... } > else > { ... } // so the else branch could be determined to "not reachable" > } Looks nice I guess this will generate few nice warnings in Phobos and in D code around.
Comment #6 by braddr — 2014-07-02T00:20:18Z
--- Comment originally from [email protected] --- (In reply to Kenji Hara from comment #4) > By advancing the thought, compiler will be able to generate "statement is > not reachable" warning in else branch of the code. > > void test(ubyte n) > { > immutable int i = n; > if (i >= 0) // const-folding with VRP will optimize the condition to > true. > { ... } > else > { ... } // so the else branch could be determined to "not reachable" > } Such things could be a problem in templates, where the type is different in different instantiations. This causes a warning if you instantiate it with an T=uint: void foo(T)(T n) { if (n >= 0) { /*...*/ } else { /*...*/ } } void main() { foo(1); // OK foo(1u); // Causes a warning }
Comment #7 by code — 2014-07-02T18:08:49Z
I'm not sure whether this is worth the added language complexity. Do you have an example for a compelling use case?
Comment #8 by lio+bugzilla — 2015-02-28T14:25:06Z
(In reply to David Nadlinger from comment #7) > I'm not sure whether this is worth the added language complexity. Do you > have an example for a compelling use case? Statically testing the range of a variable: ubyte u; static assert(u >= 0);
Comment #9 by bearophile_hugs — 2015-02-28T14:36:10Z
(In reply to Lionello Lunesu from comment #8) This doesn't compile: ubyte x; void main() { immutable int y = x; ubyte z = y; static assert(y >= 0); } But this compiles, so the compiler knows statically y can't be negative: ubyte x; void main() { immutable int y = x; ubyte z = y; } So accepting that static assert seems a small improvement, perhaps it's just a matter of using the variable range knowledge inside static assert.
Comment #10 by code — 2015-02-28T14:37:44Z
(In reply to Lionello Lunesu from comment #8) > (In reply to David Nadlinger from comment #7) > > I'm not sure whether this is worth the added language complexity. Do you > > have an example for a compelling use case? > > Statically testing the range of a variable: > > ubyte u; > static assert(u >= 0); 1. That's hardly what I'd call a use case. It's a minimal snippet showing a consequence of the feature, but doesn't tell me why I would ever want to do this in the first place. 2. In this specific case, inspecting the type (isUnsigned) would be enough anyway.
Comment #11 by bearophile_hugs — 2015-02-28T14:38:07Z
Even this doesn't compile, but it should: void main() { ubyte x; static assert(x >= 0); }
Comment #12 by lio+bugzilla — 2015-02-28T15:12:28Z
(In reply to David Nadlinger from comment #10) > (In reply to Lionello Lunesu from comment #8) > > (In reply to David Nadlinger from comment #7) > > > I'm not sure whether this is worth the added language complexity. Do you > > > have an example for a compelling use case? > > > > Statically testing the range of a variable: > > > > ubyte u; > > static assert(u >= 0); > > 1. That's hardly what I'd call a use case. It's a minimal snippet showing a > consequence of the feature, but doesn't tell me why I would ever want to do > this in the first place. > > 2. In this specific case, inspecting the type (isUnsigned) would be enough > anyway. Fine: ubyte u; //<a lot of code> static assert(u < 9);
Comment #13 by bearophile_hugs — 2015-02-28T15:15:30Z
(In reply to Lionello Lunesu from comment #12) > ubyte u; > //<a lot of code> > static assert(u < 9); I don't understand the point of this code.
Comment #14 by robert.schadek — 2024-12-13T18:21:50Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18844 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB