Commit 5d93da1d by Martin Sebor Committed by Martin Sebor

PR middle-end/78703 -fprintf-return-value floating point handling incorrect in…

PR middle-end/78703 -fprintf-return-value floating point handling incorrect in locales with a mulltibyte decimal point

gcc/ChangeLog:
	PR middle-end/78703
	* gimple-ssa-sprintf.c (struct result_range): Add likely and
	unlikely counters.
	(struct format_result): Replace number_chars, number_chars_min,
	and number_chars_max with a single member of struct result_range.
	Remove bounded.
	(format_result::operator+=): Adjust.
	(struct fmtresult): Remove bounded.  Handle likely and unlikely
	counters.
	(fmtresult::adjust_for_width_or_precision): New function.
	(fmtresult:type_max_digits): New function.
	(bytes_remaining): Handle likely and unlikely counters.
	(min_bytes_remaining): Remove.
	(format_percent): Simplify.
	(format_integer, format_floating): Set likely and unlikely counters.
	(get_string_length, format_character, format_string): Same.
	(format_plain, should_warn_p): New function.
	(maybe_warn): Call should_warn_p.  Update diagnostic messages
	and handle those for all directives, including plain strings.
	(format_directive): Handle likely and unlikely counters.
	Remove unnecessary quoting from diagnostics.  Add an informational
	note.
	(add_bytes): Remove.
	(pass_sprintf_length::compute_format_length): Simplify.
	(try_substitute_return_value): Handle likely and unlikely counters.

gcc/testsuite/ChangeLog:

	PR middle-end/78703
	* gcc.dg/format/pr78569.c: Adjust.
	* gcc.dg/tree-ssa/builtin-snprintf-warn-2.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-2.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-5.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-2.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-3.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-4.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-6.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-7.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf-warn-9.c: Same.
	* gcc.dg/tree-ssa/builtin-sprintf.c: Same.

From-SVN: r244953
parent c8699672
2017-01-26 Martin Sebor <msebor@redhat.com>
PR middle-end/78703
* gimple-ssa-sprintf.c (struct result_range): Add likely and
unlikely counters.
(struct format_result): Replace number_chars, number_chars_min,
and number_chars_max with a single member of struct result_range.
Remove bounded.
(format_result::operator+=): Adjust.
(struct fmtresult): Remove bounded. Handle likely and unlikely
counters.
(fmtresult::adjust_for_width_or_precision): New function.
(fmtresult:type_max_digits): New function.
(bytes_remaining): Handle likely and unlikely counters.
(min_bytes_remaining): Remove.
(format_percent): Simplify.
(format_integer, format_floating): Set likely and unlikely counters.
(get_string_length, format_character, format_string): Same.
(format_plain, should_warn_p): New function.
(maybe_warn): Call should_warn_p. Update diagnostic messages
and handle those for all directives, including plain strings.
(format_directive): Handle likely and unlikely counters.
Remove unnecessary quoting from diagnostics. Add an informational
note.
(add_bytes): Remove.
(pass_sprintf_length::compute_format_length): Simplify.
(try_substitute_return_value): Handle likely and unlikely counters.
2017-01-26 Carl Love <cel@us.ibm.com> 2017-01-26 Carl Love <cel@us.ibm.com>
* config/rs6000/rs6000-c (altivec_overloaded_builtins): Remove * config/rs6000/rs6000-c (altivec_overloaded_builtins): Remove
......
2017-01-26 Martin Sebor <msebor@redhat.com>
PR middle-end/78703
* gcc.dg/format/pr78569.c: Adjust.
* gcc.dg/tree-ssa/builtin-snprintf-warn-2.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-2.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-5.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-2.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-3.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-4.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-6.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-7.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf-warn-9.c: Same.
* gcc.dg/tree-ssa/builtin-sprintf.c: Same.
2017-01-26 Jakub Jelinek <jakub@redhat.com> 2017-01-26 Jakub Jelinek <jakub@redhat.com>
PR c++/68727 PR c++/68727
......
...@@ -20,5 +20,5 @@ void test (void) ...@@ -20,5 +20,5 @@ void test (void)
"channel uplink (see section 7.6.1)."); "channel uplink (see section 7.6.1).");
/* { dg-warning "output truncated" "" { target *-*-* } 7 } */ /* { dg-warning "output truncated" "" { target *-*-* } 7 } */
/* { dg-message "format output" "" { target *-*-* } 6 } */ /* { dg-message "output" "" { target *-*-* } 6 } */
} }
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
typedef struct typedef struct
{ {
char a0[0]; char a0[0];
/* Separate a0 from a1 to prevent the former from being substituted
for the latter and causing false positives. */
int: 8;
char a1[1]; char a1[1];
char a2[2]; char a2[2];
char a3[3]; char a3[3];
...@@ -39,7 +42,9 @@ void test_int_retval_unused (void) ...@@ -39,7 +42,9 @@ void test_int_retval_unused (void)
void test_string_retval_unused (const Arrays *ar) void test_string_retval_unused (const Arrays *ar)
{ {
T (1, "%-s", ar->a0); /* At level 2 strings of unknown length are assumed to be 1 character
long, so the following is diagnosed. */
T (1, "%-s", ar->a0); /* { dg-warning "output may be truncated" } */
T (1, "%-s", ar->a1); T (1, "%-s", ar->a1);
T (1, "%-s", ar->a2); /* { dg-warning "output may be truncated" } */ T (1, "%-s", ar->a2); /* { dg-warning "output may be truncated" } */
} }
...@@ -64,7 +69,7 @@ void test_int_retval_used (void) ...@@ -64,7 +69,7 @@ void test_int_retval_used (void)
void test_string_retval_used (const Arrays *ar) void test_string_retval_used (const Arrays *ar)
{ {
T (1, "%-s", ar->a0); T (1, "%-s", ar->a0); /* { dg-warning "output may be truncated" } */
T (1, "%-s", ar->a1); T (1, "%-s", ar->a1);
T (1, "%-s", ar->a2); /* { dg-warning "output may be truncated" } */ T (1, "%-s", ar->a2); /* { dg-warning "output may be truncated" } */
} }
...@@ -59,15 +59,15 @@ void must_not_eliminate (void); ...@@ -59,15 +59,15 @@ void must_not_eliminate (void);
typedef __SIZE_TYPE__ size_t; typedef __SIZE_TYPE__ size_t;
extern int i; volatile int i;
extern unsigned u; volatile unsigned u;
extern long li; volatile long li;
extern unsigned long lu; volatile unsigned long lu;
extern size_t sz; volatile size_t sz;
extern char *str; volatile char *str;
extern double d; volatile double d;
extern long double ld; volatile long double ld;
/* Verify that overflowing the destination object disables the return /* Verify that overflowing the destination object disables the return
value optimization. */ value optimization. */
...@@ -280,7 +280,8 @@ RNG (0, 6, 8, "%s%ls", "1", L"2"); ...@@ -280,7 +280,8 @@ RNG (0, 6, 8, "%s%ls", "1", L"2");
*/ */
/* Only conditional calls to abort should be made (with any probability): /* Only conditional calls to must_not_eliminate must be made (with
any probability):
{ dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]:\n *must_not_eliminate" 124 "optimized" { target { ilp32 || lp64 } } } } { dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]:\n *must_not_eliminate" 124 "optimized" { target { ilp32 || lp64 } } } }
{ dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]:\n *must_not_eliminate" 93 "optimized" { target { { ! ilp32 } && { ! lp64 } } } } } { dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]:\n *must_not_eliminate" 93 "optimized" { target { { ! ilp32 } && { ! lp64 } } } } }
No unconditional calls to abort should be made: No unconditional calls to abort should be made:
......
...@@ -136,7 +136,6 @@ void test_arg_string (const char *s) ...@@ -136,7 +136,6 @@ void test_arg_string (const char *s)
void test_arg_multiarg (int i, double d) void test_arg_multiarg (int i, double d)
{ {
EQL (16, "%i %f %s", 123, 3.14, "abc");
EQL (16, "%12i %s", i, "abc"); EQL (16, "%12i %s", i, "abc");
EQL (16, "%*i %s", 12, i, "abc"); EQL (16, "%*i %s", 12, i, "abc");
} }
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-std=c99 -Wformat -Wformat-overflow=2 -ftrack-macro-expansion=0" } */ /* { dg-options "-Wformat -Wformat-overflow=2 -ftrack-macro-expansion=0" } */
/* When debugging, define LINE to the line number of the test case to exercise /* When debugging, define LINE to the line number of the test case to exercise
and avoid exercising any of the others. The buffer and objsize macros and avoid exercising any of the others. The buffer and objsize macros
...@@ -47,12 +47,16 @@ void test_s_const (void) ...@@ -47,12 +47,16 @@ void test_s_const (void)
T (1, "%*ls", 0, L"\0"); T (1, "%*ls", 0, L"\0");
T (1, "%*ls", 1, L""); /* { dg-warning "nul past the end" } */ T (1, "%*ls", 1, L""); /* { dg-warning "nul past the end" } */
T (1, "%ls", L"1"); /* { dg-warning "directive writing between 1 and 6 bytes into a region of size 1" } */ /* A wide character converts into between zero and MB_LEN_MAX bytes
(although individual ASCII characters are assumed to convert into
1 bt %lc so this could be made smarter. */
T (1, "%ls", L"1"); /* { dg-warning "directive writing up to 6 bytes into a region of size 1" } */
T (1, "%.0ls", L"1"); T (1, "%.0ls", L"1");
T (2, "%.0ls", L"1"); T (2, "%.0ls", L"1");
T (2, "%.1ls", L"1"); T (2, "%.1ls", L"1");
T (2, "%.2ls", L"1"); /* { dg-warning "nul past the end" } */ T (2, "%.2ls", L"1"); /* { dg-warning "nul past the end" } */
T (2, "%.3ls", L"1"); /* { dg-warning "directive writing between 1 and 3 bytes into a region of size 2" } */ T (2, "%.3ls", L"1"); /* { dg-warning "directive writing up to 3 bytes into a region of size 2" } */
T (2, "%.7ls", L"1"); /* { dg-warning "directive writing up to 6 bytes into a region of size 2" } */
T (2, "%.2ls", L"12"); /* { dg-warning "nul past the end" } */ T (2, "%.2ls", L"12"); /* { dg-warning "nul past the end" } */
/* The "%.2ls" directive below will write at a minimum 1 byte (because /* The "%.2ls" directive below will write at a minimum 1 byte (because
...@@ -71,8 +75,8 @@ void test_s_const (void) ...@@ -71,8 +75,8 @@ void test_s_const (void)
T (3, "%.3ls", L"12"); /* { dg-warning "nul past the end" } */ T (3, "%.3ls", L"12"); /* { dg-warning "nul past the end" } */
T (4, "%.3ls", L"123"); T (4, "%.3ls", L"123");
T (4, "%.4ls", L"123"); /* { dg-warning "nul past the end" } */ T (4, "%.4ls", L"123"); /* { dg-warning "nul past the end" } */
T (4, "%.5ls", L"123"); /* { dg-warning "directive writing between 3 and 5 bytes into a region of size 4" } */ T (4, "%.5ls", L"123"); /* { dg-warning "directive writing up to 5 bytes into a region of size 4" } */
T (4, "%.6ls", L"123"); /* { dg-warning "directive writing between 3 and 6 bytes into a region of size 4" } */ T (4, "%.6ls", L"123"); /* { dg-warning "directive writing up to 6 bytes into a region of size 4" } */
} }
...@@ -87,37 +91,48 @@ struct Arrays { ...@@ -87,37 +91,48 @@ struct Arrays {
/* Exercise buffer overflow detection with non-const string arguments. */ /* Exercise buffer overflow detection with non-const string arguments. */
void test_s_nonconst (const char *s, const wchar_t *ws, struct Arrays *a) void test_s_nonconst (int w, int p, const char *s, const wchar_t *ws,
struct Arrays *a)
{ {
T (0, "%s", s); /* { dg-warning "into a region" "sprintf transformed into strcpy" { xfail *-*-* } } */ T (0, "%s", s); /* { dg-warning "into a region" "sprintf transformed into strcpy" { xfail *-*-* } } */
T (1, "%s", s); /* { dg-warning "nul past the end" "sprintf transformed into strcpy" { xfail *-*-* } } */ T (1, "%s", s); /* { dg-warning "nul past the end" "sprintf transformed into strcpy" { xfail *-*-* } } */
T (1, "%1s", s); /* { dg-warning "nul past the end" } */ T (1, "%1s", s); /* { dg-warning "writing a terminating nul" } */
T (1, "%.0s", s); T (1, "%.0s", s);
T (1, "%.1s", s); /* { dg-warning "may write a terminating nul" } */ T (1, "%.1s", s); /* { dg-warning "may write a terminating nul" } */
T (1, "%*s", 0, s); /* { dg-warning "may write a terminating nul" } */
T (1, "%*s", 1, s); /* { dg-warning "writing a terminating nul" } */
T (1, "%*s", 2, s); /* { dg-warning "directive writing 2 or more bytes" } */
T (1, "%*s", 3, s); /* { dg-warning "directive writing 3 or more bytes" } */
T (1, "%.*s", 1, s); /* { dg-warning "may write a terminating nul" } */
T (1, "%.*s", 2, s); /* { dg-warning "writing up to 2 bytes" } */
T (1, "%.*s", 3, s); /* { dg-warning "writing up to 3 bytes" } */
T (1, "%.0ls", ws); T (1, "%.0ls", ws);
T (1, "%.1ls", ws); /* { dg-warning "may write a terminating nul" } */ T (1, "%.1ls", ws); /* { dg-warning "may write a terminating nul" } */
T (1, "%ls", ws); /* { dg-warning "writing a terminating nul" } */ T (1, "%ls", ws); /* { dg-warning "may write a terminating nul" } */
/* Verify that the size of the array is used in lieu of its length. /* Verify that the size of the array is used in lieu of its length.
The minus sign disables GCC's sprintf to strcpy transformation. */ The minus sign disables GCC's sprintf to strcpy transformation.
T (1, "%-s", a->a1); /* { dg-warning "nul past the end" } */ In the case below, the length of s->a1 can be at most zero, so
the call should not be diagnosed. */
T (1, "%-s", a->a1);
/* In the following test, since the length of the strings isn't known, /* In the following test, since the length of the strings isn't known,
their type (the array) is used to bound the maximum length to 1, their type (the array) is used to bound the maximum length to 1,
which means the "%-s" directive would not overflow the buffer, which means the "%-s" directive would not overflow the buffer,
but it would leave no room for the terminating nul. */ but it would leave no room for the terminating nul. */
T (1, "%-s", a->a2); /* { dg-warning "writing a terminating nul" } */ T (1, "%-s", a->a2); /* { dg-warning "may write a terminating nul" } */
/* Unlike in the test above, since the length of the string is bounded /* Unlike in the test above, since the length of the string is bounded
by the array type to at most 2, the "^-s" directive is diagnosed firts, by the array type to at most 2, the "^-s" directive is diagnosed firts,
preventing the diagnostic about the terminatinb nul. */ preventing the diagnostic about the terminatinb nul. */
T (1, "%-s", a->a3); /* { dg-warning "directive writing between 1 and 2 bytes" } */ T (1, "%-s", a->a3); /* { dg-warning "directive writing up to 2 bytes" } */
/* The length of a zero length array and flexible array member is /* The length of a zero length array and flexible array member is
unknown and at leve 2 assumed to be at least 1. */ unknown and at leve 2 assumed to be at least 1. */
T (1, "%-s", a->a0); /* { dg-warning "nul past the end" } */ T (1, "%-s", a->a0); /* { dg-warning "may write a terminating nul" } */
T (1, "%-s", a->ax); /* { dg-warning "nul past the end" } */ T (1, "%-s", a->ax); /* { dg-warning "may write a terminating nul" } */
T (2, "%-s", a->a0); T (2, "%-s", a->a0);
T (2, "%-s", a->ax); T (2, "%-s", a->ax);
...@@ -145,20 +160,20 @@ void test_hh_nonconst (int w, int p, int x, unsigned y) ...@@ -145,20 +160,20 @@ void test_hh_nonconst (int w, int p, int x, unsigned y)
/* Zero precision means that zero argument formats as no bytes unless /* Zero precision means that zero argument formats as no bytes unless
length or flags make it otherwise. */ length or flags make it otherwise. */
T (1, "%.*hhi", 0, x); /* { dg-warning "between 0 and 4 bytes" } */ T (1, "%.*hhi", 0, x); /* { dg-warning "writing up to 4 bytes" } */
T (2, "%.*hhi", 0, x); /* { dg-warning "between 0 and 4 bytes" } */ T (2, "%.*hhi", 0, x); /* { dg-warning "writing up to 4 bytes" } */
T (3, "%.*hhi", 0, x); /* { dg-warning "between 0 and 4 bytes" } */ T (3, "%.*hhi", 0, x); /* { dg-warning "writing up to 4 bytes" } */
T (4, "%.*hhi", 0, x); /* { dg-warning "may write a terminating nul past the end of the destination" } */ T (4, "%.*hhi", 0, x); /* { dg-warning "may write a terminating nul past the end of the destination" } */
T (1, "%.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */ T (1, "%.*hhi", 0, y); /* { dg-warning "writing up to 4 bytes" } */
T (2, "%.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */ T (2, "%.*hhi", 0, y); /* { dg-warning "writing up to 4 bytes" } */
T (3, "%.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */ T (3, "%.*hhi", 0, y); /* { dg-warning "writing up to 4 bytes" } */
T (4, "%.*hhi", 0, y); /* { dg-warning "may write a terminating nul past the end of the destination" } */ T (4, "%.*hhi", 0, y); /* { dg-warning "may write a terminating nul past the end of the destination" } */
T (1, "%#.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */ T (1, "%#.*hhi", 0, y); /* { dg-warning "writing up to 4 bytes" } */
/* { dg-warning ".#. flag used" "-Wformat" { target *-*-* } .-1 } */ /* { dg-warning ".#. flag used" "-Wformat" { target *-*-* } .-1 } */
T (1, "%+.*hhi", 0, y); /* { dg-warning "between 1 and 4 bytes" } */ T (1, "%+.*hhi", 0, y); /* { dg-warning "between 1 and 4 bytes" } */
T (1, "%-.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */ T (1, "%-.*hhi", 0, y); /* { dg-warning "writing up to 4 bytes" } */
T (1, "% .*hhi", 0, y); /* { dg-warning "between 1 and 4 bytes" } */ T (1, "% .*hhi", 0, y); /* { dg-warning "between 1 and 4 bytes" } */
T (1, "%#.*hhi", 1, y); /* { dg-warning "between 1 and 4 bytes" } */ T (1, "%#.*hhi", 1, y); /* { dg-warning "between 1 and 4 bytes" } */
...@@ -167,18 +182,18 @@ void test_hh_nonconst (int w, int p, int x, unsigned y) ...@@ -167,18 +182,18 @@ void test_hh_nonconst (int w, int p, int x, unsigned y)
T (1, "%-.*hhi", 1, y); /* { dg-warning "between 1 and 4 bytes" } */ T (1, "%-.*hhi", 1, y); /* { dg-warning "between 1 and 4 bytes" } */
T (1, "% .*hhi", 1, y); /* { dg-warning "between 2 and 4 bytes" } */ T (1, "% .*hhi", 1, y); /* { dg-warning "between 2 and 4 bytes" } */
T (1, "%#.*hhi", p, y); /* { dg-warning "writing 0 or more bytes" } */ T (1, "%#.*hhi", p, y); /* { dg-warning "writing up to \[0-9\]+ bytes" } */
/* { dg-warning ".#. flag used" "-Wformat" { target *-*-* } .-1 } */ /* { dg-warning ".#. flag used" "-Wformat" { target *-*-* } .-1 } */
T (1, "%+.*hhi", p, y); /* { dg-warning "writing 1 or more bytes" } */ T (1, "%+.*hhi", p, y); /* { dg-warning "writing 1 or more bytes|writing between 1 and \[0-9\]+ bytes" } */
T (1, "%-.*hhi", p, y); /* { dg-warning "writing 0 or more bytes" } */ T (1, "%-.*hhi", p, y); /* { dg-warning "writing up to \[0-9\]+ bytes" } */
T (1, "% .*hhi", p, y); /* { dg-warning "writing 1 or more bytes" } */ T (1, "% .*hhi", p, y); /* { dg-warning "writing between 1 and \[0-9\]+ bytes|writing 1 or more bytes" } */
T (1, "%#.*hhu", 0, y); /* { dg-warning "between 0 and 3 bytes" } */ T (1, "%#.*hhu", 0, y); /* { dg-warning "writing up to 3 bytes" } */
/* { dg-warning ".#. flag used" "-Wformat" { target *-*-* } .-1 } */ /* { dg-warning ".#. flag used" "-Wformat" { target *-*-* } .-1 } */
T (1, "%+.*hhu", 0, y); /* { dg-warning "between 0 and 3 bytes" } */ T (1, "%+.*hhu", 0, y); /* { dg-warning "writing up to 3 bytes" } */
/* { dg-warning ".\\+. flag used" "-Wformat" { target *-*-* } .-1 } */ /* { dg-warning ".\\+. flag used" "-Wformat" { target *-*-* } .-1 } */
T (1, "%-.*hhu", 0, y); /* { dg-warning "between 0 and 3 bytes" } */ T (1, "%-.*hhu", 0, y); /* { dg-warning "writing up to 3 bytes" } */
T (1, "% .*hhu", 0, y); /* { dg-warning "between 0 and 3 bytes" } */ T (1, "% .*hhu", 0, y); /* { dg-warning "writing up to 3 bytes" } */
/* { dg-warning ". . flag used" "-Wformat" { target *-*-* } .-1 } */ /* { dg-warning ". . flag used" "-Wformat" { target *-*-* } .-1 } */
} }
......
...@@ -60,6 +60,9 @@ void test_sprintf_chk_string (const char *s, const char *t) ...@@ -60,6 +60,9 @@ void test_sprintf_chk_string (const char *s, const char *t)
T (1, "%s", x ? "1" : ""); /* { dg-warning "nul past the end" } */ T (1, "%s", x ? "1" : ""); /* { dg-warning "nul past the end" } */
T (1, "%s", x ? s : "1"); /* { dg-warning "nul past the end" } */ T (1, "%s", x ? s : "1"); /* { dg-warning "nul past the end" } */
T (1, "%s", x ? "1" : s); /* { dg-warning "nul past the end" } */ T (1, "%s", x ? "1" : s); /* { dg-warning "nul past the end" } */
/* When neither string is known no warning should be issued at level 1
since their lenghts are assumed to be zero. */
T (1, "%s", x ? s : t); T (1, "%s", x ? s : t);
T (2, "%s", x ? "" : "1"); T (2, "%s", x ? "" : "1");
...@@ -85,7 +88,7 @@ void test_sprintf_chk_integer_value (void) ...@@ -85,7 +88,7 @@ void test_sprintf_chk_integer_value (void)
T ( 1, "%i", i ( 0)); /* { dg-warning "nul past the end" } */ T ( 1, "%i", i ( 0)); /* { dg-warning "nul past the end" } */
T ( 1, "%i", i ( 1)); /* { dg-warning "nul past the end" } */ T ( 1, "%i", i ( 1)); /* { dg-warning "nul past the end" } */
T ( 1, "%i", i ( -1)); /* { dg-warning "into a region" } */ T ( 1, "%i", i ( -1)); /* { dg-warning "into a region" } */
T ( 1, "%i_", i ( 1)); /* { dg-warning "character ._. at offset 2 past the end" } */ T ( 1, "%i_", i ( 1)); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 1, "_%i", i ( 1)); /* { dg-warning "into a region" } */ T ( 1, "_%i", i ( 1)); /* { dg-warning "into a region" } */
T ( 1, "_%i_",i ( 1)); /* { dg-warning "into a region" } */ T ( 1, "_%i_",i ( 1)); /* { dg-warning "into a region" } */
T ( 1, "%o", i ( 0)); /* { dg-warning "nul past the end" } */ T ( 1, "%o", i ( 0)); /* { dg-warning "nul past the end" } */
...@@ -102,7 +105,7 @@ void test_sprintf_chk_integer_value (void) ...@@ -102,7 +105,7 @@ void test_sprintf_chk_integer_value (void)
T ( 2, "%i", i ( 10)); /* { dg-warning "nul past the end" } */ T ( 2, "%i", i ( 10)); /* { dg-warning "nul past the end" } */
T ( 2, "%i_", i ( 0)); /* { dg-warning "nul past the end" } */ T ( 2, "%i_", i ( 0)); /* { dg-warning "nul past the end" } */
T ( 2, "_%i", i ( 0)); /* { dg-warning "nul past the end" } */ T ( 2, "_%i", i ( 0)); /* { dg-warning "nul past the end" } */
T ( 2, "_%i_",i ( 0)); /* { dg-warning "character ._. at offset 3 past the end" } */ T ( 2, "_%i_",i ( 0)); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 2, "%o", i ( 1)); T ( 2, "%o", i ( 1));
T ( 2, "%o", i ( 7)); T ( 2, "%o", i ( 7));
T ( 2, "%o", i ( 010)); /* { dg-warning "nul past the end" } */ T ( 2, "%o", i ( 010)); /* { dg-warning "nul past the end" } */
...@@ -211,10 +214,10 @@ void test_sprintf_chk_range_schar (void) ...@@ -211,10 +214,10 @@ void test_sprintf_chk_range_schar (void)
T ( 3, "%i", R ( 0, 99)); T ( 3, "%i", R ( 0, 99));
T ( 3, "%i", R ( 0, 100)); /* { dg-warning "may write a terminating nul past the end of the destination" } */ T ( 3, "%i", R ( 0, 100)); /* { dg-warning "may write a terminating nul past the end of the destination" } */
/* The following call may write as few as 3 bytes and as many as 5. /* The following call may write as few as 2 bytes and as many as 4.
It's a judgment call how best to diagnose it to make the potential It's a judgment call how best to diagnose it to make the potential
problem clear. */ problem clear. */
T ( 3, "%i%i", R (1, 10), R (9, 10)); /* { dg-warning "may write a terminating nul past the end|.%i. directive writing between 1 and 2 bytes into a region of size 1" } */ T ( 3, "%i%i", R (1, 10), R (9, 10)); /* { dg-warning "directive writing between 1 and 2 bytes into a region of size between 1 and 2" } */
T ( 4, "%i%i", R (10, 11), R (12, 13)); /* { dg-warning "nul past the end" } */ T ( 4, "%i%i", R (10, 11), R (12, 13)); /* { dg-warning "nul past the end" } */
...@@ -224,7 +227,11 @@ void test_sprintf_chk_range_schar (void) ...@@ -224,7 +227,11 @@ void test_sprintf_chk_range_schar (void)
T ( 6, "%i_%i_%i", R (0, 9), R (0, 9), R (0, 10)); /* { dg-warning "may write a terminating nul past the end" } */ T ( 6, "%i_%i_%i", R (0, 9), R (0, 9), R (0, 10)); /* { dg-warning "may write a terminating nul past the end" } */
T ( 6, "%i_%i_%i", R (0, 9), R (0, 10), R (0, 9)); /* { dg-warning "may write a terminating nul past the end" } */ T ( 6, "%i_%i_%i", R (0, 9), R (0, 10), R (0, 9)); /* { dg-warning "may write a terminating nul past the end" } */
T ( 6, "%i_%i_%i", R (0, 10), R (0, 9), R (0, 9)); /* { dg-warning "may write a terminating nul past the end" } */ T ( 6, "%i_%i_%i", R (0, 10), R (0, 9), R (0, 9)); /* { dg-warning "may write a terminating nul past the end" } */
T ( 6, "%i_%i_%i", R (0, 9), R (0, 10), R (0, 10)); /* { dg-warning "may write a terminating nul past the end|.%i. directive writing between 1 and 2 bytes into a region of size 1" } */ T ( 6, "%hhi_%hi_%i", R (0, 9), R (0, 10), R (0, 10)); /* { dg-warning ".i. directive writing between 1 and 2 bytes into a region of size between 1 and 2" } */
T ( 6, "%3i|%2i/%1i", R (0, 99), R (0, 99), R (0, 99)); /* { dg-warning "./. directive writing 1 byte into a region of size 0" } */
T ( 6, "%.3i|%.2i/%i", R (0, 99), R (0, 99), R (0, 99)); /* { dg-warning "./. directive writing 1 byte into a region of size 0" } */
T ( 6, "%.3i|%.2i/%i", R (0, 119), R (0, 99), R (0, 99)); /* { dg-warning "./. directive writing 1 byte into a region of size 0" } */
T ( 6, "%.3i|%.2i/%i", R (0, 1), R (0, 2), R (0, 3)); /* { dg-warning "./. directive writing 1 byte into a region of size 0" } */
} }
void test_sprintf_chk_range_uchar (void) void test_sprintf_chk_range_uchar (void)
......
...@@ -12,14 +12,14 @@ void test (void) ...@@ -12,14 +12,14 @@ void test (void)
The redundant argument is there to get around GCC bug 77799. */ The redundant argument is there to get around GCC bug 77799. */
sprintf (dst + 2, "1", 0); sprintf (dst + 2, "1", 0);
/* { dg-warning "writing a terminating nul past the end of the destination" "nul warning" { target *-*-* } .-1 } /* { dg-warning "writing a terminating nul past the end of the destination" "nul warning" { target *-*-* } .-1 }
{ dg-message "format output 2 bytes into a destination of size 1" "note" { target *-*-* } .-2 } { dg-message ".sprintf. output 2 bytes into a destination of size 1" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat output: redundant argument" } { dg-begin-multiline-output "-Wformat output: redundant argument" }
sprintf (dst + 2, "1", 0); sprintf (dst + 2, "1", 0);
^~~ ^~~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "-Wformat-overflow output" } { dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst + 2, "1", 0); sprintf (dst + 2, "1", 0);
~^ ^
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" } { dg-begin-multiline-output "note" }
sprintf (dst + 2, "1", 0); sprintf (dst + 2, "1", 0);
...@@ -29,15 +29,15 @@ void test (void) ...@@ -29,15 +29,15 @@ void test (void)
/* Verify thet the caret points at the first format character written /* Verify thet the caret points at the first format character written
past the end of the destination. */ past the end of the destination. */
sprintf (dst, "1234", 0); sprintf (dst, "1234", 0);
/* { dg-warning "writing format character .4. at offset 3 past the end of the destination" "nul warning" { target *-*-* } .-1 } /* { dg-warning "writing 4 bytes into a region of size 3" "overlong format string" { target *-*-* } .-1 }
{ dg-message "format output 5 bytes into a destination of size 3" "note" { target *-*-* } .-2 } { dg-message ".sprintf. output 5 bytes into a destination of size 3" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat output: redundant argument" } { dg-begin-multiline-output "-Wformat output: redundant argument" }
sprintf (dst, "1234", 0); sprintf (dst, "1234", 0);
^~~~~~ ^~~~~~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "-Wformat-overflow output" } { dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst, "1234", 0); sprintf (dst, "1234", 0);
^ ~~~^
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" } { dg-begin-multiline-output "note" }
sprintf (dst, "1234", 0); sprintf (dst, "1234", 0);
...@@ -48,15 +48,15 @@ void test (void) ...@@ -48,15 +48,15 @@ void test (void)
past the end of the destination and the rest of the format string past the end of the destination and the rest of the format string
is underlined. */ is underlined. */
sprintf (dst, "12345", 0); sprintf (dst, "12345", 0);
/* { dg-warning "writing format character .4. at offset 3 past the end of the destination" "nul warning" { target *-*-* } .-1 } /* { dg-warning "writing 5 bytes into a region of size 3" "nul warning" { target *-*-* } .-1 }
{ dg-message "format output 6 bytes into a destination of size 3" "note" { target *-*-* } .-2 } { dg-message ".sprintf. output 6 bytes into a destination of size 3" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat output: redundant argument" } { dg-begin-multiline-output "-Wformat output: redundant argument" }
sprintf (dst, "12345", 0); sprintf (dst, "12345", 0);
^~~~~~~ ^~~~~~~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "-Wformat-overflow output" } { dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst, "12345", 0); sprintf (dst, "12345", 0);
^~ ~~~^~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" } { dg-begin-multiline-output "note" }
sprintf (dst, "12345", 0); sprintf (dst, "12345", 0);
...@@ -67,10 +67,10 @@ void test (void) ...@@ -67,10 +67,10 @@ void test (void)
get around GCC bug 77671. */ get around GCC bug 77671. */
sprintf (dst + 2, "%-s", "1"); sprintf (dst + 2, "%-s", "1");
/* { dg-warning "writing a terminating nul past the end of the destination" "warning" { target *-*-* } .-1 } /* { dg-warning "writing a terminating nul past the end of the destination" "warning" { target *-*-* } .-1 }
{ dg-message "format output 2 bytes into a destination of size 1" "note" { target *-*-* } .-2 } { dg-message ".sprintf. output 2 bytes into a destination of size 1" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat-overflow output" } { dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst + 2, "%-s", "1"); sprintf (dst + 2, "%-s", "1");
~~~^ ^
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" } { dg-begin-multiline-output "note" }
sprintf (dst + 2, "%-s", "1"); sprintf (dst + 2, "%-s", "1");
...@@ -79,7 +79,7 @@ void test (void) ...@@ -79,7 +79,7 @@ void test (void)
sprintf (dst + 2, "%-s", "abcd"); sprintf (dst + 2, "%-s", "abcd");
/* { dg-warning ".%-s. directive writing 4 bytes into a region of size 1" "warning" { target *-*-* } .-1 } /* { dg-warning ".%-s. directive writing 4 bytes into a region of size 1" "warning" { target *-*-* } .-1 }
{ dg-message "format output 5 bytes into a destination of size 1" "note" { target *-*-* } .-2 } { dg-message ".sprintf. output 5 bytes into a destination of size 1" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat-overflow output" } { dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst + 2, "%-s", "abcd"); sprintf (dst + 2, "%-s", "abcd");
^~~ ~~~~~~ ^~~ ~~~~~~
...@@ -105,8 +105,8 @@ extern char *ptr; ...@@ -105,8 +105,8 @@ extern char *ptr;
/* Evaluate to an array of SIZE characters when non-negative and LINE /* Evaluate to an array of SIZE characters when non-negative and LINE
is not set or set to the line the macro is on, or to a pointer to is not set or set to the line the macro is on, or to a pointer to
an unknown object otherwise. */ an unknown object otherwise. */
#define buffer(size) \ #define buffer(size) \
(0 <= size && (!LINE || __LINE__ == LINE) \ (0 <= size && (!LINE || __LINE__ == LINE) \
? buffer + sizeof buffer - size : ptr) ? buffer + sizeof buffer - size : ptr)
/* Verify that the note printed along with the diagnostic mentions /* Verify that the note printed along with the diagnostic mentions
...@@ -124,7 +124,7 @@ void test_sprintf_note (void) ...@@ -124,7 +124,7 @@ void test_sprintf_note (void)
^~ ^~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-message "format output 4 bytes into a destination of size 0" "" { target *-*-* } .-7 } { dg-message ".__builtin_sprintf. output 4 bytes into a destination of size 0" "" { target *-*-* } .-7 }
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
__builtin_sprintf (buffer (0), "%c%s%i", '1', "2", 3); __builtin_sprintf (buffer (0), "%c%s%i", '1', "2", 3);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -137,7 +137,7 @@ void test_sprintf_note (void) ...@@ -137,7 +137,7 @@ void test_sprintf_note (void)
^~ ~~~~ ^~ ~~~~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-message "format output 6 bytes into a destination of size 1" "" { target *-*-* } .-7 } { dg-message ".__builtin_sprintf. output 6 bytes into a destination of size 1" "" { target *-*-* } .-7 }
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
__builtin_sprintf (buffer (1), "%c%s%i", '1', "23", 45); __builtin_sprintf (buffer (1), "%c%s%i", '1', "23", 45);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -150,7 +150,7 @@ void test_sprintf_note (void) ...@@ -150,7 +150,7 @@ void test_sprintf_note (void)
^~ ^~
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-message "format output 6 bytes into a destination of size 2" "" { target *-*-* } .-7 } { dg-message ".__builtin_sprintf. output 6 bytes into a destination of size 2" "" { target *-*-* } .-7 }
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
__builtin_sprintf (buffer (2), "%c%s%i", '1', "2", 345); __builtin_sprintf (buffer (2), "%c%s%i", '1', "2", 345);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -160,10 +160,10 @@ void test_sprintf_note (void) ...@@ -160,10 +160,10 @@ void test_sprintf_note (void)
/* { dg-warning "41: writing a terminating nul past the end of the destination" "" { target *-*-* } .-1 } /* { dg-warning "41: writing a terminating nul past the end of the destination" "" { target *-*-* } .-1 }
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
__builtin_sprintf (buffer (6), "%c%s%i", '1', "2", 3456); __builtin_sprintf (buffer (6), "%c%s%i", '1', "2", 3456);
~~~~~~^ ^
{ dg-end-multiline-output "" } { dg-end-multiline-output "" }
{ dg-message "format output 7 bytes into a destination of size 6" "" { target *-*-* } .-7 } { dg-message ".__builtin_sprintf. output 7 bytes into a destination of size 6" "" { target *-*-* } .-7 }
{ dg-begin-multiline-output "" } { dg-begin-multiline-output "" }
__builtin_sprintf (buffer (6), "%c%s%i", '1', "2", 3456); __builtin_sprintf (buffer (6), "%c%s%i", '1', "2", 3456);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -52,7 +52,7 @@ void fuint (unsigned j, char *p) ...@@ -52,7 +52,7 @@ void fuint (unsigned j, char *p)
if (j > 999) if (j > 999)
return; return;
snprintf (p, 4, "%3u", j); /* { dg-bogus "may be truncated" "unsigned int" { xfail *-*-* } } */ snprintf (p, 4, "%3u", j);
} }
void fint (int j, char *p) void fint (int j, char *p)
...@@ -62,7 +62,7 @@ void fint (int j, char *p) ...@@ -62,7 +62,7 @@ void fint (int j, char *p)
if (k > 999) if (k > 999)
return; return;
snprintf (p, 4, "%3u", k); /* { dg-bogus "may be truncated" "signed int" { xfail *-*-* } } */ snprintf (p, 4, "%3u", k);
} }
void fulong (unsigned long j, char *p) void fulong (unsigned long j, char *p)
...@@ -70,7 +70,7 @@ void fulong (unsigned long j, char *p) ...@@ -70,7 +70,7 @@ void fulong (unsigned long j, char *p)
if (j > 999) if (j > 999)
return; return;
snprintf (p, 4, "%3lu", j); /* { dg-bogus "may be truncated" "unsigned long" { xfail *-*-* } } */ snprintf (p, 4, "%3lu", j);
} }
void flong (long j, char *p) void flong (long j, char *p)
...@@ -80,7 +80,7 @@ void flong (long j, char *p) ...@@ -80,7 +80,7 @@ void flong (long j, char *p)
if (k > 999) if (k > 999)
return; return;
snprintf (p, 4, "%3lu", k); /* { dg-bogus "may be truncated" "signed long" { xfail *-*-* } } */ snprintf (p, 4, "%3lu", k);
} }
void fullong (unsigned long long j, char *p) void fullong (unsigned long long j, char *p)
...@@ -88,7 +88,7 @@ void fullong (unsigned long long j, char *p) ...@@ -88,7 +88,7 @@ void fullong (unsigned long long j, char *p)
if (j > 999) if (j > 999)
return; return;
snprintf (p, 4, "%3llu", j); /* { dg-bogus "may be truncated" "signed long" { xfail *-*-* } } */ snprintf (p, 4, "%3llu", j);
} }
void fllong (long long j, char *p) void fllong (long long j, char *p)
...@@ -98,7 +98,7 @@ void fllong (long long j, char *p) ...@@ -98,7 +98,7 @@ void fllong (long long j, char *p)
if (k > 999) if (k > 999)
return; return;
snprintf (p, 4, "%3llu", k); /* { dg-bogus "may be truncated" "unsigned long long" { xfail *-*-* } } */ snprintf (p, 4, "%3llu", k);
} }
/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */ /* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
...@@ -32,14 +32,16 @@ void test_integer_cst (void) ...@@ -32,14 +32,16 @@ void test_integer_cst (void)
void test_integer_var (int i) void test_integer_var (int i)
{ {
T (0, "%*d", INT_MIN, i); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*d", INT_MIN, i); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*d", INT_MAX, i); /* { dg-warning "writing 2147483647 bytes" } */
T (0, "%.*d", INT_MIN, i); /* { dg-warning "writing between 1 and 11 bytes" } */
/* The following writes INT_MAX digits and, when i is negative, a minus /* The following writes INT_MAX digits and, when i is negative, a minus
sign. */ sign. */
T (0, "%.*d", INT_MAX, i); /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */ T (0, "%.*d", INT_MAX, i); /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */
T (0, "%.*d", INT_MIN, i); /* { dg-warning "writing between 1 and 11 bytes" } */
/* The following writes a range because of the possible minus sign. */
T (0, "%.*d", INT_MAX, i); /* { dg-warning "writing between 2147483647 and 2147483648 bytes" } */
T (0, "%*.*d", INT_MIN, INT_MIN, i); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*.*d", INT_MIN, INT_MIN, i); /* { dg-warning "writing 2147483648 bytes" } */
/* The following writes INT_MAX digits and, when i is negative, a minus /* The following writes INT_MAX digits and, when i is negative, a minus
...@@ -52,7 +54,10 @@ void test_floating_a_cst (void) ...@@ -52,7 +54,10 @@ void test_floating_a_cst (void)
T (0, "%*a", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*a", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*a", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%*a", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */
T (0, "%.*a", INT_MIN, 0.); /* { dg-warning "writing 6 bytes" } */ /* %a is poorly specified and as a result some implementations trim
redundant trailing zeros (e.g., Glibc) and others don't (e.g.,
Solaris). */
T (0, "%.*a", INT_MIN, 0.); /* { dg-warning "writing between 6 and 20 bytes" } */
T (0, "%.*a", INT_MAX, 0.); /* { dg-warning "writing 2147483654 bytes" } */ T (0, "%.*a", INT_MAX, 0.); /* { dg-warning "writing 2147483654 bytes" } */
...@@ -111,7 +116,7 @@ void test_floating_f_cst (void) ...@@ -111,7 +116,7 @@ void test_floating_f_cst (void)
T (0, "%*f", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*f", INT_MIN, 0.); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*f", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%*f", INT_MAX, 0.); /* { dg-warning "writing 2147483647 bytes" } */
T (0, "%.*f", INT_MIN, 0.); /* { dg-warning "writing 8 byte" } */ T (0, "%.*f", INT_MIN, 0.); /* { dg-warning "writing 8 bytes" } */
T (0, "%.*f", INT_MAX, 0.); /* { dg-warning "writing 2147483649 bytes" } */ T (0, "%.*f", INT_MAX, 0.); /* { dg-warning "writing 2147483649 bytes" } */
...@@ -178,14 +183,14 @@ void test_string_cst (void) ...@@ -178,14 +183,14 @@ void test_string_cst (void)
void test_string_var (const char *s) void test_string_var (const char *s)
{ {
T (0, "%*s", INT_MIN, s); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*s", INT_MIN, s); /* { dg-warning "writing 2147483648 or more bytes" } */
T (0, "%*s", INT_MAX, s); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%*s", INT_MAX, s); /* { dg-warning "writing 2147483647 or more bytes" } */
T (0, "%.*s", INT_MIN, s); /* { dg-warning "writing a terminating nul" } */ T (0, "%.*s", INT_MIN, s); /* { dg-warning "writing a terminating nul" } */
T (0, "%.*s", INT_MAX, s); /* { dg-warning "writing between 0 and 2147483647 bytes" } */ T (0, "%.*s", INT_MAX, s); /* { dg-warning "writing up to 2147483647 bytes" } */
T (0, "%*.*s", INT_MIN, INT_MIN, s); /* { dg-warning "writing 2147483648 bytes" } */ T (0, "%*.*s", INT_MIN, INT_MIN, s); /* { dg-warning "writing 2147483648 or more bytes" } */
T (0, "%*.*s", INT_MAX, INT_MAX, s); /* { dg-warning "writing 2147483647 bytes" } */ T (0, "%*.*s", INT_MAX, INT_MAX, s); /* { dg-warning "writing 2147483647 bytes" } */
} }
...@@ -37,19 +37,17 @@ void test_a (int w, int p, double x) ...@@ -37,19 +37,17 @@ void test_a (int w, int p, double x)
T1 ("%*.a", 6); /* { dg-warning "between 6 and 10 bytes" } */ T1 ("%*.a", 6); /* { dg-warning "between 6 and 10 bytes" } */
T1 ("%*.a", 7); /* { dg-warning "between 7 and 10 bytes" } */ T1 ("%*.a", 7); /* { dg-warning "between 7 and 10 bytes" } */
T1 ("%*.a", w); /* { dg-warning "writing 6 or more bytes" } */ T1 ("%*.a", w); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T1 ("%*.0a", w); /* { dg-warning "writing 6 or more bytes" } */ T1 ("%*.0a", w); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T1 ("%*.1a", w); /* { dg-warning "writing 8 or more bytes" } */ T1 ("%*.1a", w); /* { dg-warning "writing between 8 and 2147483648 bytes" } */
T1 ("%*.2a", w); /* { dg-warning "writing 9 or more bytes" } */ T1 ("%*.2a", w); /* { dg-warning "writing between 9 and 2147483648 bytes" } */
T1 ("%.*a", p); /* { dg-warning "writing 6 or more bytes" } */ T1 ("%.*a", p); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T1 ("%1.*a", p); /* { dg-warning "writing 6 or more bytes" } */ T1 ("%1.*a", p); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T1 ("%2.*a", p); /* { dg-warning "writing 6 or more bytes" } */ T1 ("%2.*a", p); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T1 ("%3.*a", p); /* { dg-warning "writing 6 or more bytes" } */ T1 ("%3.*a", p); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T2 ("%*.*a", w, p); /* { dg-warning "writing 6 or more bytes" } */ T2 ("%*.*a", w, p); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T2 ("%*.*a", w, p); /* { dg-warning "writing 6 or more bytes" } */
T2 ("%*.*a", w, p); /* { dg-warning "writing 6 or more bytes" } */
} }
/* Exercise %e. */ /* Exercise %e. */
...@@ -69,19 +67,17 @@ void test_e (int w, int p, double x) ...@@ -69,19 +67,17 @@ void test_e (int w, int p, double x)
T1 ("%*.e", 6); /* { dg-warning "between 6 and 7 bytes" } */ T1 ("%*.e", 6); /* { dg-warning "between 6 and 7 bytes" } */
T1 ("%*.e", 7); /* { dg-warning "writing 7 bytes" } */ T1 ("%*.e", 7); /* { dg-warning "writing 7 bytes" } */
T1 ("%*.e", w); /* { dg-warning "writing 5 or more bytes" } */ T1 ("%*.e", w); /* { dg-warning "writing between 5 and 2147483648 bytes" } */
T1 ("%*.0e", w); /* { dg-warning "writing 5 or more bytes" } */ T1 ("%*.0e", w); /* { dg-warning "writing between 5 and 2147483648 bytes" } */
T1 ("%*.1e", w); /* { dg-warning "writing 7 or more bytes" } */ T1 ("%*.1e", w); /* { dg-warning "writing between 7 and 2147483648 bytes" } */
T1 ("%*.2e", w); /* { dg-warning "writing 8 or more bytes" } */ T1 ("%*.2e", w); /* { dg-warning "writing between 8 and 2147483648 bytes" } */
T1 ("%.*e", p); /* { dg-warning "writing 5 or more bytes" } */ T1 ("%.*e", p); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T1 ("%1.*e", p); /* { dg-warning "writing 5 or more bytes" } */ T1 ("%1.*e", p); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T1 ("%2.*e", p); /* { dg-warning "writing 5 or more bytes" } */ T1 ("%2.*e", p); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T1 ("%3.*e", p); /* { dg-warning "writing 5 or more bytes" } */ T1 ("%3.*e", p); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T2 ("%*.*e", w, p); /* { dg-warning "writing 5 or more bytes" } */ T2 ("%*.*e", w, p); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T2 ("%*.*e", w, p); /* { dg-warning "writing 5 or more bytes" } */
T2 ("%*.*e", w, p); /* { dg-warning "writing 5 or more bytes" } */
} }
/* Exercise %f. */ /* Exercise %f. */
...@@ -103,19 +99,17 @@ void test_f (int w, int p, double x) ...@@ -103,19 +99,17 @@ void test_f (int w, int p, double x)
T2 ("%*.*f", 312, 312); /* { dg-warning "between 314 and 623 bytes" } */ T2 ("%*.*f", 312, 312); /* { dg-warning "between 314 and 623 bytes" } */
T2 ("%*.*f", 312, 313); /* { dg-warning "between 315 and 624 bytes" } */ T2 ("%*.*f", 312, 313); /* { dg-warning "between 315 and 624 bytes" } */
T1 ("%*.f", w); /* { dg-warning "writing 1 or more bytes" } */ T1 ("%*.f", w); /* { dg-warning "writing between 1 and 2147483648 bytes" } */
T1 ("%*.0f", w); /* { dg-warning "writing 1 or more bytes" } */ T1 ("%*.0f", w); /* { dg-warning "writing between 1 and 2147483648 bytes" } */
T1 ("%*.1f", w); /* { dg-warning "writing 3 or more bytes" } */ T1 ("%*.1f", w); /* { dg-warning "writing between 3 and 2147483648 bytes" } */
T1 ("%*.2f", w); /* { dg-warning "writing 4 or more bytes" } */ T1 ("%*.2f", w); /* { dg-warning "writing between 4 and 2147483648 bytes" } */
T1 ("%.*f", p); /* { dg-warning "writing 1 or more bytes" } */ T1 ("%.*f", p); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T1 ("%1.*f", p); /* { dg-warning "writing 1 or more bytes" } */ T1 ("%1.*f", p); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T1 ("%2.*f", p); /* { dg-warning "writing 2 or more bytes" } */ T1 ("%2.*f", p); /* { dg-warning "writing between 2 and 2147483958 bytes" } */
T1 ("%3.*f", p); /* { dg-warning "writing 3 or more bytes" } */ T1 ("%3.*f", p); /* { dg-warning "writing between 3 and 2147483958 bytes" } */
T2 ("%*.*f", w, p); /* { dg-warning "writing 1 or more bytes" } */ T2 ("%*.*f", w, p); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T2 ("%*.*f", w, p); /* { dg-warning "writing 1 or more bytes" } */
T2 ("%*.*f", w, p); /* { dg-warning "writing 1 or more bytes" } */
} }
/* Exercise %g. The expected output is the lesser of %e and %f. */ /* Exercise %g. The expected output is the lesser of %e and %f. */
...@@ -156,18 +150,18 @@ void test_a_va (va_list va) ...@@ -156,18 +150,18 @@ void test_a_va (va_list va)
T ("%6.a"); /* { dg-warning "between 6 and 10 bytes" } */ T ("%6.a"); /* { dg-warning "between 6 and 10 bytes" } */
T ("%7.a"); /* { dg-warning "between 7 and 10 bytes" } */ T ("%7.a"); /* { dg-warning "between 7 and 10 bytes" } */
T ("%*.a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%*.a"); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T ("%*.0a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%*.0a"); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T ("%*.1a"); /* { dg-warning "writing 8 or more bytes" } */ T ("%*.1a"); /* { dg-warning "writing between 8 and 2147483648 bytes" } */
T ("%*.2a"); /* { dg-warning "writing 9 or more bytes" } */ T ("%*.2a"); /* { dg-warning "writing between 9 and 2147483648 bytes" } */
T ("%.*a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%1.*a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%1.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%2.*a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%2.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%6.*a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%6.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%9.*a"); /* { dg-warning "writing 9 or more bytes" } */ T ("%9.*a"); /* { dg-warning "writing between 9 and 2147483658 bytes" } */
T ("%*.*a"); /* { dg-warning "writing 6 or more bytes" } */ T ("%*.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
} }
/* Exercise %e. */ /* Exercise %e. */
...@@ -195,12 +189,12 @@ void test_e_va (va_list va) ...@@ -195,12 +189,12 @@ void test_e_va (va_list va)
T ("%6.e"); /* { dg-warning "between 6 and 7 bytes" } */ T ("%6.e"); /* { dg-warning "between 6 and 7 bytes" } */
T ("%7.e"); /* { dg-warning "writing 7 bytes" } */ T ("%7.e"); /* { dg-warning "writing 7 bytes" } */
T ("%.*e"); /* { dg-warning "writing 5 or more bytes" } */ T ("%.*e"); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T ("%1.*e"); /* { dg-warning "writing 5 or more bytes" } */ T ("%1.*e"); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T ("%6.*e"); /* { dg-warning "writing 6 or more bytes" } */ T ("%6.*e"); /* { dg-warning "writing between 6 and 2147483655 bytes" } */
T ("%9.*e"); /* { dg-warning "writing 9 or more bytes" } */ T ("%9.*e"); /* { dg-warning "writing between 9 and 2147483655 bytes" } */
T ("%*.*e"); /* { dg-warning "writing 5 or more bytes" } */ T ("%*.*e"); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
} }
/* Exercise %f. */ /* Exercise %f. */
...@@ -232,11 +226,11 @@ void test_f_va (va_list va) ...@@ -232,11 +226,11 @@ void test_f_va (va_list va)
T ("%312.312f"); /* { dg-warning "between 314 and 623 bytes" } */ T ("%312.312f"); /* { dg-warning "between 314 and 623 bytes" } */
T ("%312.313f"); /* { dg-warning "between 315 and 624 bytes" } */ T ("%312.313f"); /* { dg-warning "between 315 and 624 bytes" } */
T ("%.*f"); /* { dg-warning "writing 1 or more bytes" } */ T ("%.*f"); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T ("%1.*f"); /* { dg-warning "writing 1 or more bytes" } */ T ("%1.*f"); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T ("%3.*f"); /* { dg-warning "writing 3 or more bytes" } */ T ("%3.*f"); /* { dg-warning "writing between 3 and 2147483958 bytes" } */
T ("%*.*f"); /* { dg-warning "writing 1 or more bytes" } */ T ("%*.*f"); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
} }
/* Exercise %g. The expected output is the lesser of %e and %f. */ /* Exercise %g. The expected output is the lesser of %e and %f. */
...@@ -268,9 +262,9 @@ void test_g_va (va_list va) ...@@ -268,9 +262,9 @@ void test_g_va (va_list va)
T ("%312.313g"); /* { dg-warning "writing 312 bytes" } */ T ("%312.313g"); /* { dg-warning "writing 312 bytes" } */
T ("%333.999g"); /* { dg-warning "writing 333 bytes" } */ T ("%333.999g"); /* { dg-warning "writing 333 bytes" } */
T ("%.*g"); /* { dg-warning "writing 1 or more bytes" } */ T ("%.*g"); /* { dg-warning "writing between 1 and 310 bytes" } */
T ("%1.*g"); /* { dg-warning "writing 1 or more bytes" } */ T ("%1.*g"); /* { dg-warning "writing between 1 and 310 bytes" } */
T ("%4.*g"); /* { dg-warning "writing 4 or more bytes" } */ T ("%4.*g"); /* { dg-warning "writing between 4 and 310 bytes" } */
T ("%*.*g"); /* { dg-warning "writing 1 or more bytes" } */ T ("%*.*g"); /* { dg-warning "writing between 1 and 2147483648 bytes" } */
} }
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