From 408d88af60e3268f7fad59fa393ec7e28922c435 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Aug 2021 22:38:18 +0200 Subject: [PATCH] libcpp: Fix ICE with -Wtraditional preprocessing [PR101638] The following testcase ICEs in cpp_sys_macro_p, because cpp_sys_macro_p is called for a builtin macro which doesn't use node->value.macro union member but a different one and so dereferencing it ICEs. As the testcase is distilled from contemporary glibc headers, it means basically -Wtraditional now ICEs on almost everything. The fix can be either the patch below, return true for builtin macros, or we could instead return false for builtin macros, or the fix could be also (untested): --- libcpp/expr.c 2021-05-07 10:34:46.345122608 +0200 +++ libcpp/expr.c 2021-08-12 09:54:01.837556365 +0200 @@ -783,13 +783,13 @@ cpp_classify_number (cpp_reader *pfile, /* Traditional C only accepted the 'L' suffix. Suppress warning about 'LL' with -Wno-long-long. */ - if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile)) + if (CPP_WTRADITIONAL (pfile)) { int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY)); int large = (result & CPP_N_WIDTH) == CPP_N_LARGE && CPP_OPTION (pfile, cpp_warn_long_long); - if (u_or_i || large) + if ((u_or_i || large) && ! cpp_sys_macro_p (pfile)) cpp_warning_with_line (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL, virtual_location, 0, "traditional C rejects the \"%.*s\" suffix", The builtin macros at least currently don't add any suffixes or numbers -Wtraditional would like to warn about. For floating point suffixes, -Wtraditional calls cpp_sys_macro_p only right away before emitting the warning, but in the above case the ICE is because cpp_sys_macro_p is called even if the number doesn't have any suffixes (that is I think always for builtin macros right now). 2021-08-12 Jakub Jelinek PR preprocessor/101638 * macro.c (cpp_sys_macro_p): Return true instead of crashing on builtin macros. * gcc.dg/cpp/pr101638.c: New test. --- gcc/testsuite/gcc.dg/cpp/pr101638.c | 7 +++++++ libcpp/macro.c | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/pr101638.c diff --git a/gcc/testsuite/gcc.dg/cpp/pr101638.c b/gcc/testsuite/gcc.dg/cpp/pr101638.c new file mode 100644 index 0000000..1030473 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pr101638.c @@ -0,0 +1,7 @@ +/* PR preprocessor/101638 */ +/* { dg-do preprocess } */ +/* { dg-options "-Wtraditional" } */ + +#define foo(attr) __has_attribute(attr) +#if foo(__deprecated__) +#endif diff --git a/libcpp/macro.c b/libcpp/macro.c index 4fc5f83..fab6779 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -3116,7 +3116,8 @@ cpp_get_token_with_location (cpp_reader *pfile, location_t *loc) /* Returns true if we're expanding an object-like macro that was defined in a system header. Just checks the macro at the top of - the stack. Used for diagnostic suppression. */ + the stack. Used for diagnostic suppression. + Also return true for builtin macros. */ int cpp_sys_macro_p (cpp_reader *pfile) { @@ -3127,7 +3128,11 @@ cpp_sys_macro_p (cpp_reader *pfile) else node = pfile->context->c.macro; - return node && node->value.macro && node->value.macro->syshdr; + if (!node) + return false; + if (cpp_builtin_macro_p (node)) + return true; + return node->value.macro && node->value.macro->syshdr; } /* Read each token in, until end of the current file. Directives are -- 2.7.4