On 4/11/25 11:36, Qing Zhao wrote:
On Apr 11, 2025, at 10:42, Andrew MacLeod <amacl...@redhat.com> wrote:
On 4/11/25 10:27, Qing Zhao wrote:
On Apr 10, 2025, at 11:12, Martin Uecker <uec...@tugraz.at> wrote:
Am Donnerstag, dem 10.04.2025 um 10:55 -0400 schrieb Siddhesh Poyarekar:
On 2025-04-10 10:50, Andrew MacLeod wrote:
Its not clear to me exactly what is being asked, but I think the
suggestion is that pointer references are being replaced with a builtin
function called .ACCESS_WITH_SIZE ? and I presume that builtin
function has some parameters that give you relevant range information of
some sort?
Added, not replaced, but yes, that's essentially it.
range-ops is setup to pull range information from builtin functions
already in gimple-range-op.cc::
gimple_range_op_handler::maybe_builtin_call (). We'd just need to write
a handler for this new one. You can pull information from 2 operands
under normal circumstances, but exceptions can be made. I'd need a
description of what it looks like and how that translates to range info.
That's perfect! It's probably redundant for cases where we end up with
both .ACCESS_WITH_SIZE and a __bos/__bdos call, but I don't remember if
that's the only place where .ACCESS_WITH_SIZE is generated today. Qing,
could you please work with Andrew on this?
BTW, what I would find very interesting is inserting such information
at the points where arrays decay to pointer.
Is the following the example?
1 #include <stdio.h>
2
3 void foo (int arr[]) {
4 // Inside the function, arr is treated as a pointer
5 arr[6] = 10;
6 }
7
8 int my_array[5] = {10, 20, 30, 40, 50};
9
10 int main() {
11 my_array[6] = 6;
12 int *ptr = my_array; // Array decays to pointer here
13 ptr[7] = 7;
14 foo (my_array);
15 16 return 0;
17 }
When I use the latest gcc to compile the above with -Warray-bounds:
[]$ gcc -O2 -Warray-bounds t.c
t.c: In function ‘main’:
t.c:13:6: warning: array subscript 7 is outside array bounds of ‘int[5]’
[-Warray-bounds=]
13 | ptr[7] = 7;
| ~~~^~~
t.c:8:5: note: at offset 28 into object ‘my_array’ of size 20
8 | int my_array[5] = {10, 20, 30, 40, 50};
| ^~~~~~~~
In function ‘foo’,
inlined from ‘main’ at t.c:14:3:
t.c:5:10: warning: array subscript 6 is outside array bounds of ‘int[5]’
[-Warray-bounds=]
5 | arr[6] = 10;
| ~~~~~~~^~~~
t.c: In function ‘main’:
t.c:8:5: note: at offset 24 into object ‘my_array’ of size 20
8 | int my_array[5] = {10, 20, 30, 40, 50};
| ^~~~~~~~
Looks like that even after the array decay to pointer, the bound information is
still carried
for the decayed pointer somehow (I guess that vrp did this?)
Just tried to disable tree-vrp by adding -fno-tree-vrp, all the above warnings
disappeared.
[]$ gcc -O2 -Warray-bounds -fno-tree-vrp t.c
[]$
Looks like tree-vrp tracks the bound information for this testing case.
tree vrp for pointers mostly tracks non-nullness, although it does
provide some range tweaks THe VRP pass itself does some points to , but
that info never escapes the VRP passes. It
No, the behaviour in these warnings is from something else. Although some range
info from VRP is used, most of this is tracked by the pointer_query
(pointer-query.cc) mechanism that was written a number of years ago before
ranger was completed. It attempts to do its own custom tracking of pointers
and what they point to and the size of things they access.
What’s the relationship between pointer_query and VRP? Is pointer_query part of
VRP? Disable VRP also disable pointer_query?
the pointer_query work is standalone and hacked on top of VRP ranges..
It attempts to track points-to and bounds information for memory refs so
it can be used to warn about potential issues. It then combines this
information with queries into VRP to determine access ranges and
compares them to what it thinks is valid.. It then makes some
decisions that depend on range patterns that were true when it was
written . For instance, if a range terminates with +INF, it usually
assumes VRP doesnt know anything about the range, and so therefore
elects not to warn because no range info is useful.
When ranger was turned on, we started producing more precise ranges.
Although there are many cases where we still don't really know anything
useful about the range, those patterns changed... ie, perhaps the range
is now [3, +INF - 4] .. so pointer-query code decides "This range does
not extend to +INF, so it must be good range info, and this access
might be out of bounds, so I better warn".
That is one of the reasons why turning VRP off makes some warning go
away, because without range into , most ranges will be [-INF, +INF] and
therefore the warning code doesnt trigger because it matches the pattern
of "the range doesn't tell us anything useful"
That being said, no one currently working on GCC really understands the
intricacies of this interaction.. The code is quite fragile and that is
why many of these warnings have not been fixed over the years. The
first step is to replace that code with something robust that we can
depend on, and then we can make better decisions about when to warn or
not. We had the enhanced pointer range class for ranger in the work
queue, but that person left last fall causing it to be delayed. It is
on my todo list, but I haven't gotten to it yet.
This is a gross simplification of the actual issue, but it is
representative of the root problem we need to solve.
thanks.
Qing
There are issues with that code, and the goal is to replace it with rangers
prange. Alas there is enhancement work to prange for that to happen as it
doesnt currently track and points to info. That would then be followed by
converting the warning code to then use ranger/VRP instead.
Any any adjustments to ranger for this are unlikely to affect anything until
that work is done, and I do not think anyone is equipped to attempt to update
the existing pointer-query code.
Unfortunately :-(
Andrew