This is the mail archive of the
mailing list for the GCC project.
anti-ranges of signed variables
- From: Martin Sebor <msebor at gmail dot com>
- To: GCC Mailing List <gcc at gcc dot gnu dot org>
- Date: Fri, 11 Nov 2016 10:34:37 -0700
- Subject: anti-ranges of signed variables
- Authentication-results: sourceware.org; auth=none
I noticed that variables of signed integer types that are constrained
to a specific subrange of values of the type like so:
[-TYPE_MAX + N, N]
are reported by get_range_info as the anti-range
[-TYPE_MAX, TYPE_MIN - 1]
for all positive N of the type regardless of the variable's actual
range. Basically, such variables are treated the same as variables
of the same type that have no range info associated with them at all
(such as function arguments or global variables).
For example, while a signed char variable between -1 and 126 is
VR_ANTI_RANGE [127, -2]
as one would expect, when the same variable is between -4 and 123
it's represented by
VR_ANTI_RANGE [128, -129]
rather than the expected
VR_ANTI_RANGE [124, -5]
I'd like to know if this is a deliberate feature or a bug. If it's
a feature, can and should it be relied on for all signed variables?
Or if it need not always hold, under what conditions, if any, might
it not hold?
I'm also curious why get_range_info returns VR_ANTI_RANGE for signed
variables with bounds of opposite signedness, and if it's something
that can be relied on. I.e., does an anti-range always imply that
the original variable (before being cast to an unsigned type as
often happens) is signed and its lower bound is negative?
I've gone through tree-ssa-vrp.[hc] to try to tease out answers to
these questions from the code but it looks too involved for me to
be confident that I haven't overlooked something.
PS I came across this while stepping through the code below in
the determine_block_size function in builtins.c:
void f (void *d, void *s, signed char n)
if (n < -4 || 123 < n) return;
memcpy (d, s, n);
The function tries to estimate the likely maximum block size for
the memcpy call and determines it to be 127 (i.e., SCHAR_MAX) in
this case. When the if statement is changed to this:
if (n < -4 || 122 < n) return;
it determines the likely maximum size to be 122 as I would expect.