I have this code in C11 (skipping references to pre-declared variables and functions):
// [...]
char *old_buf = it->buf;
shift += it->buf_size;
it->buf_size *= 2;
char *tmp = realloc (it->buf, it->buf_size);
if (!tmp) {
log_error ("Memory allocation error.");
return -1;
}
it->buf = tmp;
size_t reloc_off = it->buf - old_buf;
it->cur += reloc_off;
it->tok += reloc_off;
it->lim += reloc_off;
it->mar += reloc_off;
// [...]
GCC with -Wextra sends this warning:
parser_common.h:104:36: warning: pointer may be used after ‘realloc’ [-Wuse-after-free]
104 | size_t reloc_off = it->buf - old_buf;
| ~~~~~~~~^~~~~~~~~
parser_common.h:97:24: note: call to ‘realloc’ here
97 | char *tmp = realloc (it->buf, it->buf_size);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I would assume that it's safe to overwrite it->buf after I have verified that tmp is not NULL, and that until reassignment it->buf has become garbage.
Why the warning then? Is it benign or is there an actual risk?
EDIT: the reasoning for calculating the offset is that I have some markers on the old buffer, to mark relative positions in a text. The buffer is filled with user data and may need to be reallocated when the input is larger than the initial allocation, as I am doing here. When I do the reallocation, the markers need to be moved to their relative positions to the new buffer address.
reallocfails, the memory pointed to byit->bufwill still be valid (and needs to be passed tofreesooner or later). But the value ofit->buf_sizewill be wrong.old_buf, but I need to reference the old address to calculatereloc_offwithout actually using the data.old_bufmight not be valid any more, and you can't subtract pointers to different objects.realloc()doesn't move the buffer, in which case the offset is 0, or it moves it and you can't do the subtraction.