https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104069
--- Comment #13 from Martin Sebor <msebor at gcc dot gnu.org> --- I confused things (including myself) yesterday, sorry. Let me try again, with just the -O2 behavior for the test case in comment #2: void *xrealloc (void *ptr, int size) { void *ret = __builtin_realloc (ptr, size); if (!ret && !size) ret = __builtin_realloc (ptr, 1); if (!ret) { ret = __builtin_realloc (ptr, size); if (!ret && !size) ret = __builtin_realloc(ptr, 1); if (!ret) __builtin_abort (); } return ret; } The optimized IL the warning works with is below. The warning is "pointer may be used after 'realloc'" because the ptr argument to the realloc calls in bb 2 and 5 is the same, and because bb 5 can't be ruled out to be entered after the call in bb 2 succeeds (i.e., when ret_17 is nonnull). The conditional in bb 2 is too complex. I don't see what the warning code alone could do about it but there are ways to avoid it. void * xrealloc (void * ptr, int size) { void * ret; long unsigned int _1; _Bool _2; _Bool _3; _Bool _4; _Bool _5; _Bool _6; <bb 2> [local count: 1073741824]: _1 = (long unsigned int) size_13(D); ret_17 = __builtin_realloc (ptr_15(D), _1); _2 = ret_17 == 0B; _3 = size_13(D) == 0; _4 = _2 & _3; if (_4 != 0) goto <bb 3>; [33.00%] >>> ret_17 may be nonnull else goto <bb 4>; [67.00%] >>> ret_17 may be nonnull <bb 3> [local count: 354334800]: ret_19 = __builtin_realloc (ptr_15(D), 1); <bb 4> [local count: 1073741824]: # ret_7 = PHI <ret_17(2), ret_19(3)> if (ret_7 == 0B) goto <bb 5>; [0.04%] >>> ret_17(2) == 0 || ret_19(3) == 0 else goto <bb 9>; [99.96%] <bb 5> [local count: 429496]: ret_21 = __builtin_realloc (ptr_15(D), _1); <<< -Wuse-after-free=2 because ret_17(2) may be nonnull _5 = ret_21 == 0B; _6 = _3 & _5; if (_6 != 0) goto <bb 6>; [33.00%] else goto <bb 7>; [67.00%]