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