There were segfaults on preprocess-only involving __has_attribute.
-MM and -E both bombed with __has_attribute.

Several codebases use __has_attribute this (because of clang).

This problem would have been found with the SD-6 macro __has_cpp_attribute as well so just taking out the extra macro is not the answer.

The answer is to provide the preprocessor pretty printer with a callback for has_attribute to match that of the lexer.

I don't know how "pretty" the output is but the thing doesn't crash and we can fix the output if needs be later on.

This patch builds and tests clean on x86_64-linux.

OK?

Ed

libcpp:

2014-11-13  Edward Smith-Rowland  <3dw...@verizon.net>

        * expr.c (parse_has_attribute): Only call pfile->cb.has_attribute
        if it is non-null.


gcc/c-family:

2014-11-13  Edward Smith-Rowland  <3dw...@verizon.net>

        * c-lex.c (cb_has_attribute): Remove old comment.
        * c-cppbuiltin.c (cb_has_attribute): New callback;
        (init_pp_output): Set it.


gcc/testsuite:

2014-11-13  Edward Smith-Rowland  <3dw...@verizon.net>

        * g++.dg/cpp1y/pr63831.C: New.
        * g++.dg/cpp1y/pr63831.h: New.
Index: libcpp/expr.c
===================================================================
--- libcpp/expr.c       (revision 217482)
+++ libcpp/expr.c       (working copy)
@@ -2162,7 +2162,10 @@
   result.high = 0;
   result.overflow = false;
 
-  result.low = pfile->cb.has_attribute (pfile);
+  if (pfile->cb.has_attribute)
+    result.low = pfile->cb.has_attribute (pfile);
+  else
+    result.low = 0;
 
   pfile->state.in__has_attribute__--;
 
Index: gcc/c-family/c-lex.c
===================================================================
--- gcc/c-family/c-lex.c        (revision 217482)
+++ gcc/c-family/c-lex.c        (working copy)
@@ -306,7 +306,6 @@
 
   if (token->type == CPP_NAME)
     {
-      //node = token->val.node.node;
       const cpp_token *nxt_token = cpp_peek_token (pfile, 0);
       if (c_dialect_cxx() && nxt_token->type == CPP_SCOPE)
        {
Index: gcc/c-family/c-ppoutput.c
===================================================================
--- gcc/c-family/c-ppoutput.c   (revision 217482)
+++ gcc/c-family/c-ppoutput.c   (working copy)
@@ -80,6 +80,7 @@
 static void cb_def_pragma (cpp_reader *, source_location);
 static void cb_read_pch (cpp_reader *pfile, const char *name,
                         int fd, const char *orig_name);
+static int cb_has_attribute (cpp_reader *);
 
 /* Preprocess and output.  */
 void
@@ -129,6 +130,8 @@
        }
     }
 
+  cb->has_attribute = cb_has_attribute;
+
   if (flag_dump_includes)
     cb->include  = cb_include;
 
@@ -510,6 +513,48 @@
     print.src_line++;
 }
 
+static int
+cb_has_attribute (cpp_reader * pfile)
+{
+  bool paren = false;
+  const cpp_token * token = cpp_get_token (pfile);
+
+  fputs ("__has_attribute__ ", print.outf);
+
+  if (token->type == CPP_OPEN_PAREN)
+    {
+      paren = true;
+      token = cpp_get_token (pfile);
+      putc ('(', print.outf);
+    }
+  if (token->type == CPP_NAME)
+    {
+      const cpp_token *nxt_token = cpp_peek_token (pfile, 0);
+      if (c_dialect_cxx() && nxt_token->type == CPP_SCOPE)
+       {
+         nxt_token = cpp_get_token (pfile); // Eat scope.
+         nxt_token = cpp_get_token (pfile);
+         if (nxt_token->type == CPP_NAME)
+           {
+             fprintf (print.outf, "%s::%s",
+                      cpp_token_as_text (pfile, token),
+                      cpp_token_as_text (pfile, nxt_token));
+           }
+       }
+      else
+       {
+         fprintf (print.outf, "%s", cpp_token_as_text (pfile, token));
+       }
+    }
+  if (paren)
+    {
+      cpp_get_token (pfile);
+      putc (')', print.outf);
+    }
+
+  return 0;
+}
+
 static void
 cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
          cpp_hashnode *node)
Index: gcc/testsuite/g++.dg/cpp1y/pr63831.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/pr63831.C        (revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/pr63831.C        (working copy)
@@ -0,0 +1,4 @@
+// { dg-do compile }
+// { dg-options "-I${srcdir}/g++.dg/cpp1y -MM" }
+
+#include <pr63831.h>
Index: gcc/testsuite/g++.dg/cpp1y/pr63831.h
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/pr63831.h        (revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/pr63831.h        (working copy)
@@ -0,0 +1,7 @@
+#ifndef __has_attribute
+#    define __has_attribute(x) 0
+#endif
+
+#if  __has_attribute(alloc_size)
+#   define U_ALLOC_SIZE_ATTR(X) __attribute__ ((alloc_size(X)))
+#endif

Reply via email to