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

gcc/testsuite/ChangeLog:

2015-05-21  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	PR c/52952
	* gcc.dg/redecl-4.c: Update column numbers.
	* gcc.dg/format/bitfld-1.c: Likewise.
	* gcc.dg/format/attr-2.c: Likewise.
	* gcc.dg/format/attr-6.c: Likewise.
	* gcc.dg/format/attr-7.c (baz): 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. Add tests for column
	locations within strings with embedded escape sequences.

gcc/c-family/ChangeLog:

2015-05-21  Manuel López-Ibáñez  <manu@gcc.gnu.org>
	
	PR c/52952
	* c-format.c (location_column_from_byte_offset): New.
	(location_from_offset): New.
	(struct format_wanted_type): Add offset_loc field.
	(check_format_info): Move handling of location for extra arguments
	closer to the point of warning.
	(check_format_info_main): Pass the result of location_from_offset
	to warning_at.
	(format_type_warning): Pass the result of location_from_offset
	to warning_at.

From-SVN: r223470
parent a4f238b6
2015-05-21 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/52952
* c-format.c (location_column_from_byte_offset): New.
(location_from_offset): New.
(struct format_wanted_type): Add offset_loc field.
(check_format_info): Move handling of location for extra arguments
closer to the point of warning.
(check_format_info_main): Pass the result of location_from_offset
to warning_at.
(format_type_warning): Pass the result of location_from_offset
to warning_at.
2015-05-20 Marek Polacek <polacek@redhat.com> 2015-05-20 Marek Polacek <polacek@redhat.com>
* c-omp.c (check_omp_for_incr_expr): Use BINARY_CLASS_P. * c-omp.c (check_omp_for_incr_expr): Use BINARY_CLASS_P.
......
...@@ -78,6 +78,78 @@ static int first_target_format_type; ...@@ -78,6 +78,78 @@ static int first_target_format_type;
static const char *format_name (int format_num); static const char *format_name (int format_num);
static int format_flags (int format_num); static int format_flags (int format_num);
/* Given a string S of length LINE_WIDTH, find the visual column
corresponding to OFFSET bytes. */
static unsigned int
location_column_from_byte_offset (const char *s, int line_width,
unsigned int offset)
{
const char * c = s;
if (*c != '"')
return 0;
c++, offset--;
while (offset > 0)
{
if (c - s >= line_width)
return 0;
switch (*c)
{
case '\\':
c++;
if (c - s >= line_width)
return 0;
switch (*c)
{
case '\\': case '\'': case '"': case '?':
case '(': case '{': case '[': case '%':
case 'a': case 'b': case 'f': case 'n':
case 'r': case 't': case 'v':
case 'e': case 'E':
c++, offset--;
break;
default:
return 0;
}
break;
case '"':
/* We found the end of the string too early. */
return 0;
default:
c++, offset--;
break;
}
}
return c - s;
}
/* Return a location that encodes the same location as LOC but shifted
by OFFSET bytes. */
static location_t
location_from_offset (location_t loc, int offset)
{
gcc_checking_assert (offset >= 0);
if (linemap_location_from_macro_expansion_p (line_table, loc)
|| offset < 0)
return loc;
expanded_location s = expand_location_to_spelling_point (loc);
int line_width;
const char *line = location_get_source_line (s, &line_width);
line += s.column - 1 ;
line_width -= s.column - 1;
unsigned int column =
location_column_from_byte_offset (line, line_width, (unsigned) offset);
return linemap_position_for_loc_and_offset (line_table, loc, column);
}
/* Check that we have a pointer to a string suitable for use as a format. /* Check that we have a pointer to a string suitable for use as a format.
The default is to check for a char type. The default is to check for a char type.
For objective-c dialects, this is extended to include references to string For objective-c dialects, this is extended to include references to string
...@@ -390,6 +462,9 @@ typedef struct format_wanted_type ...@@ -390,6 +462,9 @@ typedef struct format_wanted_type
tree param; tree param;
/* The argument number of that parameter. */ /* The argument number of that parameter. */
int arg_num; int arg_num;
/* The offset location of this argument with respect to the format
string location. */
unsigned int offset_loc;
/* The next type to check for this format conversion, or NULL if none. */ /* The next type to check for this format conversion, or NULL if none. */
struct format_wanted_type *next; struct format_wanted_type *next;
} format_wanted_type; } format_wanted_type;
...@@ -1358,8 +1433,6 @@ check_format_info (function_format_info *info, tree params) ...@@ -1358,8 +1433,6 @@ check_format_info (function_format_info *info, tree params)
format_tree, arg_num); format_tree, arg_num);
location_t loc = format_ctx.res->format_string_loc; 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)
{ {
...@@ -1405,8 +1478,12 @@ check_format_info (function_format_info *info, tree params) ...@@ -1405,8 +1478,12 @@ 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)
{
if (res.extra_arg_loc == UNKNOWN_LOCATION)
res.extra_arg_loc = loc;
warning_at (res.extra_arg_loc, OPT_Wformat_extra_args, warning_at (res.extra_arg_loc, OPT_Wformat_extra_args,
"too many arguments for format"); "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_at (loc, OPT_Wformat_extra_args, "unused arguments in $-style format"); warning_at (loc, OPT_Wformat_extra_args, "unused arguments in $-style format");
...@@ -1682,7 +1759,9 @@ check_format_info_main (format_check_results *res, ...@@ -1682,7 +1759,9 @@ check_format_info_main (format_check_results *res,
continue; continue;
if (*format_chars == 0) if (*format_chars == 0)
{ {
warning_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"spurious trailing %<%%%> in format"); "spurious trailing %<%%%> in format");
continue; continue;
} }
...@@ -1727,7 +1806,10 @@ check_format_info_main (format_check_results *res, ...@@ -1727,7 +1806,10 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars + 1
- orig_format_chars),
OPT_Wformat_,
"repeated %s in format", _(s->name)); "repeated %s in format", _(s->name));
} }
else else
...@@ -1807,6 +1889,8 @@ check_format_info_main (format_check_results *res, ...@@ -1807,6 +1889,8 @@ check_format_info_main (format_check_results *res,
width_wanted_type.format_length = 1; width_wanted_type.format_length = 1;
width_wanted_type.param = cur_param; width_wanted_type.param = cur_param;
width_wanted_type.arg_num = arg_num; width_wanted_type.arg_num = arg_num;
width_wanted_type.offset_loc =
format_chars - orig_format_chars;
width_wanted_type.next = NULL; width_wanted_type.next = NULL;
if (last_wanted_type != 0) if (last_wanted_type != 0)
last_wanted_type->next = &width_wanted_type; last_wanted_type->next = &width_wanted_type;
...@@ -1849,7 +1933,9 @@ check_format_info_main (format_check_results *res, ...@@ -1849,7 +1933,9 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"empty left precision in %s format", fki->name); "empty left precision in %s format", fki->name);
while (ISDIGIT (*format_chars)) while (ISDIGIT (*format_chars))
++format_chars; ++format_chars;
...@@ -1914,6 +2000,8 @@ check_format_info_main (format_check_results *res, ...@@ -1914,6 +2000,8 @@ check_format_info_main (format_check_results *res,
precision_wanted_type.format_start = format_chars - 2; precision_wanted_type.format_start = format_chars - 2;
precision_wanted_type.format_length = 2; precision_wanted_type.format_length = 2;
precision_wanted_type.arg_num = arg_num; precision_wanted_type.arg_num = arg_num;
precision_wanted_type.offset_loc =
format_chars - orig_format_chars;
precision_wanted_type.next = NULL; precision_wanted_type.next = NULL;
if (last_wanted_type != 0) if (last_wanted_type != 0)
last_wanted_type->next = &precision_wanted_type; last_wanted_type->next = &precision_wanted_type;
...@@ -1926,7 +2014,9 @@ check_format_info_main (format_check_results *res, ...@@ -1926,7 +2014,9 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"empty precision in %s format", fki->name); "empty precision in %s format", fki->name);
while (ISDIGIT (*format_chars)) while (ISDIGIT (*format_chars))
++format_chars; ++format_chars;
...@@ -2012,7 +2102,10 @@ check_format_info_main (format_check_results *res, ...@@ -2012,7 +2102,10 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars
- orig_format_chars),
OPT_Wformat_,
"repeated %s in format", _(s->name)); "repeated %s in format", _(s->name));
} }
else else
...@@ -2030,7 +2123,9 @@ check_format_info_main (format_check_results *res, ...@@ -2030,7 +2123,9 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"conversion lacks type at end of format"); "conversion lacks type at end of format");
continue; continue;
} }
...@@ -2042,11 +2137,15 @@ check_format_info_main (format_check_results *res, ...@@ -2042,11 +2137,15 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"unknown conversion type character %qc in format", "unknown conversion type character %qc in format",
format_char); format_char);
else else
warning_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"unknown conversion type character 0x%x in format", "unknown conversion type character 0x%x in format",
format_char); format_char);
continue; continue;
...@@ -2054,7 +2153,9 @@ check_format_info_main (format_check_results *res, ...@@ -2054,7 +2153,9 @@ check_format_info_main (format_check_results *res,
if (pedantic) if (pedantic)
{ {
if (ADJ_STD (fci->std) > C_STD_VER) if (ADJ_STD (fci->std) > C_STD_VER)
warning_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"%s does not support the %<%%%c%> %s format", "%s does not support the %<%%%c%> %s format",
C_STD_NAME (fci->std), format_char, fki->name); C_STD_NAME (fci->std), format_char, fki->name);
} }
...@@ -2071,7 +2172,9 @@ check_format_info_main (format_check_results *res, ...@@ -2071,7 +2172,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_at (format_string_loc, warning_at (location_from_offset (format_string_loc,
format_chars
- orig_format_chars),
OPT_Wformat_, "%s used with %<%%%c%> %s format", OPT_Wformat_, "%s used with %<%%%c%> %s format",
_(s->name), format_char, fki->name); _(s->name), format_char, fki->name);
d++; d++;
...@@ -2186,7 +2289,9 @@ check_format_info_main (format_check_results *res, ...@@ -2186,7 +2289,9 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
OPT_Wformat_,
"no closing %<]%> for %<%%[%> format"); "no closing %<]%> for %<%%[%> format");
} }
...@@ -2200,8 +2305,11 @@ check_format_info_main (format_check_results *res, ...@@ -2200,8 +2305,11 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
"use of %qs length modifier with %qc type character", format_chars - orig_format_chars),
OPT_Wformat_,
"use of %qs length modifier with %qc type character"
" has either no effect or undefined behavior",
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. */
...@@ -2218,7 +2326,9 @@ check_format_info_main (format_check_results *res, ...@@ -2218,7 +2326,9 @@ 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_at (format_string_loc, OPT_Wformat_, warning_at (location_from_offset (format_string_loc,
format_chars - orig_format_chars),
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);
...@@ -2303,6 +2413,7 @@ check_format_info_main (format_check_results *res, ...@@ -2303,6 +2413,7 @@ check_format_info_main (format_check_results *res,
wanted_type_ptr->arg_num = arg_num; wanted_type_ptr->arg_num = arg_num;
wanted_type_ptr->format_start = format_start; wanted_type_ptr->format_start = format_start;
wanted_type_ptr->format_length = format_chars - format_start; wanted_type_ptr->format_length = format_chars - format_start;
wanted_type_ptr->offset_loc = format_chars - orig_format_chars;
wanted_type_ptr->next = NULL; wanted_type_ptr->next = NULL;
if (last_wanted_type != 0) if (last_wanted_type != 0)
last_wanted_type->next = wanted_type_ptr; last_wanted_type->next = wanted_type_ptr;
...@@ -2327,7 +2438,9 @@ check_format_info_main (format_check_results *res, ...@@ -2327,7 +2438,9 @@ check_format_info_main (format_check_results *res,
} }
if (format_chars - orig_format_chars != format_length) if (format_chars - orig_format_chars != format_length)
warning_at (format_string_loc, OPT_Wformat_contains_nul, warning_at (location_from_offset (format_string_loc,
format_chars + 1 - orig_format_chars),
OPT_Wformat_contains_nul,
"embedded %<\\0%> in format"); "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)
...@@ -2535,6 +2648,7 @@ format_type_warning (location_t loc, format_wanted_type *type, ...@@ -2535,6 +2648,7 @@ format_type_warning (location_t loc, format_wanted_type *type,
int format_length = type->format_length; int format_length = type->format_length;
int pointer_count = type->pointer_count; int pointer_count = type->pointer_count;
int arg_num = type->arg_num; int arg_num = type->arg_num;
unsigned int offset_loc = type->offset_loc;
char *p; char *p;
/* If ARG_TYPE is a typedef with a misleading name (for example, /* If ARG_TYPE is a typedef with a misleading name (for example,
...@@ -2568,6 +2682,8 @@ format_type_warning (location_t loc, format_wanted_type *type, ...@@ -2568,6 +2682,8 @@ format_type_warning (location_t loc, format_wanted_type *type,
p[pointer_count + 1] = 0; p[pointer_count + 1] = 0;
} }
loc = location_from_offset (loc, offset_loc);
if (wanted_type_name) if (wanted_type_name)
{ {
if (arg_type) if (arg_type)
......
2015-05-21 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/52952
* gcc.dg/redecl-4.c: Update column numbers.
* gcc.dg/format/bitfld-1.c: Likewise.
* gcc.dg/format/attr-2.c: Likewise.
* gcc.dg/format/attr-6.c: Likewise.
* gcc.dg/format/attr-7.c (baz): 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. Add tests for column
locations within strings with embedded escape sequences.
2015-05-20 Alex Velenko <Alex.Velenko@arm.com> 2015-05-20 Alex Velenko <Alex.Velenko@arm.com>
* gcc.target/arm/thumb1-far-jump-2.c (r4): Added int in definition. * gcc.target/arm/thumb1-far-jump-2.c (r4): Added int in definition.
......
...@@ -42,39 +42,40 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -42,39 +42,40 @@ 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 "16:format" "float" } */ asm_fprintf ("%f\n", d); /* { dg-warning "18:format" "float" } */
asm_fprintf ("%e\n", d); /* { dg-warning "16:format" "float" } */ asm_fprintf ("%e\n", d); /* { dg-warning "18:format" "float" } */
asm_fprintf ("%E\n", d); /* { dg-warning "16:format" "float" } */ asm_fprintf ("%E\n", d); /* { dg-warning "18:format" "float" } */
asm_fprintf ("%g\n", d); /* { dg-warning "16:format" "float" } */ asm_fprintf ("%g\n", d); /* { dg-warning "18:format" "float" } */
asm_fprintf ("%G\n", d); /* { dg-warning "16:format" "float" } */ asm_fprintf ("%G\n", d); /* { dg-warning "18:format" "float" } */
asm_fprintf ("%p\n", p); /* { dg-warning "16:format" "pointer" } */ asm_fprintf ("%p\n", p); /* { dg-warning "18:format" "pointer" } */
asm_fprintf ("%n\n", n); /* { dg-warning "16:format" "counter" } */ asm_fprintf ("%n\n", n); /* { dg-warning "18:format" "counter" } */
asm_fprintf ("%hd\n", i); /* { dg-warning "16:format" "conversion" } */ asm_fprintf ("%hd\n", i); /* { dg-warning "18:format" "conversion" } */
/* Various tests of bad argument types. */ /* Various tests of bad argument types. */
asm_fprintf ("%d", l); /* { dg-warning "16:format" "bad argument types" } */ asm_fprintf ("%d", l); /* { dg-warning "18:format" "bad argument types" } */
asm_fprintf ("%wd", l); /* { dg-warning "16:format" "bad argument types" } */ asm_fprintf ("%wd", l); /* { dg-warning "19:format" "bad argument types" } */
asm_fprintf ("%d", ll); /* { dg-warning "16:format" "bad argument types" } */ asm_fprintf ("%d", ll); /* { dg-warning "18:format" "bad argument types" } */
asm_fprintf ("%*d\n", i1, i); /* { dg-warning "16:format" "bad * argument types" } */ asm_fprintf ("%*d\n", i1, i); /* { dg-warning "18:format" "bad * argument types" } */
asm_fprintf ("%.*d\n", i2, i); /* { dg-warning "16:format" "bad * argument types" } */ asm_fprintf ("%.*d\n", i2, i); /* { dg-warning "19:format" "bad * argument types" } */
asm_fprintf ("%*.*ld\n", i1, i2, l); /* { dg-warning "16:format" "bad * argument types" } */ asm_fprintf ("%*.*ld\n", i1, i2, l); /* { dg-warning "18:format" "bad * argument types" } */
asm_fprintf ("%ld", i); /* { dg-warning "16:format" "bad argument types" } */ asm_fprintf ("%ld", i); /* { dg-warning "19:format" "bad argument types" } */
asm_fprintf ("%s", n); /* { dg-warning "16:format" "bad argument types" } */ asm_fprintf ("%s", n); /* { dg-warning "18:format" "bad argument types" } */
/* Wrong number of arguments. */ /* Wrong number of arguments. */
asm_fprintf ("%d%d", i); /* { dg-warning "16:matching" "wrong number of args" } */ asm_fprintf ("%d%d", i); /* { dg-warning "20:matching" "wrong number of args" } */
asm_fprintf ("%d", i, i); /* { dg-warning "16: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 "16:zero-length" "warning for empty format" } */ asm_fprintf (""); /* { dg-warning "16:zero-length" "warning for empty format" } */
asm_fprintf ("\0"); /* { dg-warning "16:embedded" "warning for embedded NUL" } */ asm_fprintf ("\0"); /* { dg-warning "17:embedded" "warning for embedded NUL" } */
asm_fprintf ("%d\0", i); /* { dg-warning "16:embedded" "warning for embedded NUL" } */ asm_fprintf ("%d\0", i); /* { dg-warning "19:embedded" "warning for embedded NUL" } */
asm_fprintf ("%d\0%d", i, i); /* { dg-warning "16:embedded|too many" "warning for embedded NUL" } */ asm_fprintf ("%d\0%d", i, i); /* { dg-warning "19: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 "16:trailing" "trailing % warning" } */ asm_fprintf ("%"); /* { dg-warning "17:trailing" "trailing % warning" } */
asm_fprintf ("%++d", i); /* { dg-warning "16:repeated" "repeated flag warning" } */ asm_fprintf ("%++d", i); /* { dg-warning "19:repeated" "repeated flag warning" } */
asm_fprintf ((const char *)L"foo"); /* { dg-warning "30: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 "11:format" "bad argument types" } */ printf ("%d\n", ll); /* { dg-warning "13:format" "bad argument types" } */
} }
/* { dg-warning "16:too many arguments for format" "too many arguments" { target *-*-* } 0 } */
...@@ -30,13 +30,13 @@ void ...@@ -30,13 +30,13 @@ void
foo (int i, int *ip, double d) foo (int i, int *ip, double d)
{ {
tformatprintf ("%d", i); tformatprintf ("%d", i);
tformatprintf ("%"); /* { dg-warning "18:format" "attribute format printf" } */ tformatprintf ("%"); /* { dg-warning "19: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);
tformatscanf ("%"); /* { dg-warning "format" "attribute format scanf" } */ tformatscanf ("%"); /* { dg-warning "format" "attribute format scanf" } */
tformat__scanf__ ("%d", ip); tformat__scanf__ ("%d", ip);
tformat__scanf__ ("%"); /* { dg-warning "format" "attribute format __scanf__" } */ tformat__scanf__ ("%"); /* { dg-warning "22:format" "attribute format __scanf__" } */
tformatstrftime ("%a"); tformatstrftime ("%a");
tformatstrftime ("%"); /* { dg-warning "format" "attribute format strftime" } */ tformatstrftime ("%"); /* { dg-warning "format" "attribute format strftime" } */
tformat__strftime__ ("%a"); tformat__strftime__ ("%a");
......
...@@ -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 "19:format" "attribute format printf case 0" } */ tformatprintf0 ("%"); /* { dg-warning "20: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 "9:format" "implicit scanf" } */ scanf("%ld", p); /* { dg-warning "12: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 "22:format" "prefix" } */ (*tformatprintf0) ("%"); /* { dg-warning "23: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 "11:has type '.*unsigned int:48'" } */ printf ("%llu", x.u48); /* { dg-warning "15:has type '.*unsigned int:48'" } */
printf ("%llu", (unsigned long long)x.u48); printf ("%llu", (unsigned long long)x.u48);
} }
...@@ -9,19 +9,19 @@ void ...@@ -9,19 +9,19 @@ 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" /* { dg-warning "21:int" "wrong type in conditional expr" } */ printf ((l > 1) ? "%d foos" /* { dg-warning "23:int" "wrong type in conditional expr" } */
: "%d foo", l); /* { dg-warning "14:int" "wrong type in conditional expr" } */ : "%d foo", l); /* { dg-warning "16: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) ? "%ld foos" : "%d foo", l); /* { dg-warning "36:int" "wrong type in conditional expr" } */
printf ((l > 1) ? "%d foos" : "%ld foo", l); /* { dg-warning "21:int" "wrong type in conditional expr" } */ printf ((l > 1) ? "%d foos" : "%ld foo", l); /* { dg-warning "23: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 "38: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 "61:long int" "wrong type" } */ printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%d foo" : "%ld foos"), nfoo); /* { dg-warning "64: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) ? "%ld foos" : ((nfoo > 0) ? "%d foo" : "%d foos"), nfoo); /* { dg-warning "27:long int" "wrong type" } */
printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%ld foo" : "%d foos"), nfoo); /* { dg-warning "50:long int" "wrong type" } */ printf ((nfoo > 1) ? "%d foos" : ((nfoo > 0) ? "%ld foo" : "%d foos"), nfoo); /* { dg-warning "53:long int" "wrong type" } */
/* Extra arguments to NULL should be complained about. */ /* Extra arguments to NULL should be complained about. */
printf (0, "foo"); /* { dg-warning "14:too many" "NULL extra args" } */ printf (0, "foo"); /* { dg-warning "14:too many" "NULL extra args" } */
/* { dg-warning "null" "null format arg" { target *-*-* } 26 } */ /* { dg-warning "null" "null format arg" { target *-*-* } 26 } */
......
...@@ -34,28 +34,35 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -34,28 +34,35 @@ 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 "11:width" "width with %n" } */ printf ("%5n\n", n); /* { dg-warning "14: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 "11:format|precision" "negative precision warning" } */ printf ("%.-5d\n", i); /* { dg-warning "14:format|precision" "negative precision warning" } */
printf ("%.-*d\n", i); /* { dg-warning "11:format" "broken %.-*d format" } */ /* { dg-warning "too many arguments for format" "too many arguments" { target *-*-* } 44 } */
printf ("%.3c\n", i); /* { dg-warning "11:precision" "precision with %c" } */ printf ("%.-*d\n", i); /* { dg-warning "14:format" "broken %.-*d format" } */
printf ("%.3p\n", p); /* { dg-warning "11:precision" "precision with %p" } */ /* { dg-warning "too many arguments for format" "too many arguments" { target *-*-* } 46 } */
printf ("%.3n\n", n); /* { dg-warning "11:precision" "precision with %n" } */ printf ("%.3c\n", i); /* { dg-warning "15:precision" "precision with %c" } */
printf ("%.3p\n", p); /* { dg-warning "15:precision" "precision with %p" } */
printf ("%.3n\n", n); /* { dg-warning "15: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 "11:format" "bogus %%" } */ printf ("%.3%"); /* { dg-warning "14:type" "missing type" } */
printf ("%-%"); /* { dg-warning "11:format" "bogus %%" } */ /* { dg-warning "15:trailing" "bogus %%" { target *-*-* } 56 } */
printf ("%-%\n"); /* { dg-warning "11:format" "bogus %%" } */ printf ("%-%"); /* { dg-warning "13:type" "missing type" } */
printf ("%5%\n"); /* { dg-warning "11:format" "bogus %%" } */ /* { dg-warning "14:trailing" "bogus %%" { target *-*-* } 58 } */
printf ("%h%\n"); /* { dg-warning "11:format" "bogus %%" } */ printf ("%-%\n"); /* { dg-warning "13:format" "bogus %%" } */
/* { dg-warning "15:format" "bogus %%" { target *-*-* } 60 } */
printf ("%5%\n"); /* { dg-warning "13:format" "bogus %%" } */
/* { dg-warning "15:format" "bogus %%" { target *-*-* } 62 } */
printf ("%h%\n"); /* { dg-warning "13:format" "bogus %%" } */
/* { dg-warning "15:format" "bogus %%" { target *-*-* } 64 } */
/* 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 +74,30 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -67,30 +74,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 "11:length" "bad use of %h" } */ printf (" %hf", d); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%he", d); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %he", d); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%hE", d); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %hE", d); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%hg", d); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %hg", d); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%hG", d); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %hG", d); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%hc", i); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %hc", i); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%hs", s); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %hs", s); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%hp", p); /* { dg-warning "11:length" "bad use of %h" } */ printf (" %hp", p); /* { dg-warning "15:length" "bad use of %h" } */
printf ("%h"); /* { dg-warning "11:conversion lacks type" "bare %h" } */ printf (" %h"); /* { dg-warning "14:conversion lacks type" "bare %h" } */
printf ("%h."); /* { dg-warning "11:conversion" "bogus %h." } */ printf (" %h."); /* { dg-warning "15: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 "11:length|C" "bad use of %l" } */ printf (" %lf", d); /* { dg-warning "15:length|C" "bad use of %l" } */
printf ("%le", d); /* { dg-warning "11:length|C" "bad use of %l" } */ printf (" %le", d); /* { dg-warning "15:length|C" "bad use of %l" } */
printf ("%lE", d); /* { dg-warning "11:length|C" "bad use of %l" } */ printf (" %lE", d); /* { dg-warning "15:length|C" "bad use of %l" } */
printf ("%lg", d); /* { dg-warning "11:length|C" "bad use of %l" } */ printf (" %lg", d); /* { dg-warning "15:length|C" "bad use of %l" } */
printf ("%lG", d); /* { dg-warning "11:length|C" "bad use of %l" } */ printf (" %lG", d); /* { dg-warning "15:length|C" "bad use of %l" } */
printf ("%lp", p); /* { dg-warning "11:length|C" "bad use of %l" } */ printf (" %lp", p); /* { dg-warning "15: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 "11:length|C" "C90 bad use of %l" } */ printf ("%lc", lc); /* { dg-warning "14:length|C" "C90 bad use of %l" } */
printf ("%ls", ls); /* { dg-warning "11:length|C" "C90 bad use of %l" } */ printf ("%ls", ls); /* { dg-warning "14: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,63 +105,63 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -98,63 +105,63 @@ 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 "11:does not support" "bad use of %L" } */ printf ("%Ld", ll); /* { dg-warning "14:does not support" "bad use of %L" } */
printf ("%Li", ll); /* { dg-warning "11:does not support" "bad use of %L" } */ printf ("%Li", ll); /* { dg-warning "14:does not support" "bad use of %L" } */
printf ("%Lo", ull); /* { dg-warning "11:does not support" "bad use of %L" } */ printf ("%Lo", ull); /* { dg-warning "14:does not support" "bad use of %L" } */
printf ("%Lu", ull); /* { dg-warning "11:does not support" "bad use of %L" } */ printf ("%Lu", ull); /* { dg-warning "14: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 "14: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 "14:does not support" "bad use of %L" } */
printf ("%Lc", i); /* { dg-warning "11:length" "bad use of %L" } */ printf ("%Lc", i); /* { dg-warning "14:length" "bad use of %L" } */
printf ("%Ls", s); /* { dg-warning "11:length" "bad use of %L" } */ printf ("%Ls", s); /* { dg-warning "14:length" "bad use of %L" } */
printf ("%Lp", p); /* { dg-warning "11:length" "bad use of %L" } */ printf ("%Lp", p); /* { dg-warning "14:length" "bad use of %L" } */
printf ("%Ln", n); /* { dg-warning "11:length" "bad use of %L" } */ printf ("%Ln", n); /* { dg-warning "14: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 "11:flag" "bad use of %-n" } */ printf ("%-n", n); /* { dg-warning "14: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 "11:flag" "bad use of + flag" } */ printf ("%+o", u); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+u", u); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+u", u); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+x", u); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+x", u); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+X", u); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+X", u); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+c", i); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+c", i); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+s", s); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+s", s); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+p", p); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+p", p); /* { dg-warning "14:flag" "bad use of + flag" } */
printf ("%+n", n); /* { dg-warning "11:flag" "bad use of + flag" } */ printf ("%+n", n); /* { dg-warning "14: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 "11: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 "11: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 "11:flag" "bad use of space flag" } */ printf ("% o", u); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% u", u); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% u", u); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% x", u); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% x", u); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% X", u); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% X", u); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% c", i); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% c", i); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% s", s); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% s", s); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% p", p); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% p", p); /* { dg-warning "14:flag" "bad use of space flag" } */
printf ("% n", n); /* { dg-warning "11:flag" "bad use of space flag" } */ printf ("% n", n); /* { dg-warning "14: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 "11:flag" "bad use of # flag" } */ printf ("%#d", i); /* { dg-warning "14:flag" "bad use of # flag" } */
printf ("%#i", i); /* { dg-warning "11:flag" "bad use of # flag" } */ printf ("%#i", i); /* { dg-warning "14:flag" "bad use of # flag" } */
printf ("%#u", u); /* { dg-warning "11:flag" "bad use of # flag" } */ printf ("%#u", u); /* { dg-warning "14:flag" "bad use of # flag" } */
printf ("%#c", i); /* { dg-warning "11:flag" "bad use of # flag" } */ printf ("%#c", i); /* { dg-warning "14:flag" "bad use of # flag" } */
printf ("%#s", s); /* { dg-warning "11:flag" "bad use of # flag" } */ printf ("%#s", s); /* { dg-warning "14:flag" "bad use of # flag" } */
printf ("%#p", p); /* { dg-warning "11:flag" "bad use of # flag" } */ printf ("%#p", p); /* { dg-warning "14:flag" "bad use of # flag" } */
printf ("%#n", n); /* { dg-warning "11:flag" "bad use of # flag" } */ printf ("%#n", n); /* { dg-warning "14: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 "11:flag" "bad use of 0 flag" } */ printf ("%0c", i); /* { dg-warning "14:flag" "bad use of 0 flag" } */
printf ("%0s", s); /* { dg-warning "11:flag" "bad use of 0 flag" } */ printf ("%0s", s); /* { dg-warning "14:flag" "bad use of 0 flag" } */
printf ("%0p", p); /* { dg-warning "11:flag" "bad use of 0 flag" } */ printf ("%0p", p); /* { dg-warning "14:flag" "bad use of 0 flag" } */
printf ("%0n", n); /* { dg-warning "11:flag" "bad use of 0 flag" } */ printf ("%0n", n); /* { dg-warning "14: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 "11: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 "11:ignored" "0 flag ignored with precision" } */ printf ("%08.5i", i); /* { dg-warning "11:ignored" "0 flag ignored with precision" } */
...@@ -176,13 +183,13 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -176,13 +183,13 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
printf ("%-08g", d); /* { dg-warning "11: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 "11: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 "11:format" "bad argument types" } */ printf ("%d", l); /* { dg-warning "13:format" "bad argument types" } */
printf ("%*.*d", l, i2, i); /* { dg-warning "11:field" "bad * argument types" } */ printf ("%*.*d", l, i2, i); /* { dg-warning "13:field" "bad * argument types" } */
printf ("%*.*d", i1, l, i); /* { dg-warning "11:field" "bad * argument types" } */ printf ("%*.*d", i1, l, i); /* { dg-warning "15:field" "bad * argument types" } */
printf ("%ld", i); /* { dg-warning "11:format" "bad argument types" } */ printf ("%ld", i); /* { dg-warning "14:format" "bad argument types" } */
printf ("%s", n); /* { dg-warning "11:format" "bad argument types" } */ printf ("%s", n); /* { dg-warning "13:format" "bad argument types" } */
printf ("%p", i); /* { dg-warning "11:format" "bad argument types" } */ printf ("%p", i); /* { dg-warning "13:format" "bad argument types" } */
printf ("%n", p); /* { dg-warning "11:format" "bad argument types" } */ printf ("%n", p); /* { dg-warning "13: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 +203,9 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -196,9 +203,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 "11:format" "bad argument types" } */ printf ("%p", foo); /* { dg-warning "13:format" "bad argument types" } */
printf ("%n", un); /* { dg-warning "11:format" "bad argument types" } */ printf ("%n", un); /* { dg-warning "13:format" "bad argument types" } */
printf ("%p", n); /* { dg-warning "11:format" "bad argument types" } */ printf ("%p", n); /* { dg-warning "13: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 +214,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -207,7 +214,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 "11:format" "bad argument types" } */ printf ("%s", p); /* { dg-warning "13: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 +227,22 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p, ...@@ -220,18 +227,22 @@ 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 "11:matching" "wrong number of args" } */ printf ("%d%d", i); /* { dg-warning "15:matching" "wrong number of args" } */
printf ("%d", i, i); /* { dg-warning "11: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 "11:zero-length" "warning for empty format" } */ printf (""); /* { dg-warning "11:zero-length" "warning for empty format" } */
printf ("\0"); /* { dg-warning "11:embedded" "warning for embedded NUL" } */ printf ("\0"); /* { dg-warning "12:embedded" "warning for embedded NUL" } */
printf ("%d\0", i); /* { dg-warning "11:embedded" "warning for embedded NUL" } */ printf ("%d\0", i); /* { dg-warning "14:embedded" "warning for embedded NUL" } */
printf ("%d\0%d", i, i); /* { dg-warning "11:embedded|too many" "warning for embedded NUL" } */ printf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */
printf (NULL); /* { dg-warning "3:null" "null format string warning" } */ printf (NULL); /* { dg-warning "3:null" "null format string warning" } */
printf ("%"); /* { dg-warning "11:trailing" "trailing % warning" } */ printf ("%"); /* { dg-warning "12:trailing" "trailing % warning" } */
printf ("%++d", i); /* { dg-warning "11:repeated" "repeated flag warning" } */ printf ("%++d", i); /* { dg-warning "14:repeated" "repeated flag warning" } */
printf ("%n", cn); /* { dg-warning "3:constant" "%n with const" } */ printf ("%n", cn); /* { dg-warning "3:constant" "%n with const" } */
printf ((const char *)L"foo"); /* { dg-warning "25:wide" "wide string" } */ printf ((const char *)L"foo"); /* { dg-warning "25:wide" "wide string" } */
printf ("%n", (int *)0); /* { dg-warning "3:null" "%n with NULL" } */ printf ("%n", (int *)0); /* { dg-warning "3:null" "%n with NULL" } */
printf ("%s", (char *)0); /* { dg-warning "3:null" "%s with NULL" } */ printf ("%s", (char *)0); /* { dg-warning "3:null" "%s with NULL" } */
/* Test for correct column locations within strings with embedded
escape sequences. */
printf ("\\\a\n \"\t%5n\n", n); /* { dg-warning "25:width" "width with %n" } */
printf ("\\a\\n%5n\n", n); /* { dg-warning "20:width" "width with %n" } */
} }
...@@ -15,7 +15,7 @@ f (void) ...@@ -15,7 +15,7 @@ f (void)
/* 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 ( printf (
"%s", 1); /* { dg-warning "6:format" } */ "%s", 1); /* { dg-warning "8: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