One of the pending issues that we should address before we release GCC 7 is that sometimes we don't issue a warning if the location points to a macro defined in a system header, unless -Wsystem-headers. Consider e.g. enum { e1 = LLONG_MIN };
or float_var = LLONG_MIN; Here, LLONG_MIN comes from a system header and so the compiler doesn't print any warnings even though it should--the problem is not in the macro itself, but in how it's used. This has happened before, e.g. with NULL, and the fix was to call expansion_point_location_if_in_system_header, but this strategy is not tenable; there are too many such issues. After having spent days on this it seems that we should always use the expansion location except for certain pedwarns/warnings--the challenge is of course how to distinguish which ones. This patch introduces expand_macros_sentinel that can be used to suppress expanding macros, removes various expansion_point_location_if_in_system_header calls and fixes testsuite fallout. I have *not* gone over all the warnings/pedwarns yet, because this is touch-and-go whether this'll be considered a reasonable approach. The general principle should be: is it the macro or its user that is responsible for the warning?, but in practice it was often less clear to me what to do. So e.g. imagine #define C : #define F i ?: 3 in a system header and then i = i ? C 5; // 1 return F; // 2 in user code -- I believe we should NOT warn for 2 (so don't expand the location), but that also means we won't warn for 1. Thoughts? Bootstrapped/regtested on x86_64-linux and ppc64-linux. 2016-11-02 Marek Polacek <pola...@redhat.com> PR c/78000 PR c/71613 gcc/c-family/ * c-common.c (unsafe_conversion_p): Don't call expansion_point_location_if_in_system_header. (c_cpp_error): Add a paramater and expand locations depending on that. * c-common.h (c_cpp_error): Update declaration. * c-warn.c (warnings_for_convert_and_check): Don't call expansion_point_location_if_in_system_header. gcc/c/ * c-decl.c (declspecs_add_type): Use expand_macros_sentinel to suppress expanding macro locations. * c-parser.c (c_parser_postfix_expression) [RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME]: Likewise. * c-typeck.c (convert_arguments): Don't call expansion_point_location_if_in_system_header. (pedwarn_init): Likewise. (warning_init): Likewise. (convert_for_assignment): Don't call expansion_point_location_if_in_system_header. (c_finish_return): Likewise. gcc/cp/ * call.c (conversion_null_warnings): Don't call expansion_point_location_if_in_system_header. * cvt.c (build_expr_type_conversion): Likewise. * parser.c (set_and_check_decl_spec_loc): Use expand_macros_sentinel to suppress expanding macro locations. * typeck.c (cp_build_binary_op): Don't call expansion_point_location_if_in_system_header. gcc/ * diagnostic.c (diagnostic_initialize): Initialize dc_expand_locations. (diagnostic_report_warnings_p): New function. * diagnostic.h (struct diagnostic_context): Add dc_expand_locations. (diagnostic_report_warnings_p): Remove. (struct expand_macros_sentinel): New sentinel. (diagnostic_report_warnings_p): Declare. * genmatch.c (error_cb): Add bool parameter. (fatal_at): Adjust error_cb call. (warning_at): Likewise. * input.c (on_error): Add bool parameter. gcc/fortran/ * cpp.c (cb_cpp_error): Add a paramater and expand locations depending on that. gcc/testsuite/ * gcc.dg/pr71613.c: New. * gcc.dg/pr78000.c: New. * gcc.dg/pr78000.h: New. libcpp/ * charset.c (noop_error_cb): Add bool parameter. (saved_error_handler): Likewise. (cpp_interpret_string_ranges): * errors.c (cpp_diagnostic_at_richloc): Adjust cb.error call. (cpp_diagnostic_at): Likewise. (cpp_diagnostic_with_line): Add bool parameter and pass it down to cb.error. (cpp_error_with_line_noexpand): New. (cpp_warning_with_line_noexpand): New. (cpp_pedwarning_with_line_noexpand): New. (cpp_warning_with_line_syshdr): Pass true to cpp_diagnostic_with_line. * expr.c (cpp_classify_number): Call *_noexpand variants. * include/cpplib.h (error): Adjust declaration. (cpp_error_with_line_noexpand): New. (cpp_warning_with_line_noexpand): New. (cpp_pedwarning_with_line_noexpand): New. diff --git gcc/gcc/c-family/c-common.c gcc/gcc/c-family/c-common.c index 307862b..b0a1b5c 100644 --- gcc/gcc/c-family/c-common.c +++ gcc/gcc/c-family/c-common.c @@ -1230,7 +1230,6 @@ unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns) { enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */ tree expr_type = TREE_TYPE (expr); - loc = expansion_point_location_if_in_system_header (loc); if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST) { @@ -6113,12 +6112,12 @@ c_option_controlling_cpp_error (int reason) bool c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, - rich_location *richloc, - const char *msg, va_list *ap) + rich_location *richloc, const char *msg, va_list *ap, bool expand) { diagnostic_info diagnostic; diagnostic_t dlevel; bool save_warn_system_headers = global_dc->dc_warn_system_headers; + bool save_expand_locations = global_dc->dc_expand_locations; bool ret; switch (level) @@ -6159,9 +6158,12 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, richloc, dlevel); diagnostic_override_option_index (&diagnostic, c_option_controlling_cpp_error (reason)); + if (!expand) + global_dc->dc_expand_locations = false; ret = report_diagnostic (&diagnostic); if (level == CPP_DL_WARNING_SYSHDR) global_dc->dc_warn_system_headers = save_warn_system_headers; + global_dc->dc_expand_locations = save_expand_locations; return ret; } diff --git gcc/gcc/c-family/c-common.h gcc/gcc/c-family/c-common.h index 547bab2..b0153b2 100644 --- gcc/gcc/c-family/c-common.h +++ gcc/gcc/c-family/c-common.h @@ -1010,7 +1010,7 @@ extern void init_c_lex (void); extern void c_cpp_builtins (cpp_reader *); extern void c_cpp_builtins_optimize_pragma (cpp_reader *, tree, tree); extern bool c_cpp_error (cpp_reader *, int, int, rich_location *, - const char *, va_list *) + const char *, va_list *, bool) ATTRIBUTE_GCC_DIAG(5,0); extern int c_common_has_attribute (cpp_reader *); diff --git gcc/gcc/c-family/c-warn.c gcc/gcc/c-family/c-warn.c index 904f6d3..0abb896 100644 --- gcc/gcc/c-family/c-warn.c +++ gcc/gcc/c-family/c-warn.c @@ -1002,8 +1002,6 @@ void warnings_for_convert_and_check (location_t loc, tree type, tree expr, tree result) { - loc = expansion_point_location_if_in_system_header (loc); - if (TREE_CODE (expr) == INTEGER_CST && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) diff --git gcc/gcc/c/c-decl.c gcc/gcc/c/c-decl.c index 3e1b7a4..23fc489 100644 --- gcc/gcc/c/c-decl.c +++ gcc/gcc/c/c-decl.c @@ -9834,6 +9834,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, "declaration specifiers")); break; } + expand_macros_sentinel e; pedwarn_c90 (loc, OPT_Wlong_long, "ISO C90 does not support %<long long%>"); specs->long_long_p = 1; diff --git gcc/gcc/c/c-parser.c gcc/gcc/c/c-parser.c index 6bc42da..0591534 100644 --- gcc/gcc/c/c-parser.c +++ gcc/gcc/c/c-parser.c @@ -7749,32 +7749,41 @@ c_parser_postfix_expression (c_parser *parser) switch (c_parser_peek_token (parser)->keyword) { case RID_FUNCTION_NAME: - pedwarn (loc, OPT_Wpedantic, "ISO C does not support " - "%<__FUNCTION__%> predefined identifier"); - expr.value = fname_decl (loc, - c_parser_peek_token (parser)->keyword, - c_parser_peek_token (parser)->value); - set_c_expr_source_range (&expr, loc, loc); - c_parser_consume_token (parser); - break; + { + expand_macros_sentinel e; + pedwarn (loc, OPT_Wpedantic, "ISO C does not support " + "%<__FUNCTION__%> predefined identifier"); + expr.value = fname_decl (loc, + c_parser_peek_token (parser)->keyword, + c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); + c_parser_consume_token (parser); + break; + } case RID_PRETTY_FUNCTION_NAME: - pedwarn (loc, OPT_Wpedantic, "ISO C does not support " - "%<__PRETTY_FUNCTION__%> predefined identifier"); - expr.value = fname_decl (loc, - c_parser_peek_token (parser)->keyword, - c_parser_peek_token (parser)->value); - set_c_expr_source_range (&expr, loc, loc); - c_parser_consume_token (parser); - break; + { + expand_macros_sentinel e; + pedwarn (loc, OPT_Wpedantic, "ISO C does not support " + "%<__PRETTY_FUNCTION__%> predefined identifier"); + expr.value = fname_decl (loc, + c_parser_peek_token (parser)->keyword, + c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); + c_parser_consume_token (parser); + break; + } case RID_C99_FUNCTION_NAME: - pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support " - "%<__func__%> predefined identifier"); - expr.value = fname_decl (loc, - c_parser_peek_token (parser)->keyword, - c_parser_peek_token (parser)->value); - set_c_expr_source_range (&expr, loc, loc); - c_parser_consume_token (parser); - break; + { + expand_macros_sentinel e; + pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support " + "%<__func__%> predefined identifier"); + expr.value = fname_decl (loc, + c_parser_peek_token (parser)->keyword, + c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); + c_parser_consume_token (parser); + break; + } case RID_VA_ARG: { location_t start_loc = loc; diff --git gcc/gcc/c/c-typeck.c gcc/gcc/c/c-typeck.c index f0917ed..f911f01 100644 --- gcc/gcc/c/c-typeck.c +++ gcc/gcc/c/c-typeck.c @@ -3270,8 +3270,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, position 0. */ location_t ploc = !arg_loc.is_empty () && values->length () == arg_loc.length () - ? expansion_point_location_if_in_system_header (arg_loc[parmnum]) - : input_location; + ? arg_loc[parmnum] : input_location; if (type == void_type_node) { @@ -6002,16 +6001,11 @@ pedwarn_init (location_t loc, int opt, const char *gmsgid) char *ofwhat; bool warned; - /* Use the location where a macro was expanded rather than where - it was defined to make sure macros defined in system headers - but used incorrectly elsewhere are diagnosed. */ - source_location exploc = expansion_point_location_if_in_system_header (loc); - /* The gmsgid may be a format string with %< and %>. */ - warned = pedwarn (exploc, opt, gmsgid); + warned = pedwarn (loc, opt, gmsgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat && warned) - inform (exploc, "(near initialization for %qs)", ofwhat); + inform (loc, "(near initialization for %qs)", ofwhat); } /* Issue a warning for a bad initializer component. @@ -6026,16 +6020,11 @@ warning_init (location_t loc, int opt, const char *gmsgid) char *ofwhat; bool warned; - /* Use the location where a macro was expanded rather than where - it was defined to make sure macros defined in system headers - but used incorrectly elsewhere are diagnosed. */ - source_location exploc = expansion_point_location_if_in_system_header (loc); - /* The gmsgid may be a format string with %< and %>. */ - warned = warning_at (exploc, opt, gmsgid); + warned = warning_at (loc, opt, gmsgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat && warned) - inform (exploc, "(near initialization for %qs)", ofwhat); + inform (loc, "(near initialization for %qs)", ofwhat); } /* If TYPE is an array type and EXPR is a parenthesized string @@ -6092,10 +6081,6 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, tree rname = NULL_TREE; bool objc_ok = false; - /* Use the expansion point location to handle cases such as user's - function returning a wrong-type macro defined in a system header. */ - location = expansion_point_location_if_in_system_header (location); - if (errtype == ic_argpass) { tree selector; @@ -9770,12 +9755,8 @@ c_finish_return (location_t loc, tree retval, tree origtype) bool npc = false; size_t rank = 0; - /* Use the expansion point to handle cases such as returning NULL - in a function returning void. */ - source_location xloc = expansion_point_location_if_in_system_header (loc); - if (TREE_THIS_VOLATILE (current_function_decl)) - warning_at (xloc, 0, + warning_at (loc, 0, "function declared %<noreturn%> has a %<return%> statement"); if (flag_cilkplus && contains_array_notation_expr (retval)) @@ -9838,11 +9819,11 @@ c_finish_return (location_t loc, tree retval, tree origtype) bool warned_here; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) warned_here = pedwarn - (xloc, 0, + (loc, 0, "%<return%> with a value, in function returning void"); else warned_here = pedwarn - (xloc, OPT_Wpedantic, "ISO C forbids " + (loc, OPT_Wpedantic, "ISO C forbids " "%<return%> with expression, in function returning void"); if (warned_here) inform (DECL_SOURCE_LOCATION (current_function_decl), diff --git gcc/gcc/cp/call.c gcc/gcc/cp/call.c index 4c19d2f..f9e0c9a 100644 --- gcc/gcc/cp/call.c +++ gcc/gcc/cp/call.c @@ -6413,15 +6413,12 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum) if (expr == null_node && TREE_CODE (totype) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (totype)) { - source_location loc = - expansion_point_location_if_in_system_header (input_location); - if (fn) - warning_at (loc, OPT_Wconversion_null, + warning_at (input_location, OPT_Wconversion_null, "passing NULL to non-pointer argument %P of %qD", argnum, fn); else - warning_at (loc, OPT_Wconversion_null, + warning_at (input_location, OPT_Wconversion_null, "converting to non-pointer type %qT from NULL", totype); } diff --git gcc/gcc/cp/cvt.c gcc/gcc/cp/cvt.c index 2f5f15a..66266e0 100644 --- gcc/gcc/cp/cvt.c +++ gcc/gcc/cp/cvt.c @@ -1647,13 +1647,8 @@ build_expr_type_conversion (int desires, tree expr, bool complain) if (expr == null_node && (desires & WANT_INT) && !(desires & WANT_NULL)) - { - source_location loc = - expansion_point_location_if_in_system_header (input_location); - - warning_at (loc, OPT_Wconversion_null, - "converting NULL to non-pointer type"); - } + warning_at (input_location, OPT_Wconversion_null, + "converting NULL to non-pointer type"); if (basetype == error_mark_node) return error_mark_node; diff --git gcc/gcc/cp/parser.c gcc/gcc/cp/parser.c index e443648..32857b9 100644 --- gcc/gcc/cp/parser.c +++ gcc/gcc/cp/parser.c @@ -27259,6 +27259,7 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs, "%<long long long%> is too long for GCC"); else { + expand_macros_sentinel e; decl_specs->locations[ds_long_long] = location; pedwarn_cxx98 (location, OPT_Wlong_long, diff --git gcc/gcc/cp/typeck.c gcc/gcc/cp/typeck.c index 569442f..2f01f62 100644 --- gcc/gcc/cp/typeck.c +++ gcc/gcc/cp/typeck.c @@ -4202,12 +4202,7 @@ cp_build_binary_op (location_t location, || (!null_ptr_cst_p (orig_op1) && !TYPE_PTR_OR_PTRMEM_P (type1))) && (complain & tf_warning)) - { - source_location loc = - expansion_point_location_if_in_system_header (input_location); - - warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic"); - } + warning_at (input_location, OPT_Wpointer_arith, "NULL used in arithmetic"); /* In case when one of the operands of the binary operation is a vector and another is a scalar -- convert scalar to vector. */ diff --git gcc/gcc/diagnostic.c gcc/gcc/diagnostic.c index 2304e14..c523d2d 100644 --- gcc/gcc/diagnostic.c +++ gcc/gcc/diagnostic.c @@ -163,6 +163,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts) context->fatal_errors = false; context->dc_inhibit_warnings = false; context->dc_warn_system_headers = false; + context->dc_expand_locations = true; context->max_errors = 0; context->internal_error = NULL; diagnostic_starter (context) = default_diagnostic_starter; @@ -785,6 +786,22 @@ print_parseable_fixits (pretty_printer *pp, rich_location *richloc) } } + +/* Returns nonzero if warnings should be emitted. */ + +bool +diagnostic_report_warnings_p (diagnostic_context *dc, location_t loc) +{ + /* Use the location where a macro was expanded rather than where + it was defined to make sure macros defined in system headers + but used incorrectly elsewhere are diagnosed. */ + if (dc->dc_expand_locations) + loc = expansion_point_location_if_in_system_header (loc); + + return (!dc->dc_inhibit_warnings + && !(in_system_header_at (loc) && !dc->dc_warn_system_headers)); +} + /* Report a diagnostic message (an error or a warning) as specified by DC. This function is *the* subroutine in terms of which front-ends should implement their specific diagnostic handling modules. The diff --git gcc/gcc/diagnostic.h gcc/gcc/diagnostic.h index ead4d2a..c448059 100644 --- gcc/gcc/diagnostic.h +++ gcc/gcc/diagnostic.h @@ -142,6 +142,9 @@ struct diagnostic_context /* True if warnings should be given in system headers. */ bool dc_warn_system_headers; + /* True if locations should be expanded. */ + bool dc_expand_locations; + /* Maximum number of errors to report. */ unsigned int max_errors; @@ -273,11 +276,6 @@ extern diagnostic_context *global_dc; /* Similarly, but for sorrys. */ #define sorrycount diagnostic_kind_count (global_dc, DK_SORRY) -/* Returns nonzero if warnings should be emitted. */ -#define diagnostic_report_warnings_p(DC, LOC) \ - (!(DC)->dc_inhibit_warnings \ - && !(in_system_header_at (LOC) && !(DC)->dc_warn_system_headers)) - #define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D) /* Override the option index to be used for reporting a @@ -285,6 +283,22 @@ extern diagnostic_context *global_dc; #define diagnostic_override_option_index(DI, OPTIDX) \ ((DI)->option_index = (OPTIDX)) +/* RAII sentinel to handle (not) expanding macros when needed. */ + +struct expand_macros_sentinel +{ + bool saved; + expand_macros_sentinel () + : saved (global_dc->dc_expand_locations) + { + global_dc->dc_expand_locations = false; + } + ~expand_macros_sentinel () + { + global_dc->dc_expand_locations = saved; + } +}; + /* Diagnostic related functions. */ extern void diagnostic_initialize (diagnostic_context *, int); extern void diagnostic_color_init (diagnostic_context *, int value = -1); @@ -293,6 +307,7 @@ extern void diagnostic_report_current_module (diagnostic_context *, location_t); extern void diagnostic_show_locus (diagnostic_context *, rich_location *richloc, diagnostic_t diagnostic_kind); +extern bool diagnostic_report_warnings_p (diagnostic_context *, location_t); /* Force diagnostics controlled by OPTIDX to be kind KIND. */ extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *, diff --git gcc/gcc/fortran/cpp.c gcc/gcc/fortran/cpp.c index 8ac8092..0a16f12 100644 --- gcc/gcc/fortran/cpp.c +++ gcc/gcc/fortran/cpp.c @@ -143,7 +143,7 @@ static void cb_ident (cpp_reader *, source_location, const cpp_string *); static void cb_used_define (cpp_reader *, source_location, cpp_hashnode *); static void cb_used_undef (cpp_reader *, source_location, cpp_hashnode *); static bool cb_cpp_error (cpp_reader *, int, int, rich_location *, - const char *, va_list *) + const char *, va_list *, bool) ATTRIBUTE_GCC_DIAG(5,0); void pp_dir_change (cpp_reader *, const char *); @@ -1025,11 +1025,12 @@ cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED, static bool cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, rich_location *richloc, - const char *msg, va_list *ap) + const char *msg, va_list *ap, bool expand) { diagnostic_info diagnostic; diagnostic_t dlevel; bool save_warn_system_headers = global_dc->dc_warn_system_headers; + bool save_expand_locations = global_dc->dc_expand_locations; bool ret; switch (level) @@ -1062,9 +1063,12 @@ cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, richloc, dlevel); if (reason == CPP_W_WARNING_DIRECTIVE) diagnostic_override_option_index (&diagnostic, OPT_Wcpp); + if (!expand) + global_dc->dc_expand_locations = false; ret = report_diagnostic (&diagnostic); if (level == CPP_DL_WARNING_SYSHDR) global_dc->dc_warn_system_headers = save_warn_system_headers; + global_dc->dc_expand_locations = save_expand_locations; return ret; } diff --git gcc/gcc/genmatch.c gcc/gcc/genmatch.c index b14034d..4be9931 100644 --- gcc/gcc/genmatch.c +++ gcc/gcc/genmatch.c @@ -73,7 +73,7 @@ static bool __attribute__((format (printf, 5, 0))) #endif error_cb (cpp_reader *, int errtype, int, rich_location *richloc, - const char *msg, va_list *ap) + const char *msg, va_list *ap, bool) { const line_map_ordinary *map; source_location location = richloc->get_loc (); @@ -121,7 +121,7 @@ fatal_at (const cpp_token *tk, const char *msg, ...) rich_location richloc (line_table, tk->src_loc); va_list ap; va_start (ap, msg); - error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap); + error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap, true); va_end (ap); } @@ -134,7 +134,7 @@ fatal_at (source_location loc, const char *msg, ...) rich_location richloc (line_table, loc); va_list ap; va_start (ap, msg); - error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap); + error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap, true); va_end (ap); } @@ -147,7 +147,7 @@ warning_at (const cpp_token *tk, const char *msg, ...) rich_location richloc (line_table, tk->src_loc); va_list ap; va_start (ap, msg); - error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap); + error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap, true); va_end (ap); } @@ -160,7 +160,7 @@ warning_at (source_location loc, const char *msg, ...) rich_location richloc (line_table, loc); va_list ap; va_start (ap, msg); - error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap); + error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap, true); va_end (ap); } diff --git gcc/gcc/input.c gcc/gcc/input.c index c2042e8..e3bf57f 100644 --- gcc/gcc/input.c +++ gcc/gcc/input.c @@ -2002,7 +2002,7 @@ class ebcdic_execution_charset : public lexer_test_options int level ATTRIBUTE_UNUSED, int reason ATTRIBUTE_UNUSED, rich_location *richloc ATTRIBUTE_UNUSED, - const char *msgid, va_list *ap ATTRIBUTE_UNUSED) + const char *msgid, va_list *ap ATTRIBUTE_UNUSED, bool) ATTRIBUTE_FPTR_PRINTF(5,0) { gcc_assert (s_singleton); diff --git gcc/gcc/testsuite/gcc.dg/.pr67730.c.swp gcc/gcc/testsuite/gcc.dg/.pr67730.c.swp index e69de29..dd35600 100644 Binary files gcc/gcc/testsuite/gcc.dg/.pr67730.c.swp and gcc/gcc/testsuite/gcc.dg/.pr67730.c.swp differ diff --git gcc/gcc/testsuite/gcc.dg/pr71613.c gcc/gcc/testsuite/gcc.dg/pr71613.c index e69de29..581a521 100644 --- gcc/gcc/testsuite/gcc.dg/pr71613.c +++ gcc/gcc/testsuite/gcc.dg/pr71613.c @@ -0,0 +1,14 @@ +/* Don't suppress the warning here even though LLONG_MIN comes from + a system header. */ +/* PR c/71613 */ +/* { dg-do compile } */ +/* { dg-options "-Wpedantic" } */ + +#include <limits.h> + +void +f (void) +{ + enum { e1 = LLONG_MIN }; /* { dg-warning "ISO C restricts enumerator values" } */ + enum { e2 = +LLONG_MIN }; /* { dg-warning "ISO C restricts enumerator values" } */ +} diff --git gcc/gcc/testsuite/gcc.dg/pr78000.c gcc/gcc/testsuite/gcc.dg/pr78000.c index e69de29..0d0ce06 100644 --- gcc/gcc/testsuite/gcc.dg/pr78000.c +++ gcc/gcc/testsuite/gcc.dg/pr78000.c @@ -0,0 +1,11 @@ +/* PR c/78000 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +#include "pr78000.h" + +int +main () +{ + foo (42); /* { dg-warning "implicit declaration" } */ +} diff --git gcc/gcc/testsuite/gcc.dg/pr78000.h gcc/gcc/testsuite/gcc.dg/pr78000.h index e69de29..2319e45 100644 --- gcc/gcc/testsuite/gcc.dg/pr78000.h +++ gcc/gcc/testsuite/gcc.dg/pr78000.h @@ -0,0 +1,2 @@ +#pragma GCC system_header +#define foo bar diff --git gcc/libcpp/charset.c gcc/libcpp/charset.c index e77270a..63a7ae0 100644 --- gcc/libcpp/charset.c +++ gcc/libcpp/charset.c @@ -1688,7 +1688,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, static bool noop_error_cb (cpp_reader *, int, int, rich_location *, - const char *, va_list *) + const char *, va_list *, bool) { /* no-op. */ return true; @@ -1734,7 +1734,7 @@ cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from, If an error does occur, we should see it via the return value of cpp_interpret_string_1. */ bool (*saved_error_handler) (cpp_reader *, int, int, rich_location *, - const char *, va_list *) + const char *, va_list *, bool) ATTRIBUTE_FPTR_PRINTF(5,0); saved_error_handler = pfile->cb.error; diff --git gcc/libcpp/errors.c gcc/libcpp/errors.c index 3b0a0b4..64e089b 100644 --- gcc/libcpp/errors.c +++ gcc/libcpp/errors.c @@ -39,7 +39,8 @@ cpp_diagnostic_at_richloc (cpp_reader * pfile, int level, int reason, if (!pfile->cb.error) abort (); - ret = pfile->cb.error (pfile, level, reason, richloc, _(msgid), ap); + ret = pfile->cb.error (pfile, level, reason, richloc, _(msgid), ap, + /*expand=*/true); return ret; } @@ -57,7 +58,8 @@ cpp_diagnostic_at (cpp_reader * pfile, int level, int reason, if (!pfile->cb.error) abort (); rich_location richloc (pfile->line_table, src_loc); - ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap); + ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap, + /*expand=*/true); return ret; } @@ -162,7 +164,7 @@ ATTRIBUTE_FPTR_PRINTF(6,0) static bool cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason, source_location src_loc, unsigned int column, - const char *msgid, va_list *ap) + const char *msgid, va_list *ap, bool expand) { bool ret; @@ -171,7 +173,8 @@ cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason, rich_location richloc (pfile->line_table, src_loc); if (column) richloc.override_column (column); - ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap); + ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap, + expand); return ret; } @@ -189,7 +192,27 @@ cpp_error_with_line (cpp_reader *pfile, int level, va_start (ap, msgid); ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc, - column, msgid, &ap); + column, msgid, &ap, true); + + va_end (ap); + return ret; +} + +/* Print a warning or error, depending on the value of LEVEL. Do not + expand the location. */ + +bool +cpp_error_with_line_noexpand (cpp_reader *pfile, int level, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc, + column, msgid, &ap, false); va_end (ap); return ret; @@ -208,7 +231,27 @@ cpp_warning_with_line (cpp_reader *pfile, int reason, va_start (ap, msgid); ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc, - column, msgid, &ap); + column, msgid, &ap, true); + + va_end (ap); + return ret; +} + +/* Print a warning. The warning reason may be given in REASON. Do not + expand the location. */ + +bool +cpp_warning_with_line_noexpand (cpp_reader *pfile, int reason, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc, + column, msgid, &ap, false); va_end (ap); return ret; @@ -227,7 +270,27 @@ cpp_pedwarning_with_line (cpp_reader *pfile, int reason, va_start (ap, msgid); ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc, - column, msgid, &ap); + column, msgid, &ap, true); + + va_end (ap); + return ret; +} + +/* Print a pedantic warning. The warning reason may be given in REASON. Do not + expand the location. */ + +bool +cpp_pedwarning_with_line_noexpand (cpp_reader *pfile, int reason, + source_location src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc, + column, msgid, &ap, false); va_end (ap); return ret; @@ -247,7 +310,7 @@ cpp_warning_with_line_syshdr (cpp_reader *pfile, int reason, va_start (ap, msgid); ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc, - column, msgid, &ap); + column, msgid, &ap, true); va_end (ap); return ret; diff --git gcc/libcpp/expr.c gcc/libcpp/expr.c index 61bc1b2..99b9f30 100644 --- gcc/libcpp/expr.c +++ gcc/libcpp/expr.c @@ -766,11 +766,11 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, : N_("use of C99 long long integer constant"); if (CPP_OPTION (pfile, c99)) - cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location, - 0, message); + cpp_warning_with_line_noexpand (pfile, CPP_W_LONG_LONG, + virtual_location, 0, message); else - cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG, - virtual_location, 0, message); + cpp_pedwarning_with_line_noexpand (pfile, CPP_W_LONG_LONG, + virtual_location, 0, message); } result |= CPP_N_INTEGER; @@ -778,16 +778,16 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, syntax_ok: if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile)) - cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, - "imaginary constants are a GCC extension"); + cpp_error_with_line_noexpand (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "imaginary constants are a GCC extension"); if (radix == 2 && !CPP_OPTION (pfile, binary_constants) && CPP_PEDANTIC (pfile)) - cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, - CPP_OPTION (pfile, cplusplus) - ? N_("binary constants are a C++14 feature " - "or GCC extension") - : N_("binary constants are a GCC extension")); + cpp_error_with_line_noexpand (pfile, CPP_DL_PEDWARN, virtual_location, 0, + CPP_OPTION (pfile, cplusplus) + ? N_("binary constants are a C++14 feature " + "or GCC extension") + : N_("binary constants are a GCC extension")); if (radix == 10) result |= CPP_N_DECIMAL; diff --git gcc/libcpp/include/cpplib.h gcc/libcpp/include/cpplib.h index 0781c09..2971ed7 100644 --- gcc/libcpp/include/cpplib.h +++ gcc/libcpp/include/cpplib.h @@ -580,7 +580,7 @@ struct cpp_callbacks /* Called to emit a diagnostic. This callback receives the translated message. */ bool (*error) (cpp_reader *, int, int, rich_location *, - const char *, va_list *) + const char *, va_list *, bool) ATTRIBUTE_FPTR_PRINTF(5,0); /* Callbacks for when a macro is expanded, or tested (whether @@ -1067,12 +1067,22 @@ extern bool cpp_errno_filename (cpp_reader *, int, const char *filename, extern bool cpp_error_with_line (cpp_reader *, int, source_location, unsigned, const char *msgid, ...) ATTRIBUTE_PRINTF_5; +extern bool cpp_error_with_line_noexpand (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; extern bool cpp_warning_with_line (cpp_reader *, int, source_location, unsigned, const char *msgid, ...) ATTRIBUTE_PRINTF_5; +extern bool cpp_warning_with_line_noexpand (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; extern bool cpp_pedwarning_with_line (cpp_reader *, int, source_location, unsigned, const char *msgid, ...) ATTRIBUTE_PRINTF_5; +extern bool cpp_pedwarning_with_line_noexpand (cpp_reader *, int, + source_location, unsigned, + const char *msgid, ...) + ATTRIBUTE_PRINTF_5; extern bool cpp_warning_with_line_syshdr (cpp_reader *, int, source_location, unsigned, const char *msgid, ...) ATTRIBUTE_PRINTF_5; Marek