re PR c/52952 (Wformat location info is bad (wrong column number))

gcc/c-family/ChangeLog:

2014-08-19  Manuel López-Ibáñez  <manu@gcc.gnu.org>
	    Steven Bosscher  <steven@gcc.gnu.org>

	PR c/52952
	* c-format.c: Add extra_arg_loc and format_string_loc to struct
	format_check_results.
	(check_function_format): Use true and add comment for boolean
	argument.
	(finish_dollar_format_checking): Use explicit location when warning.
	(check_format_info): Likewise.
	(check_format_arg): Set extra_arg_loc and format_string_loc.
	(check_format_info_main): Use explicit location when warning.
	(check_format_types): Pass explicit location.
	(format_type_warning): Likewise.

gcc/testsuite/ChangeLog:

2014-08-19  Manuel López-Ibáñez  <manu@gcc.gnu.org>
	    Steven Bosscher  <steven@gcc.gnu.org>

	PR c/52952
	* gcc.dg/redecl-4.c: Add column markers.
	* gcc.dg/format/bitfld-1.c: Likewise.
	* gcc.dg/format/attr-2.c: Likewise.
	* gcc.dg/format/attr-6.c: Likewise.
	* gcc.dg/format/array-1.c: Likewise.
	* gcc.dg/format/attr-7.c: Likewise.
	* gcc.dg/format/asm_fprintf-1.c: Likewise.
	* gcc.dg/format/attr-4.c: Likewise.
	* gcc.dg/format/branch-1.c: Likewise.
	* gcc.dg/format/c90-printf-1.c: Likewise.


Co-Authored-By: Steven Bosscher <steven@gcc.gnu.org>

From-SVN: r214129
parent 0f82e5c9
2014-08-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
Steven Bosscher <steven@gcc.gnu.org>
PR c/52952
* c-format.c: Add extra_arg_loc and format_string_loc to struct
format_check_results.
(check_function_format): Use true and add comment for boolean
argument.
(finish_dollar_format_checking): Use explicit location when warning.
(check_format_info): Likewise.
(check_format_arg): Set extra_arg_loc and format_string_loc.
(check_format_info_main): Use explicit location when warning.
(check_format_types): Pass explicit location.
(format_type_warning): Likewise.
2014-08-15 Manuel López-Ibáñez <manu@gcc.gnu.org> 2014-08-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054 PR fortran/44054
......
...@@ -895,6 +895,7 @@ typedef struct ...@@ -895,6 +895,7 @@ typedef struct
/* Number of leaves of the format argument that were null pointers or /* Number of leaves of the format argument that were null pointers or
string literals, but had extra format arguments. */ string literals, but had extra format arguments. */
int number_extra_args; int number_extra_args;
location_t extra_arg_loc;
/* Number of leaves of the format argument that were null pointers or /* Number of leaves of the format argument that were null pointers or
string literals, but had extra format arguments and used $ operand string literals, but had extra format arguments and used $ operand
numbers. */ numbers. */
...@@ -909,6 +910,8 @@ typedef struct ...@@ -909,6 +910,8 @@ typedef struct
int number_unterminated; int number_unterminated;
/* Number of leaves of the format argument that were not counted above. */ /* Number of leaves of the format argument that were not counted above. */
int number_other; int number_other;
/* Location of the format string. */
location_t format_string_loc;
} format_check_results; } format_check_results;
typedef struct typedef struct
...@@ -954,8 +957,8 @@ static void finish_dollar_format_checking (format_check_results *, int); ...@@ -954,8 +957,8 @@ static void finish_dollar_format_checking (format_check_results *, int);
static const format_flag_spec *get_flag_spec (const format_flag_spec *, static const format_flag_spec *get_flag_spec (const format_flag_spec *,
int, const char *); int, const char *);
static void check_format_types (format_wanted_type *); static void check_format_types (location_t, format_wanted_type *);
static void format_type_warning (format_wanted_type *, tree, tree); static void format_type_warning (location_t, format_wanted_type *, tree, tree);
/* Decode a format type from a string, returning the type, or /* Decode a format type from a string, returning the type, or
format_type_error if not valid, in which case the caller should print an format_type_error if not valid, in which case the caller should print an
...@@ -1002,7 +1005,7 @@ check_function_format (tree attrs, int nargs, tree *argarray) ...@@ -1002,7 +1005,7 @@ check_function_format (tree attrs, int nargs, tree *argarray)
{ {
/* Yup; check it. */ /* Yup; check it. */
function_format_info info; function_format_info info;
decode_format_attr (TREE_VALUE (a), &info, 1); decode_format_attr (TREE_VALUE (a), &info, /*validated=*/true);
if (warn_format) if (warn_format)
{ {
/* FIXME: Rewrite all the internal functions in this file /* FIXME: Rewrite all the internal functions in this file
...@@ -1256,9 +1259,9 @@ finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok) ...@@ -1256,9 +1259,9 @@ finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
|| dollar_arguments_pointer_p[i])) || dollar_arguments_pointer_p[i]))
found_pointer_gap = true; found_pointer_gap = true;
else else
warning (OPT_Wformat_, warning_at (res->format_string_loc, OPT_Wformat_,
"format argument %d unused before used argument %d in $-style format", "format argument %d unused before used argument %d in $-style format",
i + 1, dollar_max_arg_used); i + 1, dollar_max_arg_used);
} }
} }
if (found_pointer_gap if (found_pointer_gap
...@@ -1329,11 +1332,13 @@ check_format_info (function_format_info *info, tree params) ...@@ -1329,11 +1332,13 @@ check_format_info (function_format_info *info, tree params)
res.number_non_literal = 0; res.number_non_literal = 0;
res.number_extra_args = 0; res.number_extra_args = 0;
res.extra_arg_loc = UNKNOWN_LOCATION;
res.number_dollar_extra_args = 0; res.number_dollar_extra_args = 0;
res.number_wide = 0; res.number_wide = 0;
res.number_empty = 0; res.number_empty = 0;
res.number_unterminated = 0; res.number_unterminated = 0;
res.number_other = 0; res.number_other = 0;
res.format_string_loc = input_location;
format_ctx.res = &res; format_ctx.res = &res;
format_ctx.info = info; format_ctx.info = info;
...@@ -1342,6 +1347,10 @@ check_format_info (function_format_info *info, tree params) ...@@ -1342,6 +1347,10 @@ check_format_info (function_format_info *info, tree params)
check_function_arguments_recurse (check_format_arg, &format_ctx, check_function_arguments_recurse (check_format_arg, &format_ctx,
format_tree, arg_num); format_tree, arg_num);
location_t loc = format_ctx.res->format_string_loc;
if (res.extra_arg_loc == UNKNOWN_LOCATION)
res.extra_arg_loc = loc;
if (res.number_non_literal > 0) if (res.number_non_literal > 0)
{ {
/* Functions taking a va_list normally pass a non-literal format /* Functions taking a va_list normally pass a non-literal format
...@@ -1351,8 +1360,8 @@ check_format_info (function_format_info *info, tree params) ...@@ -1351,8 +1360,8 @@ check_format_info (function_format_info *info, tree params)
{ {
/* For strftime-like formats, warn for not checking the format /* For strftime-like formats, warn for not checking the format
string; but there are no arguments to check. */ string; but there are no arguments to check. */
warning (OPT_Wformat_nonliteral, warning_at (loc, OPT_Wformat_nonliteral,
"format not a string literal, format string not checked"); "format not a string literal, format string not checked");
} }
else if (info->first_arg_num != 0) else if (info->first_arg_num != 0)
{ {
...@@ -1366,14 +1375,14 @@ check_format_info (function_format_info *info, tree params) ...@@ -1366,14 +1375,14 @@ check_format_info (function_format_info *info, tree params)
++arg_num; ++arg_num;
} }
if (params == 0 && warn_format_security) if (params == 0 && warn_format_security)
warning (OPT_Wformat_security, warning_at (loc, OPT_Wformat_security,
"format not a string literal and no format arguments"); "format not a string literal and no format arguments");
else if (params == 0 && warn_format_nonliteral) else if (params == 0 && warn_format_nonliteral)
warning (OPT_Wformat_nonliteral, warning_at (loc, OPT_Wformat_nonliteral,
"format not a string literal and no format arguments"); "format not a string literal and no format arguments");
else else
warning (OPT_Wformat_nonliteral, warning_at (loc, OPT_Wformat_nonliteral,
"format not a string literal, argument types not checked"); "format not a string literal, argument types not checked");
} }
} }
...@@ -1386,20 +1395,21 @@ check_format_info (function_format_info *info, tree params) ...@@ -1386,20 +1395,21 @@ check_format_info (function_format_info *info, tree params)
case of extra format arguments. */ case of extra format arguments. */
if (res.number_extra_args > 0 && res.number_non_literal == 0 if (res.number_extra_args > 0 && res.number_non_literal == 0
&& res.number_other == 0) && res.number_other == 0)
warning (OPT_Wformat_extra_args, "too many arguments for format"); warning_at (res.extra_arg_loc, OPT_Wformat_extra_args,
"too many arguments for format");
if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
&& res.number_other == 0) && res.number_other == 0)
warning (OPT_Wformat_extra_args, "unused arguments in $-style format"); warning_at (loc, OPT_Wformat_extra_args, "unused arguments in $-style format");
if (res.number_empty > 0 && res.number_non_literal == 0 if (res.number_empty > 0 && res.number_non_literal == 0
&& res.number_other == 0) && res.number_other == 0)
warning (OPT_Wformat_zero_length, "zero-length %s format string", warning_at (loc, OPT_Wformat_zero_length, "zero-length %s format string",
format_types[info->format_type].name); format_types[info->format_type].name);
if (res.number_wide > 0) if (res.number_wide > 0)
warning (OPT_Wformat_, "format is a wide character string"); warning_at (loc, OPT_Wformat_, "format is a wide character string");
if (res.number_unterminated > 0) if (res.number_unterminated > 0)
warning (OPT_Wformat_, "unterminated format string"); warning_at (loc, OPT_Wformat_, "unterminated format string");
} }
/* Callback from check_function_arguments_recurse to check a /* Callback from check_function_arguments_recurse to check a
...@@ -1437,9 +1447,13 @@ check_format_arg (void *ctx, tree format_tree, ...@@ -1437,9 +1447,13 @@ check_format_arg (void *ctx, tree format_tree,
if (params == 0) if (params == 0)
res->number_other++; res->number_other++;
else else
res->number_extra_args++; {
if (res->number_extra_args == 0)
res->extra_arg_loc = EXPR_LOC_OR_LOC (TREE_VALUE (params),
input_location);
res->number_extra_args++;
}
return; return;
} }
...@@ -1471,6 +1485,7 @@ check_format_arg (void *ctx, tree format_tree, ...@@ -1471,6 +1485,7 @@ check_format_arg (void *ctx, tree format_tree,
res->number_non_literal++; res->number_non_literal++;
return; return;
} }
res->format_string_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
format_tree = TREE_OPERAND (format_tree, 0); format_tree = TREE_OPERAND (format_tree, 0);
if (format_types[info->format_type].flags if (format_types[info->format_type].flags
& (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL) & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)
...@@ -1606,6 +1621,7 @@ check_format_info_main (format_check_results *res, ...@@ -1606,6 +1621,7 @@ check_format_info_main (format_check_results *res,
const format_kind_info *fki = &format_types[info->format_type]; const format_kind_info *fki = &format_types[info->format_type];
const format_flag_spec *flag_specs = fki->flag_specs; const format_flag_spec *flag_specs = fki->flag_specs;
const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs; const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
location_t format_string_loc = res->format_string_loc;
/* -1 if no conversions taking an operand have been found; 0 if one has /* -1 if no conversions taking an operand have been found; 0 if one has
and it didn't use $; 1 if $ formats are in use. */ and it didn't use $; 1 if $ formats are in use. */
...@@ -1643,7 +1659,8 @@ check_format_info_main (format_check_results *res, ...@@ -1643,7 +1659,8 @@ check_format_info_main (format_check_results *res,
continue; continue;
if (*format_chars == 0) if (*format_chars == 0)
{ {
warning (OPT_Wformat_, "spurious trailing %<%%%> in format"); warning_at (format_string_loc, OPT_Wformat_,
"spurious trailing %<%%%> in format");
continue; continue;
} }
if (*format_chars == '%') if (*format_chars == '%')
...@@ -1687,7 +1704,8 @@ check_format_info_main (format_check_results *res, ...@@ -1687,7 +1704,8 @@ check_format_info_main (format_check_results *res,
*format_chars, NULL); *format_chars, NULL);
if (strchr (flag_chars, *format_chars) != 0) if (strchr (flag_chars, *format_chars) != 0)
{ {
warning (OPT_Wformat_, "repeated %s in format", _(s->name)); warning_at (format_string_loc, OPT_Wformat_,
"repeated %s in format", _(s->name));
} }
else else
{ {
...@@ -1700,7 +1718,8 @@ check_format_info_main (format_check_results *res, ...@@ -1700,7 +1718,8 @@ check_format_info_main (format_check_results *res,
++format_chars; ++format_chars;
if (*format_chars == 0) if (*format_chars == 0)
{ {
warning (OPT_Wformat_, "missing fill character at end of strfmon format"); warning_at (format_string_loc, OPT_Wformat_,
"missing fill character at end of strfmon format");
return; return;
} }
} }
...@@ -1788,7 +1807,8 @@ check_format_info_main (format_check_results *res, ...@@ -1788,7 +1807,8 @@ check_format_info_main (format_check_results *res,
} }
if (found_width && !non_zero_width_char && if (found_width && !non_zero_width_char &&
(fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD)) (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
warning (OPT_Wformat_, "zero width in %s format", fki->name); warning_at (format_string_loc, OPT_Wformat_,
"zero width in %s format", fki->name);
if (found_width) if (found_width)
{ {
i = strlen (flag_chars); i = strlen (flag_chars);
...@@ -1806,7 +1826,8 @@ check_format_info_main (format_check_results *res, ...@@ -1806,7 +1826,8 @@ check_format_info_main (format_check_results *res,
flag_chars[i++] = fki->left_precision_char; flag_chars[i++] = fki->left_precision_char;
flag_chars[i] = 0; flag_chars[i] = 0;
if (!ISDIGIT (*format_chars)) if (!ISDIGIT (*format_chars))
warning (OPT_Wformat_, "empty left precision in %s format", fki->name); warning_at (format_string_loc, OPT_Wformat_,
"empty left precision in %s format", fki->name);
while (ISDIGIT (*format_chars)) while (ISDIGIT (*format_chars))
++format_chars; ++format_chars;
} }
...@@ -1882,7 +1903,8 @@ check_format_info_main (format_check_results *res, ...@@ -1882,7 +1903,8 @@ check_format_info_main (format_check_results *res,
{ {
if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK) if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
&& !ISDIGIT (*format_chars)) && !ISDIGIT (*format_chars))
warning (OPT_Wformat_, "empty precision in %s format", fki->name); warning_at (format_string_loc, OPT_Wformat_,
"empty precision in %s format", fki->name);
while (ISDIGIT (*format_chars)) while (ISDIGIT (*format_chars))
++format_chars; ++format_chars;
} }
...@@ -1950,10 +1972,10 @@ check_format_info_main (format_check_results *res, ...@@ -1950,10 +1972,10 @@ check_format_info_main (format_check_results *res,
{ {
/* Warn if the length modifier is non-standard. */ /* Warn if the length modifier is non-standard. */
if (ADJ_STD (length_chars_std) > C_STD_VER) if (ADJ_STD (length_chars_std) > C_STD_VER)
warning (OPT_Wformat_, warning_at (format_string_loc, OPT_Wformat_,
"%s does not support the %qs %s length modifier", "%s does not support the %qs %s length modifier",
C_STD_NAME (length_chars_std), length_chars, C_STD_NAME (length_chars_std), length_chars,
fki->name); fki->name);
} }
} }
...@@ -1967,7 +1989,8 @@ check_format_info_main (format_check_results *res, ...@@ -1967,7 +1989,8 @@ check_format_info_main (format_check_results *res,
{ {
const format_flag_spec *s = get_flag_spec (flag_specs, const format_flag_spec *s = get_flag_spec (flag_specs,
*format_chars, NULL); *format_chars, NULL);
warning (OPT_Wformat_, "repeated %s in format", _(s->name)); warning_at (format_string_loc, OPT_Wformat_,
"repeated %s in format", _(s->name));
} }
else else
{ {
...@@ -1984,7 +2007,8 @@ check_format_info_main (format_check_results *res, ...@@ -1984,7 +2007,8 @@ check_format_info_main (format_check_results *res,
|| (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK) || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
&& format_char == '%')) && format_char == '%'))
{ {
warning (OPT_Wformat_, "conversion lacks type at end of format"); warning_at (format_string_loc, OPT_Wformat_,
"conversion lacks type at end of format");
continue; continue;
} }
format_chars++; format_chars++;
...@@ -1995,18 +2019,21 @@ check_format_info_main (format_check_results *res, ...@@ -1995,18 +2019,21 @@ check_format_info_main (format_check_results *res,
if (fci->format_chars == 0) if (fci->format_chars == 0)
{ {
if (ISGRAPH (format_char)) if (ISGRAPH (format_char))
warning (OPT_Wformat_, "unknown conversion type character %qc in format", warning_at (format_string_loc, OPT_Wformat_,
format_char); "unknown conversion type character %qc in format",
format_char);
else else
warning (OPT_Wformat_, "unknown conversion type character 0x%x in format", warning_at (format_string_loc, OPT_Wformat_,
format_char); "unknown conversion type character 0x%x in format",
format_char);
continue; continue;
} }
if (pedantic) if (pedantic)
{ {
if (ADJ_STD (fci->std) > C_STD_VER) if (ADJ_STD (fci->std) > C_STD_VER)
warning (OPT_Wformat_, "%s does not support the %<%%%c%> %s format", warning_at (format_string_loc, OPT_Wformat_,
C_STD_NAME (fci->std), format_char, fki->name); "%s does not support the %<%%%c%> %s format",
C_STD_NAME (fci->std), format_char, fki->name);
} }
/* Validate the individual flags used, removing any that are invalid. */ /* Validate the individual flags used, removing any that are invalid. */
...@@ -2021,8 +2048,9 @@ check_format_info_main (format_check_results *res, ...@@ -2021,8 +2048,9 @@ check_format_info_main (format_check_results *res,
continue; continue;
if (strchr (fci->flag_chars, flag_chars[i]) == 0) if (strchr (fci->flag_chars, flag_chars[i]) == 0)
{ {
warning (OPT_Wformat_, "%s used with %<%%%c%> %s format", warning_at (format_string_loc,
_(s->name), format_char, fki->name); OPT_Wformat_, "%s used with %<%%%c%> %s format",
_(s->name), format_char, fki->name);
d++; d++;
continue; continue;
} }
...@@ -2030,8 +2058,9 @@ check_format_info_main (format_check_results *res, ...@@ -2030,8 +2058,9 @@ check_format_info_main (format_check_results *res,
{ {
const format_flag_spec *t; const format_flag_spec *t;
if (ADJ_STD (s->std) > C_STD_VER) if (ADJ_STD (s->std) > C_STD_VER)
warning (OPT_Wformat_, "%s does not support %s", warning_at (format_string_loc, OPT_Wformat_,
C_STD_NAME (s->std), _(s->long_name)); "%s does not support %s",
C_STD_NAME (s->std), _(s->long_name));
t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2); t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std)) if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
{ {
...@@ -2039,10 +2068,10 @@ check_format_info_main (format_check_results *res, ...@@ -2039,10 +2068,10 @@ check_format_info_main (format_check_results *res,
? t->long_name ? t->long_name
: s->long_name); : s->long_name);
if (ADJ_STD (t->std) > C_STD_VER) if (ADJ_STD (t->std) > C_STD_VER)
warning (OPT_Wformat_, warning_at (format_string_loc, OPT_Wformat_,
"%s does not support %s with the %<%%%c%> %s format", "%s does not support %s with the %<%%%c%> %s format",
C_STD_NAME (t->std), _(long_name), C_STD_NAME (t->std), _(long_name),
format_char, fki->name); format_char, fki->name);
} }
} }
} }
...@@ -2075,24 +2104,26 @@ check_format_info_main (format_check_results *res, ...@@ -2075,24 +2104,26 @@ check_format_info_main (format_check_results *res,
if (bad_flag_pairs[i].ignored) if (bad_flag_pairs[i].ignored)
{ {
if (bad_flag_pairs[i].predicate != 0) if (bad_flag_pairs[i].predicate != 0)
warning (OPT_Wformat_, warning_at (format_string_loc, OPT_Wformat_,
"%s ignored with %s and %<%%%c%> %s format", "%s ignored with %s and %<%%%c%> %s format",
_(s->name), _(t->name), format_char, _(s->name), _(t->name), format_char,
fki->name); fki->name);
else else
warning (OPT_Wformat_, "%s ignored with %s in %s format", warning_at (format_string_loc, OPT_Wformat_,
_(s->name), _(t->name), fki->name); "%s ignored with %s in %s format",
_(s->name), _(t->name), fki->name);
} }
else else
{ {
if (bad_flag_pairs[i].predicate != 0) if (bad_flag_pairs[i].predicate != 0)
warning (OPT_Wformat_, warning_at (format_string_loc, OPT_Wformat_,
"use of %s and %s together with %<%%%c%> %s format", "use of %s and %s together with %<%%%c%> %s format",
_(s->name), _(t->name), format_char, _(s->name), _(t->name), format_char,
fki->name); fki->name);
else else
warning (OPT_Wformat_, "use of %s and %s together in %s format", warning_at (format_string_loc, OPT_Wformat_,
_(s->name), _(t->name), fki->name); "use of %s and %s together in %s format",
_(s->name), _(t->name), fki->name);
} }
} }
...@@ -2110,11 +2141,13 @@ check_format_info_main (format_check_results *res, ...@@ -2110,11 +2141,13 @@ check_format_info_main (format_check_results *res,
else if (strchr (fci->flags2, '2') != 0) else if (strchr (fci->flags2, '2') != 0)
y2k_level = 2; y2k_level = 2;
if (y2k_level == 3) if (y2k_level == 3)
warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of " warning_at (format_string_loc, OPT_Wformat_y2k,
"year in some locales", format_char); "%<%%%c%> yields only last 2 digits of "
"year in some locales", format_char);
else if (y2k_level == 2) else if (y2k_level == 2)
warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of " warning_at (format_string_loc, OPT_Wformat_y2k,
"year", format_char); "%<%%%c%> yields only last 2 digits of year",
format_char);
} }
if (strchr (fci->flags2, '[') != 0) if (strchr (fci->flags2, '[') != 0)
...@@ -2130,7 +2163,8 @@ check_format_info_main (format_check_results *res, ...@@ -2130,7 +2163,8 @@ check_format_info_main (format_check_results *res,
++format_chars; ++format_chars;
if (*format_chars != ']') if (*format_chars != ']')
/* The end of the format string was reached. */ /* The end of the format string was reached. */
warning (OPT_Wformat_, "no closing %<]%> for %<%%[%> format"); warning_at (format_string_loc, OPT_Wformat_,
"no closing %<]%> for %<%%[%> format");
} }
wanted_type = 0; wanted_type = 0;
...@@ -2143,9 +2177,9 @@ check_format_info_main (format_check_results *res, ...@@ -2143,9 +2177,9 @@ check_format_info_main (format_check_results *res,
wanted_type_std = fci->types[length_chars_val].std; wanted_type_std = fci->types[length_chars_val].std;
if (wanted_type == 0) if (wanted_type == 0)
{ {
warning (OPT_Wformat_, warning_at (format_string_loc, OPT_Wformat_,
"use of %qs length modifier with %qc type character", "use of %qs length modifier with %qc type character",
length_chars, format_char); length_chars, format_char);
/* Heuristic: skip one argument when an invalid length/type /* Heuristic: skip one argument when an invalid length/type
combination is encountered. */ combination is encountered. */
arg_num++; arg_num++;
...@@ -2161,10 +2195,10 @@ check_format_info_main (format_check_results *res, ...@@ -2161,10 +2195,10 @@ check_format_info_main (format_check_results *res,
&& ADJ_STD (wanted_type_std) > ADJ_STD (fci->std)) && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
{ {
if (ADJ_STD (wanted_type_std) > C_STD_VER) if (ADJ_STD (wanted_type_std) > C_STD_VER)
warning (OPT_Wformat_, warning_at (format_string_loc, OPT_Wformat_,
"%s does not support the %<%%%s%c%> %s format", "%s does not support the %<%%%s%c%> %s format",
C_STD_NAME (wanted_type_std), length_chars, C_STD_NAME (wanted_type_std), length_chars,
format_char, fki->name); format_char, fki->name);
} }
} }
...@@ -2179,11 +2213,13 @@ check_format_info_main (format_check_results *res, ...@@ -2179,11 +2213,13 @@ check_format_info_main (format_check_results *res,
if (main_arg_num != 0) if (main_arg_num != 0)
{ {
if (suppressed) if (suppressed)
warning (OPT_Wformat_, "operand number specified with " warning_at (format_string_loc, OPT_Wformat_,
"suppressed assignment"); "operand number specified with "
"suppressed assignment");
else else
warning (OPT_Wformat_, "operand number specified for format " warning_at (format_string_loc, OPT_Wformat_,
"taking no argument"); "operand number specified for format "
"taking no argument");
} }
} }
else else
...@@ -2200,7 +2236,8 @@ check_format_info_main (format_check_results *res, ...@@ -2200,7 +2236,8 @@ check_format_info_main (format_check_results *res,
++arg_num; ++arg_num;
if (has_operand_number > 0) if (has_operand_number > 0)
{ {
warning (OPT_Wformat_, "missing $ operand number in format"); warning_at (format_string_loc, OPT_Wformat_,
"missing $ operand number in format");
return; return;
} }
else else
...@@ -2263,11 +2300,12 @@ check_format_info_main (format_check_results *res, ...@@ -2263,11 +2300,12 @@ check_format_info_main (format_check_results *res,
} }
if (first_wanted_type != 0) if (first_wanted_type != 0)
check_format_types (first_wanted_type); check_format_types (format_string_loc, first_wanted_type);
} }
if (format_chars - orig_format_chars != format_length) if (format_chars - orig_format_chars != format_length)
warning (OPT_Wformat_contains_nul, "embedded %<\\0%> in format"); warning_at (format_string_loc, OPT_Wformat_contains_nul,
"embedded %<\\0%> in format");
if (info->first_arg_num != 0 && params != 0 if (info->first_arg_num != 0 && params != 0
&& has_operand_number <= 0) && has_operand_number <= 0)
{ {
...@@ -2280,9 +2318,10 @@ check_format_info_main (format_check_results *res, ...@@ -2280,9 +2318,10 @@ check_format_info_main (format_check_results *res,
/* Check the argument types from a single format conversion (possibly /* Check the argument types from a single format conversion (possibly
including width and precision arguments). */ including width and precision arguments). LOC is the location of
the format string. */
static void static void
check_format_types (format_wanted_type *types) check_format_types (location_t loc, format_wanted_type *types)
{ {
for (; types != 0; types = types->next) for (; types != 0; types = types->next)
{ {
...@@ -2309,7 +2348,7 @@ check_format_types (format_wanted_type *types) ...@@ -2309,7 +2348,7 @@ check_format_types (format_wanted_type *types)
cur_param = types->param; cur_param = types->param;
if (!cur_param) if (!cur_param)
{ {
format_type_warning (types, wanted_type, NULL); format_type_warning (loc, types, wanted_type, NULL);
continue; continue;
} }
...@@ -2383,7 +2422,7 @@ check_format_types (format_wanted_type *types) ...@@ -2383,7 +2422,7 @@ check_format_types (format_wanted_type *types)
} }
else else
{ {
format_type_warning (types, wanted_type, orig_cur_type); format_type_warning (loc, types, wanted_type, orig_cur_type);
break; break;
} }
} }
...@@ -2437,12 +2476,12 @@ check_format_types (format_wanted_type *types) ...@@ -2437,12 +2476,12 @@ check_format_types (format_wanted_type *types)
&& TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type)) && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
continue; continue;
/* Now we have a type mismatch. */ /* Now we have a type mismatch. */
format_type_warning (types, wanted_type, orig_cur_type); format_type_warning (loc, types, wanted_type, orig_cur_type);
} }
} }
/* Give a warning about a format argument of different type from that /* Give a warning at LOC about a format argument of different type from that
expected. WANTED_TYPE is the type the argument should have, possibly expected. WANTED_TYPE is the type the argument should have, possibly
stripped of pointer dereferences. The description (such as "field stripped of pointer dereferences. The description (such as "field
precision"), the placement in the format string, a possibly more precision"), the placement in the format string, a possibly more
...@@ -2450,7 +2489,8 @@ check_format_types (format_wanted_type *types) ...@@ -2450,7 +2489,8 @@ check_format_types (format_wanted_type *types)
are taken from TYPE. ARG_TYPE is the type of the actual argument, are taken from TYPE. ARG_TYPE is the type of the actual argument,
or NULL if it is missing. */ or NULL if it is missing. */
static void static void
format_type_warning (format_wanted_type *type, tree wanted_type, tree arg_type) format_type_warning (location_t loc, format_wanted_type *type,
tree wanted_type, tree arg_type)
{ {
int kind = type->kind; int kind = type->kind;
const char *wanted_type_name = type->wanted_type_name; const char *wanted_type_name = type->wanted_type_name;
...@@ -2494,32 +2534,36 @@ format_type_warning (format_wanted_type *type, tree wanted_type, tree arg_type) ...@@ -2494,32 +2534,36 @@ format_type_warning (format_wanted_type *type, tree wanted_type, tree arg_type)
if (wanted_type_name) if (wanted_type_name)
{ {
if (arg_type) if (arg_type)
warning (OPT_Wformat_, "%s %<%s%.*s%> expects argument of type %<%s%s%>, " warning_at (loc, OPT_Wformat_,
"but argument %d has type %qT", "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
gettext (kind_descriptions[kind]), "but argument %d has type %qT",
(kind == CF_KIND_FORMAT ? "%" : ""), gettext (kind_descriptions[kind]),
format_length, format_start, (kind == CF_KIND_FORMAT ? "%" : ""),
wanted_type_name, p, arg_num, arg_type); format_length, format_start,
wanted_type_name, p, arg_num, arg_type);
else else
warning (OPT_Wformat_, "%s %<%s%.*s%> expects a matching %<%s%s%> argument", warning_at (loc, OPT_Wformat_,
gettext (kind_descriptions[kind]), "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
(kind == CF_KIND_FORMAT ? "%" : ""), gettext (kind_descriptions[kind]),
format_length, format_start, wanted_type_name, p); (kind == CF_KIND_FORMAT ? "%" : ""),
format_length, format_start, wanted_type_name, p);
} }
else else
{ {
if (arg_type) if (arg_type)
warning (OPT_Wformat_, "%s %<%s%.*s%> expects argument of type %<%T%s%>, " warning_at (loc, OPT_Wformat_,
"but argument %d has type %qT", "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
gettext (kind_descriptions[kind]), "but argument %d has type %qT",
(kind == CF_KIND_FORMAT ? "%" : ""), gettext (kind_descriptions[kind]),
format_length, format_start, (kind == CF_KIND_FORMAT ? "%" : ""),
wanted_type, p, arg_num, arg_type); format_length, format_start,
wanted_type, p, arg_num, arg_type);
else else
warning (OPT_Wformat_, "%s %<%s%.*s%> expects a matching %<%T%s%> argument", warning_at (loc, OPT_Wformat_,
gettext (kind_descriptions[kind]), "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
(kind == CF_KIND_FORMAT ? "%" : ""), gettext (kind_descriptions[kind]),
format_length, format_start, wanted_type, p); (kind == CF_KIND_FORMAT ? "%" : ""),
format_length, format_start, wanted_type, p);
} }
} }
......
2014-08-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
Steven Bosscher <steven@gcc.gnu.org>
PR c/52952
* gcc.dg/redecl-4.c: Add column markers.
* gcc.dg/format/bitfld-1.c: Likewise.
* gcc.dg/format/attr-2.c: Likewise.
* gcc.dg/format/attr-6.c: Likewise.
* gcc.dg/format/array-1.c: Likewise.
* gcc.dg/format/attr-7.c: Likewise.
* gcc.dg/format/asm_fprintf-1.c: Likewise.
* gcc.dg/format/attr-4.c: Likewise.
* gcc.dg/format/branch-1.c: Likewise.
* gcc.dg/format/c90-printf-1.c: Likewise.
2014-08-18 Aldy Hernandez <aldyh@redhat.com> 2014-08-18 Aldy Hernandez <aldyh@redhat.com>
* guality/nrv-1.c: Add `used' attribute to a1. * guality/nrv-1.c: Add `used' attribute to a1.
......
...@@ -23,19 +23,19 @@ foo (int i, long l) ...@@ -23,19 +23,19 @@ foo (int i, long l)
static const char q2[] = "bar%d"; static const char q2[] = "bar%d";
printf (a1); printf (a1);
printf (a2, i); printf (a2, i);
printf (a2, l); /* { dg-warning "format" "wrong type with array" } */ printf (a2, l); /* { dg-warning "11:format" "wrong type with array" } */
printf (b1); /* { dg-warning "unterminated" "unterminated array" } */ printf (b1); /* { dg-warning "11:unterminated" "unterminated array" } */
printf (b2); /* { dg-warning "unterminated" "unterminated array" } */ printf (b2); /* { dg-warning "11:unterminated" "unterminated array" } */
printf (c1); printf (c1);
printf (c2, i); printf (c2, i);
printf (c2, l); /* { dg-warning "format" "wrong type with array" } */ printf (c2, l); /* { dg-warning "11:format" "wrong type with array" } */
printf (p1); printf (p1);
printf (p2, i); printf (p2, i);
printf (p2, l); /* { dg-warning "format" "wrong type with array" } */ printf (p2, l); /* { dg-warning "11:format" "wrong type with array" } */
printf (q1); printf (q1);
printf (q2, i); printf (q2, i);
printf (q2, l); /* { dg-warning "format" "wrong type with array" } */ printf (q2, l); /* { dg-warning "11:format" "wrong type with array" } */
/* Volatile or non-constant arrays must not be checked. */ /* Volatile or non-constant arrays must not be checked. */
printf (d); /* { dg-warning "not a string literal" "non-const" } */ printf (d); /* { dg-warning "11:not a string literal" "non-const" } */
printf ((const char *)e); /* { dg-warning "not a string literal" "volatile" } */ printf ((const char *)e); /* { dg-warning "25:not a string literal" "volatile" } */
} }
...@@ -42,39 +42,39 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -42,39 +42,39 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
asm_fprintf ("%wd%wi%wo%wu%wx%wX", ll, ll, ull, ull, ull, ull); asm_fprintf ("%wd%wi%wo%wu%wx%wX", ll, ll, ull, ull, ull, ull);
/* Standard specifiers not accepted in asm_fprintf. */ /* Standard specifiers not accepted in asm_fprintf. */
asm_fprintf ("%f\n", d); /* { dg-warning "format" "float" } */ asm_fprintf ("%f\n", d); /* { dg-warning "16:format" "float" } */
asm_fprintf ("%e\n", d); /* { dg-warning "format" "float" } */ asm_fprintf ("%e\n", d); /* { dg-warning "16:format" "float" } */
asm_fprintf ("%E\n", d); /* { dg-warning "format" "float" } */ asm_fprintf ("%E\n", d); /* { dg-warning "16:format" "float" } */
asm_fprintf ("%g\n", d); /* { dg-warning "format" "float" } */ asm_fprintf ("%g\n", d); /* { dg-warning "16:format" "float" } */
asm_fprintf ("%G\n", d); /* { dg-warning "format" "float" } */ asm_fprintf ("%G\n", d); /* { dg-warning "16:format" "float" } */
asm_fprintf ("%p\n", p); /* { dg-warning "format" "pointer" } */ asm_fprintf ("%p\n", p); /* { dg-warning "16:format" "pointer" } */
asm_fprintf ("%n\n", n); /* { dg-warning "format" "counter" } */ asm_fprintf ("%n\n", n); /* { dg-warning "16:format" "counter" } */
asm_fprintf ("%hd\n", i); /* { dg-warning "format" "conversion" } */ asm_fprintf ("%hd\n", i); /* { dg-warning "16:format" "conversion" } */
/* Various tests of bad argument types. */ /* Various tests of bad argument types. */
asm_fprintf ("%d", l); /* { dg-warning "format" "bad argument types" } */ asm_fprintf ("%d", l); /* { dg-warning "16:format" "bad argument types" } */
asm_fprintf ("%wd", l); /* { dg-warning "format" "bad argument types" } */ asm_fprintf ("%wd", l); /* { dg-warning "16:format" "bad argument types" } */
asm_fprintf ("%d", ll); /* { dg-warning "format" "bad argument types" } */ asm_fprintf ("%d", ll); /* { dg-warning "16:format" "bad argument types" } */
asm_fprintf ("%*d\n", i1, i); /* { dg-warning "format" "bad * argument types" } */ asm_fprintf ("%*d\n", i1, i); /* { dg-warning "16:format" "bad * argument types" } */
asm_fprintf ("%.*d\n", i2, i); /* { dg-warning "format" "bad * argument types" } */ asm_fprintf ("%.*d\n", i2, i); /* { dg-warning "16:format" "bad * argument types" } */
asm_fprintf ("%*.*ld\n", i1, i2, l); /* { dg-warning "format" "bad * argument types" } */ asm_fprintf ("%*.*ld\n", i1, i2, l); /* { dg-warning "16:format" "bad * argument types" } */
asm_fprintf ("%ld", i); /* { dg-warning "format" "bad argument types" } */ asm_fprintf ("%ld", i); /* { dg-warning "16:format" "bad argument types" } */
asm_fprintf ("%s", n); /* { dg-warning "format" "bad argument types" } */ asm_fprintf ("%s", n); /* { dg-warning "16:format" "bad argument types" } */
/* Wrong number of arguments. */ /* Wrong number of arguments. */
asm_fprintf ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */ asm_fprintf ("%d%d", i); /* { dg-warning "16:matching" "wrong number of args" } */
asm_fprintf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */ asm_fprintf ("%d", i, i); /* { dg-warning "16:arguments" "wrong number of args" } */
/* Miscellaneous bogus constructions. */ /* Miscellaneous bogus constructions. */
asm_fprintf (""); /* { dg-warning "zero-length" "warning for empty format" } */ asm_fprintf (""); /* { dg-warning "16:zero-length" "warning for empty format" } */
asm_fprintf ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */ asm_fprintf ("\0"); /* { dg-warning "16:embedded" "warning for embedded NUL" } */
asm_fprintf ("%d\0", i); /* { dg-warning "embedded" "warning for embedded NUL" } */ asm_fprintf ("%d\0", i); /* { dg-warning "16:embedded" "warning for embedded NUL" } */
asm_fprintf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */ asm_fprintf ("%d\0%d", i, i); /* { dg-warning "16:embedded|too many" "warning for embedded NUL" } */
asm_fprintf (NULL); /* { dg-warning "null" "null format string warning" } */ asm_fprintf (NULL); /* { dg-warning "null" "null format string warning" } */
asm_fprintf ("%"); /* { dg-warning "trailing" "trailing % warning" } */ asm_fprintf ("%"); /* { dg-warning "16:trailing" "trailing % warning" } */
asm_fprintf ("%++d", i); /* { dg-warning "repeated" "repeated flag warning" } */ asm_fprintf ("%++d", i); /* { dg-warning "16:repeated" "repeated flag warning" } */
asm_fprintf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */ asm_fprintf ((const char *)L"foo"); /* { dg-warning "30:wide" "wide string" } */
asm_fprintf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */ asm_fprintf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */
/* Make sure we still get warnings for regular printf. */ /* Make sure we still get warnings for regular printf. */
printf ("%d\n", ll); /* { dg-warning "format" "bad argument types" } */ printf ("%d\n", ll); /* { dg-warning "11:format" "bad argument types" } */
} }
...@@ -30,7 +30,7 @@ void ...@@ -30,7 +30,7 @@ void
foo (int i, int *ip, double d) foo (int i, int *ip, double d)
{ {
tformatprintf ("%d", i); tformatprintf ("%d", i);
tformatprintf ("%"); /* { dg-warning "format" "attribute format printf" } */ tformatprintf ("%"); /* { dg-warning "18:format" "attribute format printf" } */
tformat__printf__ ("%d", i); tformat__printf__ ("%d", i);
tformat__printf__ ("%"); /* { dg-warning "format" "attribute format __printf__" } */ tformat__printf__ ("%"); /* { dg-warning "format" "attribute format __printf__" } */
tformatscanf ("%d", ip); tformatscanf ("%d", ip);
......
...@@ -16,7 +16,7 @@ void ...@@ -16,7 +16,7 @@ void
baz (int i, int *ip, double d) baz (int i, int *ip, double d)
{ {
tformatprintf0 ("%d", i); tformatprintf0 ("%d", i);
tformatprintf0 ("%"); /* { dg-warning "format" "attribute format printf case 0" } */ tformatprintf0 ("%"); /* { dg-warning "19:format" "attribute format printf case 0" } */
tformatprintf1 ("%d", i); tformatprintf1 ("%d", i);
tformatprintf1 ("%"); /* { dg-warning "format" "attribute format printf case 1" } */ tformatprintf1 ("%"); /* { dg-warning "format" "attribute format printf case 1" } */
tformatprintf2 ("%d", i); tformatprintf2 ("%d", i);
......
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
void void
foo (const char *s, int *p) foo (const char *s, int *p)
{ {
scanf("%ld", p); /* { dg-warning "format" "implicit scanf" } */ scanf("%ld", p); /* { dg-warning "9:format" "implicit scanf" } */
/* { dg-warning "implicit" "implicit decl warning" { target *-*-* } 20 } */ /* { dg-warning "implicit" "implicit decl warning" { target *-*-* } 20 } */
} }
...@@ -18,7 +18,7 @@ baz (int i) ...@@ -18,7 +18,7 @@ baz (int i)
{ {
(*tformatprintf0) ("%d", i); (*tformatprintf0) ("%d", i);
(*tformatprintf0) ((*tformat_arg) ("%d"), i); (*tformatprintf0) ((*tformat_arg) ("%d"), i);
(*tformatprintf0) ("%"); /* { dg-warning "format" "prefix" } */ (*tformatprintf0) ("%"); /* { dg-warning "22:format" "prefix" } */
(*tformatprintf0) ((*tformat_arg) ("%")); /* { dg-warning "format" "prefix" } */ (*tformatprintf0) ((*tformat_arg) ("%")); /* { dg-warning "format" "prefix" } */
(*tformatprintf1) ("%d", i); (*tformatprintf1) ("%d", i);
(*tformatprintf1) ((*tformat_arg) ("%d"), i); (*tformatprintf1) ((*tformat_arg) ("%d"), i);
......
...@@ -46,6 +46,6 @@ foo (void) ...@@ -46,6 +46,6 @@ foo (void)
printf ("%ld%lu", x.u32, x.u32); printf ("%ld%lu", x.u32, x.u32);
printf ("%ld%lu", x.s32, x.s32); printf ("%ld%lu", x.s32, x.s32);
#endif #endif
printf ("%llu", x.u48); /* { dg-warning "has type '.*unsigned int:48'" } */ printf ("%llu", x.u48); /* { dg-warning "11:has type '.*unsigned int:48'" } */
printf ("%llu", (unsigned long long)x.u48); printf ("%llu", (unsigned long long)x.u48);
} }
...@@ -9,19 +9,20 @@ void ...@@ -9,19 +9,20 @@ void
foo (long l, int nfoo) foo (long l, int nfoo)
{ {
printf ((nfoo > 1) ? "%d foos" : "%d foo", nfoo); printf ((nfoo > 1) ? "%d foos" : "%d foo", nfoo);
printf ((l > 1) ? "%d foos" : "%d foo", l); /* { dg-warning "int" "wrong type in conditional expr" } */ printf ((l > 1) ? "%d foos" /* { dg-warning "21:int" "wrong type in conditional expr" } */
printf ((l > 1) ? "%ld foos" : "%d foo", l); /* { dg-warning "int" "wrong type in conditional expr" } */ : "%d foo", l); /* { dg-warning "14:int" "wrong type in conditional expr" } */
printf ((l > 1) ? "%d foos" : "%ld foo", l); /* { dg-warning "int" "wrong type in conditional expr" } */ printf ((l > 1) ? "%ld foos" : "%d foo", l); /* { dg-warning "34:int" "wrong type in conditional expr" } */
printf ((l > 1) ? "%d foos" : "%ld foo", l); /* { dg-warning "21:int" "wrong type in conditional expr" } */
/* Should allow one case to have extra arguments. */ /* Should allow one case to have extra arguments. */
printf ((nfoo > 1) ? "%d foos" : "1 foo", nfoo); printf ((nfoo > 1) ? "%d foos" : "1 foo", nfoo);
printf ((nfoo > 1) ? "many foos" : "1 foo", nfoo); /* { dg-warning "too many" "too many args in all branches" } */ printf ((nfoo > 1) ? "many foos" : "1 foo", nfoo); /* { dg-warning "38:too many" "too many args in all branches" } */
printf ((nfoo > 1) ? "%d foos" : "", nfoo); printf ((nfoo > 1) ? "%d foos" : "", nfoo);
printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "1 foo" : "no foos"), nfoo); printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "1 foo" : "no foos"), nfoo);
printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), nfoo); printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), nfoo);
printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%ld foos"), nfoo); /* { dg-warning "long int" "wrong type" } */ printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%ld foos"), nfoo); /* { dg-warning "61:long int" "wrong type" } */
printf ((nfoo > 1) ? "%ld foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), nfoo); /* { dg-warning "long int" "wrong type" } */ printf ((nfoo > 1) ? "%ld foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), nfoo); /* { dg-warning "24:long int" "wrong type" } */
printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%ld foo" : "%d foos"), nfoo); /* { dg-warning "long int" "wrong type" } */ printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%ld foo" : "%d foos"), nfoo); /* { dg-warning "50:long int" "wrong type" } */
/* Extra arguments to NULL should be complained about. */ /* Extra arguments to NULL should be complained about. */
printf (NULL, "foo"); /* { dg-warning "too many" "NULL extra args" } */ printf (0, "foo"); /* { dg-warning "14:too many" "NULL extra args" } */
/* { dg-warning "null" "null format arg" { target *-*-* } 25 } */ /* { dg-warning "null" "null format arg" { target *-*-* } 26 } */
} }
...@@ -34,28 +34,28 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -34,28 +34,28 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
*/ */
printf ("%.e\n", d); /* { dg-bogus "precision" "bogus precision warning" } */ printf ("%.e\n", d); /* { dg-bogus "precision" "bogus precision warning" } */
/* Bogus use of width. */ /* Bogus use of width. */
printf ("%5n\n", n); /* { dg-warning "width" "width with %n" } */ printf ("%5n\n", n); /* { dg-warning "11:width" "width with %n" } */
/* Erroneous, ignored or pointless constructs with precision. */ /* Erroneous, ignored or pointless constructs with precision. */
/* Whether negative values for precision may be included in the format /* Whether negative values for precision may be included in the format
string is not entirely clear; presume not, following Clive Feather's string is not entirely clear; presume not, following Clive Feather's
proposed resolution to DR#220 against C99. In any case, such a proposed resolution to DR#220 against C99. In any case, such a
construct should be warned about. construct should be warned about.
*/ */
printf ("%.-5d\n", i); /* { dg-warning "format|precision" "negative precision warning" } */ printf ("%.-5d\n", i); /* { dg-warning "11:format|precision" "negative precision warning" } */
printf ("%.-*d\n", i); /* { dg-warning "format" "broken %.-*d format" } */ printf ("%.-*d\n", i); /* { dg-warning "11:format" "broken %.-*d format" } */
printf ("%.3c\n", i); /* { dg-warning "precision" "precision with %c" } */ printf ("%.3c\n", i); /* { dg-warning "11:precision" "precision with %c" } */
printf ("%.3p\n", p); /* { dg-warning "precision" "precision with %p" } */ printf ("%.3p\n", p); /* { dg-warning "11:precision" "precision with %p" } */
printf ("%.3n\n", n); /* { dg-warning "precision" "precision with %n" } */ printf ("%.3n\n", n); /* { dg-warning "11:precision" "precision with %n" } */
/* Valid and invalid %% constructions. Some of the warning messages /* Valid and invalid %% constructions. Some of the warning messages
are non-optimal, but they do detect the errorneous nature of the are non-optimal, but they do detect the errorneous nature of the
format string. format string.
*/ */
printf ("%%"); printf ("%%");
printf ("%.3%"); /* { dg-warning "format" "bogus %%" } */ printf ("%.3%"); /* { dg-warning "11:format" "bogus %%" } */
printf ("%-%"); /* { dg-warning "format" "bogus %%" } */ printf ("%-%"); /* { dg-warning "11:format" "bogus %%" } */
printf ("%-%\n"); /* { dg-warning "format" "bogus %%" } */ printf ("%-%\n"); /* { dg-warning "11:format" "bogus %%" } */
printf ("%5%\n"); /* { dg-warning "format" "bogus %%" } */ printf ("%5%\n"); /* { dg-warning "11:format" "bogus %%" } */
printf ("%h%\n"); /* { dg-warning "format" "bogus %%" } */ printf ("%h%\n"); /* { dg-warning "11:format" "bogus %%" } */
/* Valid and invalid %h, %l, %L constructions. */ /* Valid and invalid %h, %l, %L constructions. */
printf ("%hd", i); printf ("%hd", i);
printf ("%hi", i); printf ("%hi", i);
...@@ -67,30 +67,30 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -67,30 +67,30 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
*/ */
printf ("%ho%hu%hx%hX", u, u, u, u); printf ("%ho%hu%hx%hX", u, u, u, u);
printf ("%hn", hn); printf ("%hn", hn);
printf ("%hf", d); /* { dg-warning "length" "bad use of %h" } */ printf ("%hf", d); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%he", d); /* { dg-warning "length" "bad use of %h" } */ printf ("%he", d); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%hE", d); /* { dg-warning "length" "bad use of %h" } */ printf ("%hE", d); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%hg", d); /* { dg-warning "length" "bad use of %h" } */ printf ("%hg", d); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%hG", d); /* { dg-warning "length" "bad use of %h" } */ printf ("%hG", d); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%hc", i); /* { dg-warning "length" "bad use of %h" } */ printf ("%hc", i); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%hs", s); /* { dg-warning "length" "bad use of %h" } */ printf ("%hs", s); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%hp", p); /* { dg-warning "length" "bad use of %h" } */ printf ("%hp", p); /* { dg-warning "11:length" "bad use of %h" } */
printf ("%h"); /* { dg-warning "conversion lacks type" "bare %h" } */ printf ("%h"); /* { dg-warning "11:conversion lacks type" "bare %h" } */
printf ("%h."); /* { dg-warning "conversion" "bogus %h." } */ printf ("%h."); /* { dg-warning "11:conversion" "bogus %h." } */
printf ("%ld%li%lo%lu%lx%lX", l, l, ul, ul, ul, ul); printf ("%ld%li%lo%lu%lx%lX", l, l, ul, ul, ul, ul);
printf ("%ln", ln); printf ("%ln", ln);
printf ("%lf", d); /* { dg-warning "length|C" "bad use of %l" } */ printf ("%lf", d); /* { dg-warning "11:length|C" "bad use of %l" } */
printf ("%le", d); /* { dg-warning "length|C" "bad use of %l" } */ printf ("%le", d); /* { dg-warning "11:length|C" "bad use of %l" } */
printf ("%lE", d); /* { dg-warning "length|C" "bad use of %l" } */ printf ("%lE", d); /* { dg-warning "11:length|C" "bad use of %l" } */
printf ("%lg", d); /* { dg-warning "length|C" "bad use of %l" } */ printf ("%lg", d); /* { dg-warning "11:length|C" "bad use of %l" } */
printf ("%lG", d); /* { dg-warning "length|C" "bad use of %l" } */ printf ("%lG", d); /* { dg-warning "11:length|C" "bad use of %l" } */
printf ("%lp", p); /* { dg-warning "length|C" "bad use of %l" } */ printf ("%lp", p); /* { dg-warning "11:length|C" "bad use of %l" } */
/* These next two were added in C94, but should be objected to in C90. /* These next two were added in C94, but should be objected to in C90.
For the first one, GCC has wanted wchar_t instead of the correct C94 For the first one, GCC has wanted wchar_t instead of the correct C94
and C99 wint_t. and C99 wint_t.
*/ */
printf ("%lc", lc); /* { dg-warning "length|C" "C90 bad use of %l" } */ printf ("%lc", lc); /* { dg-warning "11:length|C" "C90 bad use of %l" } */
printf ("%ls", ls); /* { dg-warning "length|C" "C90 bad use of %l" } */ printf ("%ls", ls); /* { dg-warning "11:length|C" "C90 bad use of %l" } */
/* These uses of %L are legitimate, though GCC has wrongly warned for /* These uses of %L are legitimate, though GCC has wrongly warned for
them in the past. them in the past.
*/ */
...@@ -98,91 +98,91 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -98,91 +98,91 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
/* These next six are accepted by GCC as referring to long long, /* These next six are accepted by GCC as referring to long long,
but -pedantic correctly warns. but -pedantic correctly warns.
*/ */
printf ("%Ld", ll); /* { dg-warning "does not support" "bad use of %L" } */ printf ("%Ld", ll); /* { dg-warning "11:does not support" "bad use of %L" } */
printf ("%Li", ll); /* { dg-warning "does not support" "bad use of %L" } */ printf ("%Li", ll); /* { dg-warning "11:does not support" "bad use of %L" } */
printf ("%Lo", ull); /* { dg-warning "does not support" "bad use of %L" } */ printf ("%Lo", ull); /* { dg-warning "11:does not support" "bad use of %L" } */
printf ("%Lu", ull); /* { dg-warning "does not support" "bad use of %L" } */ printf ("%Lu", ull); /* { dg-warning "11:does not support" "bad use of %L" } */
printf ("%Lx", ull); /* { dg-warning "does not support" "bad use of %L" } */ printf ("%Lx", ull); /* { dg-warning "11:does not support" "bad use of %L" } */
printf ("%LX", ull); /* { dg-warning "does not support" "bad use of %L" } */ printf ("%LX", ull); /* { dg-warning "11:does not support" "bad use of %L" } */
printf ("%Lc", i); /* { dg-warning "length" "bad use of %L" } */ printf ("%Lc", i); /* { dg-warning "11:length" "bad use of %L" } */
printf ("%Ls", s); /* { dg-warning "length" "bad use of %L" } */ printf ("%Ls", s); /* { dg-warning "11:length" "bad use of %L" } */
printf ("%Lp", p); /* { dg-warning "length" "bad use of %L" } */ printf ("%Lp", p); /* { dg-warning "11:length" "bad use of %L" } */
printf ("%Ln", n); /* { dg-warning "length" "bad use of %L" } */ printf ("%Ln", n); /* { dg-warning "11:length" "bad use of %L" } */
/* Valid uses of each bare conversion. */ /* Valid uses of each bare conversion. */
printf ("%d%i%o%u%x%X%f%e%E%g%G%c%s%p%n%%", i, i, u, u, u, u, d, d, d, d, d, printf ("%d%i%o%u%x%X%f%e%E%g%G%c%s%p%n%%", i, i, u, u, u, u, d, d, d, d, d,
i, s, p, n); i, s, p, n);
/* Uses of the - flag (valid on all non-%, non-n conversions). */ /* Uses of the - flag (valid on all non-%, non-n conversions). */
printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, u, u, u, u, printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, u, u, u, u,
d, d, d, d, d, i, s, p); d, d, d, d, d, i, s, p);
printf ("%-n", n); /* { dg-warning "flag" "bad use of %-n" } */ printf ("%-n", n); /* { dg-warning "11:flag" "bad use of %-n" } */
/* Uses of the + flag (valid on signed conversions only). */ /* Uses of the + flag (valid on signed conversions only). */
printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d); printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d);
printf ("%+o", u); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+o", u); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+u", u); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+u", u); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+x", u); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+x", u); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+X", u); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+X", u); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+c", i); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+c", i); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+s", s); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+s", s); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+p", p); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+p", p); /* { dg-warning "11:flag" "bad use of + flag" } */
printf ("%+n", n); /* { dg-warning "flag" "bad use of + flag" } */ printf ("%+n", n); /* { dg-warning "11:flag" "bad use of + flag" } */
/* Uses of the space flag (valid on signed conversions only, and ignored /* Uses of the space flag (valid on signed conversions only, and ignored
with +). with +).
*/ */
printf ("% +d", i); /* { dg-warning "use of both|ignored" "use of space and + flags" } */ printf ("% +d", i); /* { dg-warning "11:use of both|ignored" "use of space and + flags" } */
printf ("%+ d", i); /* { dg-warning "use of both|ignored" "use of space and + flags" } */ printf ("%+ d", i); /* { dg-warning "11:use of both|ignored" "use of space and + flags" } */
printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d); printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d);
printf ("% o", u); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% o", u); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% u", u); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% u", u); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% x", u); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% x", u); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% X", u); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% X", u); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% c", i); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% c", i); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% s", s); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% s", s); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% p", p); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% p", p); /* { dg-warning "11:flag" "bad use of space flag" } */
printf ("% n", n); /* { dg-warning "flag" "bad use of space flag" } */ printf ("% n", n); /* { dg-warning "11:flag" "bad use of space flag" } */
/* Uses of the # flag. */ /* Uses of the # flag. */
printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, d, d); printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, d, d);
printf ("%#d", i); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#d", i); /* { dg-warning "11:flag" "bad use of # flag" } */
printf ("%#i", i); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#i", i); /* { dg-warning "11:flag" "bad use of # flag" } */
printf ("%#u", u); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#u", u); /* { dg-warning "11:flag" "bad use of # flag" } */
printf ("%#c", i); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#c", i); /* { dg-warning "11:flag" "bad use of # flag" } */
printf ("%#s", s); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#s", s); /* { dg-warning "11:flag" "bad use of # flag" } */
printf ("%#p", p); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#p", p); /* { dg-warning "11:flag" "bad use of # flag" } */
printf ("%#n", n); /* { dg-warning "flag" "bad use of # flag" } */ printf ("%#n", n); /* { dg-warning "11:flag" "bad use of # flag" } */
/* Uses of the 0 flag. */ /* Uses of the 0 flag. */
printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, u, u, u, u, printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, u, u, u, u,
d, d, d, d, d); d, d, d, d, d);
printf ("%0c", i); /* { dg-warning "flag" "bad use of 0 flag" } */ printf ("%0c", i); /* { dg-warning "11:flag" "bad use of 0 flag" } */
printf ("%0s", s); /* { dg-warning "flag" "bad use of 0 flag" } */ printf ("%0s", s); /* { dg-warning "11:flag" "bad use of 0 flag" } */
printf ("%0p", p); /* { dg-warning "flag" "bad use of 0 flag" } */ printf ("%0p", p); /* { dg-warning "11:flag" "bad use of 0 flag" } */
printf ("%0n", n); /* { dg-warning "flag" "bad use of 0 flag" } */ printf ("%0n", n); /* { dg-warning "11:flag" "bad use of 0 flag" } */
/* 0 flag ignored with precision for certain types, not others. */ /* 0 flag ignored with precision for certain types, not others. */
printf ("%08.5d", i); /* { dg-warning "ignored" "0 flag ignored with precision" } */ printf ("%08.5d", i); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
printf ("%08.5i", i); /* { dg-warning "ignored" "0 flag ignored with precision" } */ printf ("%08.5i", i); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
printf ("%08.5o", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */ printf ("%08.5o", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
printf ("%08.5u", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */ printf ("%08.5u", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
printf ("%08.5x", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */ printf ("%08.5x", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
printf ("%08.5X", u); /* { dg-warning "ignored" "0 flag ignored with precision" } */ printf ("%08.5X", u); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
printf ("%08.5f%08.5e%08.5E%08.5g%08.5G", d, d, d, d, d); printf ("%08.5f%08.5e%08.5E%08.5g%08.5G", d, d, d, d, d);
/* 0 flag ignored with - flag. */ /* 0 flag ignored with - flag. */
printf ("%-08d", i); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08d", i); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08i", i); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08i", i); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08o", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08o", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08u", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08u", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08x", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08x", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08X", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08X", u); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08e", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08e", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08E", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08E", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08f", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08f", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08g", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08g", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
printf ("%-08G", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */ printf ("%-08G", d); /* { dg-warning "11:flags|ignored" "0 flag ignored with - flag" } */
/* Various tests of bad argument types. */ /* Various tests of bad argument types. */
printf ("%d", l); /* { dg-warning "format" "bad argument types" } */ printf ("%d", l); /* { dg-warning "11:format" "bad argument types" } */
printf ("%*.*d", l, i2, i); /* { dg-warning "field" "bad * argument types" } */ printf ("%*.*d", l, i2, i); /* { dg-warning "11:field" "bad * argument types" } */
printf ("%*.*d", i1, l, i); /* { dg-warning "field" "bad * argument types" } */ printf ("%*.*d", i1, l, i); /* { dg-warning "11:field" "bad * argument types" } */
printf ("%ld", i); /* { dg-warning "format" "bad argument types" } */ printf ("%ld", i); /* { dg-warning "11:format" "bad argument types" } */
printf ("%s", n); /* { dg-warning "format" "bad argument types" } */ printf ("%s", n); /* { dg-warning "11:format" "bad argument types" } */
printf ("%p", i); /* { dg-warning "format" "bad argument types" } */ printf ("%p", i); /* { dg-warning "11:format" "bad argument types" } */
printf ("%n", p); /* { dg-warning "format" "bad argument types" } */ printf ("%n", p); /* { dg-warning "11:format" "bad argument types" } */
/* With -pedantic, we want some further checks for pointer targets: /* With -pedantic, we want some further checks for pointer targets:
%p should allow only pointers to void (possibly qualified) and %p should allow only pointers to void (possibly qualified) and
to character types (possibly qualified), but not function pointers to character types (possibly qualified), but not function pointers
...@@ -196,9 +196,9 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -196,9 +196,9 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
char * or unsigned char * being passed to %hhn, even if strictly char * or unsigned char * being passed to %hhn, even if strictly
legitimate by the standard.) legitimate by the standard.)
*/ */
printf ("%p", foo); /* { dg-warning "format" "bad argument types" } */ printf ("%p", foo); /* { dg-warning "11:format" "bad argument types" } */
printf ("%n", un); /* { dg-warning "format" "bad argument types" } */ printf ("%n", un); /* { dg-warning "11:format" "bad argument types" } */
printf ("%p", n); /* { dg-warning "format" "bad argument types" } */ printf ("%p", n); /* { dg-warning "11:format" "bad argument types" } */
/* Allow character pointers with %p. */ /* Allow character pointers with %p. */
printf ("%p%p%p%p", s, ss, us, css); printf ("%p%p%p%p", s, ss, us, css);
/* %s allows any character type. */ /* %s allows any character type. */
...@@ -207,7 +207,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -207,7 +207,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
and seems useful to keep, even if some standard versions might be and seems useful to keep, even if some standard versions might be
read to permit it. read to permit it.
*/ */
printf ("%s", p); /* { dg-warning "format" "bad argument types" } */ printf ("%s", p); /* { dg-warning "11:format" "bad argument types" } */
/* The historical behavior is to allow signed / unsigned types /* The historical behavior is to allow signed / unsigned types
interchangeably as arguments. For values representable in both types, interchangeably as arguments. For values representable in both types,
such usage may be correct. For now preserve the behavior of GCC such usage may be correct. For now preserve the behavior of GCC
...@@ -220,18 +220,18 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -220,18 +220,18 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
*/ */
printf ("%*.*d", u1, u2, i); printf ("%*.*d", u1, u2, i);
/* Wrong number of arguments. */ /* Wrong number of arguments. */
printf ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */ printf ("%d%d", i); /* { dg-warning "11:matching" "wrong number of args" } */
printf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */ printf ("%d", i, i); /* { dg-warning "11:arguments" "wrong number of args" } */
/* Miscellaneous bogus constructions. */ /* Miscellaneous bogus constructions. */
printf (""); /* { dg-warning "zero-length" "warning for empty format" } */ printf (""); /* { dg-warning "11:zero-length" "warning for empty format" } */
printf ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */ printf ("\0"); /* { dg-warning "11:embedded" "warning for embedded NUL" } */
printf ("%d\0", i); /* { dg-warning "embedded" "warning for embedded NUL" } */ printf ("%d\0", i); /* { dg-warning "11:embedded" "warning for embedded NUL" } */
printf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */ printf ("%d\0%d", i, i); /* { dg-warning "11:embedded|too many" "warning for embedded NUL" } */
printf (NULL); /* { dg-warning "null" "null format string warning" } */ printf (NULL); /* { dg-warning "3:null" "null format string warning" } */
printf ("%"); /* { dg-warning "trailing" "trailing % warning" } */ printf ("%"); /* { dg-warning "11:trailing" "trailing % warning" } */
printf ("%++d", i); /* { dg-warning "repeated" "repeated flag warning" } */ printf ("%++d", i); /* { dg-warning "11:repeated" "repeated flag warning" } */
printf ("%n", cn); /* { dg-warning "constant" "%n with const" } */ printf ("%n", cn); /* { dg-warning "3:constant" "%n with const" } */
printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */ printf ((const char *)L"foo"); /* { dg-warning "25:wide" "wide string" } */
printf ("%n", (int *)0); /* { dg-warning "null" "%n with NULL" } */ printf ("%n", (int *)0); /* { dg-warning "3:null" "%n with NULL" } */
printf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */ printf ("%s", (char *)0); /* { dg-warning "3:null" "%s with NULL" } */
} }
...@@ -14,7 +14,8 @@ f (void) ...@@ -14,7 +14,8 @@ f (void)
int strcmp (); int strcmp ();
/* Should get format warnings even though the built-in declaration /* Should get format warnings even though the built-in declaration
isn't "visible". */ isn't "visible". */
printf ("%s", 1); /* { dg-warning "format" } */ printf (
"%s", 1); /* { dg-warning "6:format" } */
/* The type of strcmp here should have no prototype. */ /* The type of strcmp here should have no prototype. */
if (0) if (0)
strcmp (1); strcmp (1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment