[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 Andrew Macleod changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #9 from Andrew Macleod --- fixed.
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 --- Comment #8 from CVS Commits --- The master branch has been updated by Andrew Macleod : https://gcc.gnu.org/g:0409aa5a2de9ce3164933814a4a7adc91f6acb96 commit r13-6850-g0409aa5a2de9ce3164933814a4a7adc91f6acb96 Author: Andrew MacLeod Date: Thu Mar 23 10:28:34 2023 -0400 Ranger cache dominator queries should ignore backedges. When querying dominators for cache values, ignore back edges in read-only mode. PR tree-optimization/109238 gcc/ * gimple-range-cache.cc (ranger_cache::resolve_dom): Ignore predecessors which this block dominates. gcc/testsuite/ * gcc.dg/pr109238.c: New.
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #7 from Jakub Jelinek --- Reduced testcase: /* PR tree-optimization/10923 */ /* { dg-do compile } */ /* { dg-options "-O2 -Wall" } */ void foo (void) __attribute__((noreturn)); void bar (void *); void baz (void *p) { void *c = __builtin_realloc (p, 16); if (c) foo (); for (;;) bar (__builtin_realloc (p, 8)); /* { dg-bogus "pointer 'p' may be used after '__builtin_realloc'" } */ }
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 --- Comment #6 from Andrew Macleod --- Created attachment 54738 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54738&action=edit Patch to fix the issue Ah, sorry I missed that. OK, I traced it through. The problem turns out to be in the dom_resolve code. when we are trying to pick up a value via dominators, we walk the dominator chain looking for outgoing edges which change the value and/or existing values. As we find these values, will fill the on-entry cache so that future queries will be faster. When we encounter a dominator node that has multiple incoming edges, as BB 33 does, we separately ask for a "quick" read-only fill and accumulate each incoming edges values. this allows us to pick up things where ranges are adjusted on edges from non-dominator block ie bb2: if (foo) if (a < 10) goto A: else goto B; else if (a >= 10) goto C: else goto A: goto D: A: Block A's dominator is bb2. It has 2 predecessors however, and on each of those incoming edges, a has a range of [0, 10]. So by querying the outgoing range of a on each predecessor we come up with [0,10] for a range of A, which would not be possible simply by examining the dominator itself. This query is done in a read-only mode so we dont go polluting the cache with a bunch of things we may not need. Anyway, it all works swimmingly. usually. What happened in this case is BB 33 has 2 predecessors. BB 28 and BB 32. The edge from BB28 correctly picked up the range of ~[0,0], but the query for BB32 went wrong. BB32 is a back edge, and the query leads back to BB 33, and in read only mode, we do not deal with these multiple incoming edges.. (and it avoids an infinite loop).. so that query bails, and we end up with VARYING. that is what was generating the confusing output: CACHE: BB 32 DOM query for c_24, found [irange] unsigned char * VARYING at BB28 CACHE: Range for DOM returns : [irange] unsigned char * VARYING CACHE: Range for DOM returns : [irange] unsigned char * VARYING When we are doing this inferior DOM query in read-only like this like this, we do not need to incorporate anything from a back edge. Its intended to be pulling a value from dominators, and there is no additional information on that edge. Any values from that edge can only be subsets of what the other incoming edges have, and with the results being unioned... its pointless. I have not yet managed to produce a reduced testcase.
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 --- Comment #5 from Richard Biener --- (In reply to Andrew Macleod from comment #4) > I think varying is the correct result tho? the branch is in BB28, but bb > 33 is a merge poi9nt again before bb 36, so we can't tell that it is > anything but varying? > > I see: > > [local count: 428124]: > c_24 = realloc (p_17, 18446744073709551615); > if (c_24 != 0B) > goto ; [99.96%] > else > goto ; [0.04%] > >[local count: 427952]: > support_exit_failure_impl (1, "tst-realloc.c", 120, "realloc (p, -1) > succeeded."); ^^^ this is noreturn > >[local count: 2741]: > _26 = (sizetype) i_25; > _27 = p_17 + _26; > _28 = *_27; > if (_28 != 255) > goto ; [66.00%] > else > goto ; [34.00%] > >[local count: 1809]: > >[local count: 2741]: > # ok_48 = PHI > i_29 = i_25 + 1; > >[local count: 2912]: <<-- both sides of BB 28 branch > merge here, so c_24 is varying again > # i_25 = PHI <0(28), i_29(32)> > # ok_49 = PHI <1(28), ok_48(32)> > if (i_25 != 16) > goto ; [94.12%] > else > goto ; [5.88%] > >[local count: 171]: > # ok_30 = PHI > if (ok_30 == 0) > goto ; [0.04%] > else > goto ; [99.96%] > >[local count: 0]: > support_exit_failure_impl (1, "tst-realloc.c", 132, "first 16 bytes were > not correct after failed realloc"); likewise >[local count: 171]: > p_31 = realloc (p_17, 0); <<-- This is dominated by bb 33 which > merged the bb28 branch > > During the cache dump the bit about > CACHE: BB 32 DOM query for c_24, found [irange] unsigned char * VARYING at > BB28 > CACHE: Range for DOM returns : [irange] unsigned char * VARYING > CACHE: Range for DOM returns : [irange] unsigned char * VARYING > > Is a bit of a misnomer I think, its dumping in the middle of a query and > didnt show the fully updated value.. But I will look a bit closer at it.. > in theory that should have been non-zero, even tho I dont think it affects > the result. As said, the "error" calls are noreturn so the range should be [0,0] in BB36.
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 --- Comment #4 from Andrew Macleod --- I think varying is the correct result tho? the branch is in BB28, but bb 33 is a merge poi9nt again before bb 36, so we can't tell that it is anything but varying? I see: [local count: 428124]: c_24 = realloc (p_17, 18446744073709551615); if (c_24 != 0B) goto ; [99.96%] else goto ; [0.04%] [local count: 427952]: support_exit_failure_impl (1, "tst-realloc.c", 120, "realloc (p, -1) succeeded."); [local count: 2741]: _26 = (sizetype) i_25; _27 = p_17 + _26; _28 = *_27; if (_28 != 255) goto ; [66.00%] else goto ; [34.00%] [local count: 1809]: [local count: 2741]: # ok_48 = PHI i_29 = i_25 + 1; [local count: 2912]: <<-- both sides of BB 28 branch merge here, so c_24 is varying again # i_25 = PHI <0(28), i_29(32)> # ok_49 = PHI <1(28), ok_48(32)> if (i_25 != 16) goto ; [94.12%] else goto ; [5.88%] [local count: 171]: # ok_30 = PHI if (ok_30 == 0) goto ; [0.04%] else goto ; [99.96%] [local count: 0]: support_exit_failure_impl (1, "tst-realloc.c", 132, "first 16 bytes were not correct after failed realloc"); [local count: 171]: p_31 = realloc (p_17, 0); <<-- This is dominated by bb 33 which merged the bb28 branch During the cache dump the bit about CACHE: BB 32 DOM query for c_24, found [irange] unsigned char * VARYING at BB28 CACHE: Range for DOM returns : [irange] unsigned char * VARYING CACHE: Range for DOM returns : [irange] unsigned char * VARYING Is a bit of a misnomer I think, its dumping in the middle of a query and didnt show the fully updated value.. But I will look a bit closer at it.. in theory that should have been non-zero, even tho I dont think it affects the result.
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 Richard Biener changed: What|Removed |Added CC||amacleod at redhat dot com --- Comment #3 from Richard Biener --- For the given CFG where dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), gimple_bb (stmt)); and we have [local count: 428124]: c_24 = realloc (p_17, 18446744073709551615); if (c_24 != 0B) goto ; [99.96%] else goto ; [0.04%] .. on the 28->33 edge intermediate blocks, including a CFG cycle ... [local count: 171]: p_31 = realloc (p_17, 0); but range_of_expr (vr, c_24, use_stmt) doesn't give us [0,0], instead we get VARYING. It looks like we go range_of_stmt of the c_24 def and then m_cache.block_range has a VARYING entry range as well and then we're done. 176 range_of_expr(c_24) at stmt p_31 = realloc (p_17, 0); 177range_on_entry (c_24) to BB 36 178 range_of_stmt (c_24) at stmt c_24 = realloc (p_17, 18446744073709551615); GLOBAL : UPDATE cache for c_24 in BB 28 : successors : : No updates! TRUE : (178) range_of_stmt (c_24) [irange] unsigned char * VARYING c_24 : CACHE: BB 36 DOM query for c_24, found [irange] unsigned char * VARYING at BB28 179 GORI outgoing_edge for c_24 on edge 28->33 180 GORIcompute op 1 (c_24) at if (c_24 != 0B) GORI LHS =[irange] _Bool [0, 0] NONZERO 0x0 GORI Computes c_24 = [irange] unsigned char * [0, 0] NONZERO 0x0 intersect Known range : [irange] unsigned char * VARYING GORITRUE : (180) produces (c_24) [irange] unsigned char * [0, 0] NONZERO 0x0 GORI TRUE : (179) outgoing_edge (c_24) [irange] unsigned char * [0, 0] NONZERO 0x0 CACHE: BB 32 DOM query for c_24, found [irange] unsigned char * VARYING at BB28 CACHE: Range for DOM returns : [irange] unsigned char * VARYING CACHE: Range for DOM returns : [irange] unsigned char * VARYING Filled from dominator! : [irange] unsigned char * VARYING TRUE : (177) range_on_entry (c_24) [irange] unsigned char * VARYING TRUE : (176) range_of_expr (c_24) [irange] unsigned char * VARYING 181 range_of_expr(c_24) at stmt _27 = p_17 + _26; 182range_on_entry (c_24) to BB 30 183 range_of_stmt (c_24) at stmt c_24 = realloc (p_17, 18446744073709551615); TRUE : (183) cached (c_24) [irange] unsigned char * VARYING c_24 : CACHE: BB 30 DOM query for c_24, found [irange] unsigned char * VARYING at BB33 CACHE: Range for DOM returns : [irange] unsigned char * VARYING Filled from dominator! : [irange] unsigned char * VARYING TRUE : (182) range_on_entry (c_24) [irange] unsigned char * VARYING ... (not sure where relevant dumps stop). A reduced testcase like the following doesn't exhibit this issue - the range is successfully computed as [0,0] there. So to me this looks like a ranger issue? Andrew? #include int do_test(void *p) { unsigned char *c = realloc (p, -1); if (c != 0) abort (); c = p; int ok = 1; for (int i = 0; i < 16; i++) { if (c[i] != 0xff) ok = 0; } if (!ok) abort (); p = realloc (p, 0); if (p != NULL) abort (); return ok; }
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 Richard Biener changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Status|NEW |ASSIGNED --- Comment #2 from Richard Biener --- I will have a look.
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 --- Comment #1 from Andrew Pinski --- c = realloc (p, -1); ... ; if (c != ((void *)0) ) support_exit_failure_impl (1, "tst-realloc.c", 120, "realloc (p, -1) succeeded."); c = p; ... p = realloc (p, 0);
[Bug tree-optimization/109238] [13 Regression] tst-realloc.i:42:19: error: pointer ‘p’ may be used after ‘realloc’ [-Werror=use-after-free] in glibc tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109238 Martin Liška changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2023-03-21 See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=109170 Target Milestone|--- |13.0 Ever confirmed|0 |1