diff mbox

[PC,preprocessor/63831] - [5 Regression] r217292 causes segfaults with -MM

Message ID 5464F37B.8060903@verizon.net
State New
Headers show

Commit Message

Ed Smith-Rowland Nov. 13, 2014, 6:07 p.m. UTC
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  <3dw4rd@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  <3dw4rd@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  <3dw4rd@verizon.net>

	* g++.dg/cpp1y/pr63831.C: New.
	* g++.dg/cpp1y/pr63831.h: New.
diff mbox

Patch

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