1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

libast: Work around gcc optimiser bug for strdup() (rhbz#1221766)

Red Hat erratum: https://bugzilla.redhat.com/1221766
"Previously, the gcc utility optimized out a non-NULL test in the
ksh implementation of the strdup() function. This caused an
unexpected termination when ksh was executed in a clean chroot
environment. With this update, ksh compilation parameters have been
updated to prevent optimizing out a non-NULL test, and ksh no
longer crashes in clean chroot environments."

The optimizer bug occurs in that function's single-line body:

  return (s && (t = oldof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0;

So it must be the test for non-NULL 's' that fails. And 's' is
declared in the function definition, as follows:

  extern char*
  strdup(register const char* s)

So that makes me wonder if we can work around the bug by simply
removing the 'const' (and the 'register' while we're at it).
However, I have no easy way to verify that at the moment. The Red
Hat patch instead tells gcc to disable optimization for this
function using a #pragma directive.

I have no idea if that gcc optimiser bug has been fixed in the
meantime, but experience from c258a04f has shown that we cannot
trust that it has been fixed (that other optimizer bug is at least
a decade old and still not fixed). So, in it goes, until someone
shows evidence that we no longer need it.

Original patch:
642af4d6/f/ksh-20120801-badgcc.patch

src/lib/libast/string/strdup.c:
- Tell GCC to disable all optimisations for strdup().
This commit is contained in:
Martijn Dekker 2020-09-29 19:34:59 +02:00
parent 1477b5fff7
commit 7afb30e15c

View file

@ -50,6 +50,13 @@ __STDPP__directive pragma pp:nohide strdup
#define extern __EXPORT__ #define extern __EXPORT__
#endif #endif
/*
* Work around a null-test optimization bug in GCC.
* https://bugzilla.redhat.com/1221766
*/
#pragma GCC push_options
#pragma GCC optimize ("O0")
extern char* extern char*
strdup(register const char* s) strdup(register const char* s)
{ {
@ -58,3 +65,5 @@ strdup(register const char* s)
return (s && (t = oldof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0; return (s && (t = oldof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0;
} }
#pragma GCC pop_options