https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98396
Bug ID: 98396 Summary: gcc wrongly assumes that free preserves errno Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: bruno at clisp dot org Target Milestone: --- Created attachment 49808 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49808&action=edit Test case On POSIX systems, free() can clobber the value of errno. This is implied by 1) https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html which says: "The setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be modified." and 2) https://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html which does not mention errno. A future version of POSIX will specify that a valid call to free() preserves errno: https://www.austingroupbugs.net/view.php?id=385 . But this is not yet standard. In particular, on Linux/glibc systems, the glibc bug https://sourceware.org/bugzilla/show_bug.cgi?id=17924 is still open, because glibc does not guarantee that free() preserves errno — neither through the code nor through the documentation. This glibc bug even has a test case of a successful free() that sets errno to ENOMEM (via a call to munmap). But GCC, when optimizing, eliminates tests of errno or assignments to errno after 'free (ptr);' where ptr was the result of a malloc(...) call in the same function. How to reproduce: $ gcc -O2 -S foo.c Inspect the resulting foo.s. You see that - In function 'check_errno_unmodified', GCC has eliminated the lines if (errno != 1789) abort (); - In function 'ensure_errno_unmodified', GCC has eliminated the lines int saved_errno = errno; and errno = saved_errno; So, while the programmer knew that free() can clobber errno and added statements to ensure that errno gets preserved, GCC optimized these statements away!