Make -preview=intpromote not suck
Steven Schveighoffer
schveiguy at gmail.com
Mon Oct 26 13:06:09 UTC 2020
For those who don't know, the current compiler does not integer promote
for negation. This means that typeof(-x) is typeof(x). This also means
that for things like short and byte:
short x = short.min; // -32768
int y = -x; // still -32768
ulong z = -x; // 18446744073709518848
In C (and in common sense), y and z are 32768.
So we have a new system, which integer-promotes a value from short or
byte to int *before* the negation.
However, this perfectly valid code will no longer work:
short x2 = -x;
Instead, you must *cast* the -x to short (and to get rid of the
deprecation, you must also cast the x to int before using - on it).
The annoying thing here is, this *buys you nothing*. Before the new
integer promotion rules, if x was short.min, x2 is short.min. After the
new integer promotion rules, with a cast, x2 is *still* short.min.
I think this one problem is going to cause us to never turn on the
intpromote rule by default. It will be insanely disruptive.
I have an idea to make this better. The true cases where integer
promotion is a problem is when you use the negation of a smaller type
implicitly as a larger type. Other than that, the differing rules
produce the same results.
I propose that the VRP state has a flag added indicating that the range
came from a negation directly (a cast or any other operations will
eliminate the flag). In the case where a value of a larger type VRP
range is assigned to a value that holds all of the range EXCEPT the
topmost value, and the negation flag is set, the assignment is allowed.
Otherwise, if it is assigned to a larger type, and the type's minimum is
in the VRP, then trigger the deprecation.
How this might look:
short x2 = -x;
Without -preview=intpromote:
-x has type short with VRP range short.min to short.max inclusive, and
negation flag set.
Assigning to a short works, because the VRP allows it. No warnings/errors.
With -preview=intpromote:
-x has type int with VRP range short.min + 1 to short.max + 1 inclusive,
and negation flag set.
Assigning to a short is allowed because of the new rule (if negation was
involved, then it's allowed to assign if the upper range is only one
higher than allowed).
int i = -x;
Without -preview=intpromote:
-x has type short with VRP range short.min to short.max inclusive, and
negation flag set.
Assigning to an int works, but triggers the deprecation because of the
negation flag, type being promoted implicitly, and the VRP includes
short.min.
With -preview=intpromote:
-x has type int with VRP range short.min + 1 to short.max + 1 inclusive,
and negation flag set.
Assigning to an int works, because int can hold all the values.
Does this make sense? I think it makes for a lot better targeted
diagnostic and problem fix.
-Steve
More information about the Digitalmars-d
mailing list