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 <[email protected]>
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