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!

Reply via email to