https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81721

            Bug ID: 81721
           Summary: precompiled header : internal compiler error:
                    Segmentation fault
           Product: gcc
           Version: 7.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: juro.bystricky at intel dot com
  Target Milestone: ---

Created attachment 41930
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41930&action=edit
symacros.h to corroborate the bug report

Given two simple files "precompiled.h" and "main.cpp" :

$ cat precompiled.h
#ifndef PRECOMPILED_H
#define PRECOMPILED_H

#include <algorithm>

#endif // PRECOMPILED_H


$ cat main.cpp 
#include "precompiled.h"

class Version {
public:
        void major() {}
};
int main(void){ return 0;}

The following sequence will generate a segmentation fault:

$ g++  -x c++-header precompiled.h
$ g++  -H main.cpp

main.cpp:5:2: internal compiler error: Segmentation fault
  void major() {}
  ^~~~
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.


In order to reproduce this, you also need to have /usr/include/sys/sysmacros.h
containing (file attached):

<snip...>
/* Caution: The text of this deprecation message is unquoted, so that
   #symbol can be substituted.  (It is converted to a string by
   __SYSMACROS_DM1.)  This means the message must be a sequence of
   complete pp-tokens; in particular, English contractions (it's,
   can't) cannot be used.

   The message has been manually word-wrapped to fit in 80 columns
   when output by GCC 5 and 6.  The first line is shorter to leave
   some room for the "foo.c:23: warning:" annotation.  */
#define __SYSMACROS_DM(symbol) __SYSMACROS_DM1 \
 (In the GNU C Library, #symbol is defined\n\
  by <sys/sysmacros.h>. For historical compatibility, it is\n\
  currently defined by <sys/types.h> as well, but we plan to\n\
  remove this soon.  To use #symbol, include <sys/sysmacros.h>\n\
  directly.  If you did not intend to use a system-defined macro\n\
  #symbol, you should undefine it after including <sys/types.h>.)

  <snip...>

After some debugging, I found the segmentation fault was caused in libcpp/lex.c
(cpp_spell_token):

  case SPELL_IDENT:
    if (forstring)
      {
      memcpy (buffer, NODE_NAME (token->val.node.spelling),
           NODE_LEN (token->val.node.spelling));
      buffer += NODE_LEN (token->val.node.spelling);
      }

In particular, the code barfs on NODE_NAME (token->val.node.spelling), because
the code implicitly assumes token->type == CPP_NAME.
However, the routine actually gets CPP_NOT (which we got from parsing
sysmacros.h "If you did not intend" sentence).

A ***very*** crude fix/POC is to do something like this in libcpp/lex.c:

  case SPELL_IDENT:
    if (forstring)
      {
        if (token->type == CPP_NAME)
          {
            memcpy (buffer, NODE_NAME (token->val.node.spelling),
                NODE_LEN (token->val.node.spelling));
            buffer += NODE_LEN (token->val.node.spelling);
          }
        if (token->type == CPP_NOT)
          {
            memcpy(buffer, "not", 3);
            buffer += 3;
            break;
          }     
    }

There is, of course, a more generic way to handle this for other token->types,
not just CPP_NOT, providing that token->types other than CPP_NAME are legal in
this routine/context and this is where the fix should be applied. 

BTW, there are two workarounds for this error, either pre-compile the headers
with -save-temps:

$ g++ -save-temps -x c++-header precompiled.h
$ g++ -H main.cpp

Or explicitly include #include <sys/types.h> before #include "precompiled.h"

We may get this instead:

main.cpp:5:13: warning: In the GNU C Library, "major" is defined
 by <sys/sysmacros.h>. For historical compatibility, it is
 currently defined by <sys/types.h> as well, but we plan to
 remove this soon. To use "major", include <sys/sysmacros.h>
 directly. If you did not intend to use a system-defined macro
 "major", you should undefine it after including <sys/types.h>.
  void major() {}
             ^~~~


(For more details please see
https://bugzilla.yoctoproject.org/show_bug.cgi?id=11738 )

Reply via email to