Hi Berny, > hmm, I tried a couple of things like declaring the variable err as static. > The only combination I found to work is: > > diff --git a/lib/free.c b/lib/free.c > index 135c3eb..e923ee5 100644 > --- a/lib/free.c > +++ b/lib/free.c > @@ -27,7 +27,10 @@ void > rpl_free (void *p) > #undef free > { > - int err = errno; > + int err[2]; > + err[0] = errno; > + err[1] = errno; > + errno = 0; > free (p); > - errno = err; > + errno = err[errno==0]; > } > > It's slow and ugly. ;-(
It's not that slow. I like it :-) Installed as follows: 2021-01-03 Bruno Haible <br...@clisp.org> free-posix: Work around GCC mis-optimization bug. Code by Bernhard Voelker <m...@bernhard-voelker.de>. * lib/free.c (rpl_free): Add alternative complicated code for GCC. diff --git a/lib/free.c b/lib/free.c index 135c3eb..5c89787 100644 --- a/lib/free.c +++ b/lib/free.c @@ -27,7 +27,21 @@ void rpl_free (void *p) #undef free { +#if defined __GNUC__ && !defined __clang__ + /* An invalid GCC optimization + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98396> + would optimize away the assignments in the code below, when link-time + optimization (LTO) is enabled. Make the code more complicated, so that + GCC does not grok how to optimize it. */ + int err[2]; + err[0] = errno; + err[1] = errno; + errno = 0; + free (p); + errno = err[errno == 0]; +#else int err = errno; free (p); errno = err; +#endif }