Subject: Re: bug#31708: 'gcc-strmov-store-file-names.patch' causes GCC segfaults

From: Mark H Weaver <[email-masked]>
Date: Mon, 04 Jun 2018 21:00:37 -0400

[email-masked] (Ludovic Courtès) writes:

> On current ‘core-updates’, we have:
>
> $ readlink -f $(type -P gcc)
> /gnu/store/zrhwhlqqk51qslbddk4cip2z2p3fpvxd-gcc-5.5.0/bin/gcc
> ludo@ribbon /home/ludo/src/guix/+core-updates$ cat strmov-ice.c
> #define _GNU_SOURCE
> #include <string.h>
>
> void foo (char *x)
> {
>   static const char buf[12];
>   memcpy (x, buf, 12);
> }
> $ gcc -dH -O2 -Wall -c strmov-ice.c
> strmov-ice.c: In function ‘foo’:
> strmov-ice.c:7:3: internal compiler error: Segmentation fault
>    memcpy (x, buf, 12);
>    ^
> gcc: internal compiler error: Aborted (program cc1)

[...]

> This is because DECL_INITIAL returns NULL_TREE for ‘buf’, but
> ‘store_reference_p’ doesn’t check whether we got NULL_TREE.
>
> The fix is very simple (adding a NULL_TREE check), but in the meantime
> we need to work around it.
>
> A simple workaround is to pass an initializer to the static const array:
>
> $ cat strmov-ice.c
> #define _GNU_SOURCE
> #include <string.h>
>
> void foo (char *x)
> {
>   static const char buf[12] = { 0, };
>   memcpy (x, buf, 12);
> }
> $ gcc -dH -O2 -Wall -c strmov-ice.c
> $ echo $?
> 0
>
> The meaning of the program is unchanged but the bug is not triggered.

Thanks for tracking this down.  This explains why I've been seeing an
unusually large number of internal compiler errors in this core-updates
cycle.  It was a bit surprising since we used the same compiler in the
previous cycle, so I was wondering what might be causing it.

At the moment, the most pressing failure caused by this bug is 'doxygen'
on armhf, which causes GCC to crash deterministically in the same place
every time, with many important dependency failures.

  https://hydra.gnu.org/build/2669344

However, it's not obvious to me how best to work around the issue in
this case.  Here's the error message:

--8<---------------cut here---------------start------------->8---
[ 36%] Building CXX object qtools/CMakeFiles/qtools.dir/qutfcodec.cpp.o
cd /tmp/guix-build-doxygen-1.8.13.drv-0/build/qtools && /gnu/store/cd5q2pni1d95fs3cdabbclyh9hqhw2nq-gcc-5.5.0/bin/c++   -I/gnu/store/zjgd0wcbwxz8469skx5s83kibycf1n5p-glibc-2.27/include -I/tmp/guix-build-doxygen-1.8.13.drv-0/doxygen-1.8.13/qtools/.  -O2 -g -DNDEBUG   -o CMakeFiles/qtools.dir/qutfcodec.cpp.o -c /tmp/guix-build-doxygen-1.8.13.drv-0/doxygen-1.8.13/qtools/qutfcodec.cpp
/tmp/guix-build-doxygen-1.8.13.drv-0/doxygen-1.8.13/qtools/qutfcodec.cpp: In member function â€˜virtual QCString QUtf16Encoder::fromUnicode(const QString&, int&)â€™:
/tmp/guix-build-doxygen-1.8.13.drv-0/doxygen-1.8.13/qtools/qutfcodec.cpp:212:61: internal compiler error: Segmentation fault
      memcpy(d.rawData(),&QChar::byteOrderMark,sizeof(QChar));
                                                             ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make[2]: *** [qtools/CMakeFiles/qtools.dir/build.make:391: qtools/CMakeFiles/qtools.dir/qutfcodec.cpp.o] Error 1
--8<---------------cut here---------------end--------------->8---

Here's the declaration of QChar::byteOrderMark from qtools/qstring.h,
included in the doxygen tarball:

--8<---------------cut here---------------start------------->8---
class Q_EXPORT Q_PACKED QChar {
public:
    QChar();
    QChar( char c );
    QChar( uchar c );
    QChar( uchar c, uchar r );
    QChar( const QChar& c );
    QChar( ushort rc );
    QChar( short rc );
    QChar( uint rc );
    QChar( int rc );

    QT_STATIC_CONST QChar null;            // 0000
    QT_STATIC_CONST QChar replacement;     // FFFD
    QT_STATIC_CONST QChar byteOrderMark;     // FEFF
    QT_STATIC_CONST QChar byteOrderSwapped;     // FFFE
    QT_STATIC_CONST QChar nbsp;            // 00A0
--8<---------------cut here---------------end--------------->8---

and here's its definition, from qtools/qstring.cpp line 12179:

  QT_STATIC_CONST_IMPL QChar QChar::byteOrderMark((ushort)0xfeff);

Any suggestions?  I've managed to avoid working with C++ so far in this
millenium, so I'm a bit rusty.

     Mark