Testing a new GCC warning to detect uses of pointers invalidated by a deallocation call exposed a few instances in Glibc. This is to make record of these ahead of submitting the new GCC warning for review. As best I can tell these are all true positives (using an indeterminate pointer in any expression, including but not limited to dereferencing it, is undefined), although the uses are in all likelihood benign. localealias.c: In function ‘read_alias_file’: localealias.c:335:56: warning: pointer may be used after ‘realloc’ [-Wuse-after-free=] 335 | map[i].alias += new_pool - string_space; | ~~~~~~~~~^~~~~~~~~~~~~~ localealias.c:325:49: note: call to ‘realloc’ here 325 | char *new_pool = (char *) realloc (string_space, new_size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ localealias.c:329:26: warning: pointer may be used after ‘realloc’ [-Wuse-after-free=] 329 | if (__builtin_expect (string_space != new_pool, 0)) | ^ localealias.c:325:49: note: call to ‘realloc’ here 325 | char *new_pool = (char *) realloc (string_space, new_size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ localealias.c:335:56: warning: pointer may be used after ‘realloc’ [-Wuse-after-free=] 335 | map[i].alias += new_pool - string_space; | ~~~~~~~~~^~~~~~~~~~~~~~ localealias.c:325:49: note: call to ‘realloc’ here 325 | char *new_pool = (char *) realloc (string_space, new_size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ localealias.c:329:26: warning: pointer may be used after ‘realloc’ [-Wuse-after-free=] 329 | if (__builtin_expect (string_space != new_pool, 0)) | ^ localealias.c:325:49: note: call to ‘realloc’ here 325 | char *new_pool = (char *) realloc (string_space, new_size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setenv.c: In function ‘__add_to_environ’: setenv.c:162:10: warning: pointer may be used after ‘realloc’ [-Wuse-after-free=] 162 | if (__environ != last_environ) | ^ setenv.c:154:31: note: call to ‘realloc’ here 154 | new_environ = (char **) realloc (last_environ, | ^~~~~~~~~~~~~~~~~~~~~~ 155 | (size + 2) * sizeof (char *)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setenv.c:162:10: warning: pointer may be used after ‘realloc’ [-Wuse-after-free=] 162 | if (__environ != last_environ) | ^ setenv.c:154:31: note: call to ‘realloc’ here 154 | new_environ = (char **) realloc (last_environ, | ^~~~~~~~~~~~~~~~~~~~~~ 155 | (size + 2) * sizeof (char *)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ldconfig.c: In function ‘manual_link’: ldconfig.c:739:6: warning: pointer ‘path’ may be used after ‘free’ [-Wuse-after-free=] 739 | if (path != real_path) | ^ ldconfig.c:738:3: note: call to ‘free’ here 738 | free (path); | ^~~~~~~~~~~ ldconfig.c:739:6: warning: pointer ‘path’ may be used after ‘free’ [-Wuse-after-free=] 739 | if (path != real_path) | ^ ldconfig.c:738:3: note: call to ‘free’ here 738 | free (path); | ^~~~~~~~~~~
Would it make sense to support the very common programming idiom for realloc as a GCC extension? That is, do not treat the original pointer (and pointers derived from it) after a successful realloc call as indeterminate? Without such an extension, calling realloc on any data structure with interior pointers (which point back into the allocation it self) is not possible.
The warning has three levels, with equality comparisons of indeterminate pointers triggers being diagnosed only in level 3. But remember, these are warnings, not hard errors: their purpose is to highlight potentially risky (or undefined) code. They don't make such code impossible, just like the "change oil" light in your car doesn't keep you from driving it. How users choose to handle them is up to them.
It turns out I already reported these problems in bug 26779. *** This bug has been marked as a duplicate of bug 26779 ***