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
This commit is contained in:
Martin Sebor 2017-01-26 21:14:18 +00:00 committed by Martin Sebor
parent c86996727f
commit 5d93da1d11
15 changed files with 1505 additions and 1209 deletions

View file

@ -1,3 +1,31 @@
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>
* config/rs6000/rs6000-c (altivec_overloaded_builtins): Remove

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,19 @@
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>
PR c++/68727

View file

@ -20,5 +20,5 @@ void test (void)
"channel uplink (see section 7.6.1).");
/* { dg-warning "output truncated" "" { target *-*-* } 7 } */
/* { dg-message "format output" "" { target *-*-* } 6 } */
/* { dg-message "output" "" { target *-*-* } 6 } */
}

View file

@ -4,6 +4,9 @@
typedef struct
{
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 a2[2];
char a3[3];
@ -39,7 +42,9 @@ void test_int_retval_unused (void)
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->a2); /* { dg-warning "output may be truncated" } */
}
@ -64,7 +69,7 @@ void test_int_retval_used (void)
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->a2); /* { dg-warning "output may be truncated" } */
}

View file

@ -59,15 +59,15 @@ void must_not_eliminate (void);
typedef __SIZE_TYPE__ size_t;
extern int i;
extern unsigned u;
extern long li;
extern unsigned long lu;
extern size_t sz;
extern char *str;
volatile int i;
volatile unsigned u;
volatile long li;
volatile unsigned long lu;
volatile size_t sz;
volatile char *str;
extern double d;
extern long double ld;
volatile double d;
volatile long double ld;
/* Verify that overflowing the destination object disables the return
value optimization. */
@ -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" 93 "optimized" { target { { ! ilp32 } && { ! lp64 } } } } }
No unconditional calls to abort should be made:

View file

@ -136,7 +136,6 @@ void test_arg_string (const char *s)
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, "%*i %s", 12, i, "abc");
}

View file

@ -11,21 +11,19 @@
#define INT_MAX __INT_MAX__
typedef __builtin_va_list va_list;
char buffer [256];
extern char *ptr;
/* 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
an unknown object otherwise. */
#define buffer(size) \
(0 <= size && (!LINE || __LINE__ == LINE) \
? buffer + sizeof buffer - size : ptr)
/* Evaluate to an array of SIZE characters when non-negative, or to
a pointer to an unknown object otherwise. */
#define buffer(size) \
((0 <= size) ? buffer + sizeof buffer - (size) : ptr)
/* Evaluate to SIZE when non-negative and LINE is not set or set to
the line the macro is on, or to SIZE_MAX otherise. */
#define objsize(size) \
(0 <= size && (!LINE || __LINE__ == LINE) \
? size : __SIZE_MAX__)
/* Evaluate to SIZE when non-negative, or to SIZE_MAX otherise. */
#define objsize(size) ((0 <= size) ? (size) : __SIZE_MAX__)
typedef __SIZE_TYPE__ size_t;
@ -61,12 +59,26 @@ const char s8[] = "12345678";
void sink (void*, ...);
int dummy_sprintf (char*, const char*, ...);
int dummy_snprintf (char*, size_t, const char*, ...);
int dummy_vsprintf (char*, const char*, va_list);
int dummy_vsnprintf (char*, size_t, const char*, va_list);
int dummy___sprintf_chk (char*, int, size_t, const char*, ...);
int dummy___snprintf_chk (char*, size_t, int, size_t, const char*, ...);
int dummy___vsprintf_chk (char*, int, size_t, const char*, va_list);
int dummy___vsnprintf_chk (char*, size_t, int, size_t, const char*, va_list);
/* Helper to expand function to either __builtin_f or dummy_f to
make debugging GCC easy. */
#define FUNC(f) \
((!LINE || LINE == __LINE__) ? __builtin_ ## f : dummy_ ## f)
/* Macro to verify that calls to __builtin_sprintf (i.e., with no size
argument) issue diagnostics by correctly determining the size of
the destination buffer. */
#define T(size, fmt, ...) \
__builtin_sprintf (buffer (size), fmt, __VA_ARGS__), \
sink (buffer, ptr);
(FUNC (sprintf) (buffer (size), fmt, __VA_ARGS__), \
sink (buffer, ptr))
/* Exercise the "%c" and "%lc" directive with constant arguments. */
@ -109,19 +121,21 @@ void test_sprintf_flexarray (void *p, int i)
struct S
{
int n;
char a [];
char a[];
} *s = p;
__builtin_sprintf (s->a, "%c", 'x');
FUNC (sprintf)(s->a, "%c", 'x');
__builtin_sprintf (s->a, "%s", "");
__builtin_sprintf (s->a, "%s", "abc");
__builtin_sprintf (s->a, "abc%sghi", "def");
FUNC (sprintf)(s->a, "%-s", "");
FUNC (sprintf)(s->a, "%-s", "abc");
FUNC (sprintf)(s->a, "abc%sghi", "def");
__builtin_sprintf (s->a, "%i", 1234);
FUNC (sprintf)(s->a, "%i", 1234);
__builtin_sprintf (buffer (1), "%s", s->a);
__builtin_sprintf (buffer (1), "%s", s [i].a);
FUNC (sprintf)(buffer (1), "%-s", s->a);
FUNC (sprintf)(buffer (1), "%-s", s [i].a);
FUNC (sprintf)(buffer (2), "%-s", s->a);
FUNC (sprintf)(buffer (2), "%-s", s [i].a);
}
/* Same as above but for zero-length arrays. */
@ -134,22 +148,22 @@ void test_sprintf_zero_length_array (void *p, int i)
char a [0];
} *s = p;
__builtin_sprintf (s->a, "%c", 'x');
FUNC (sprintf)(s->a, "%c", 'x');
__builtin_sprintf (s->a, "%s", "");
__builtin_sprintf (s->a, "%s", "abc");
__builtin_sprintf (s->a, "abc%sghi", "def");
FUNC (sprintf)(s->a, "%s", "");
FUNC (sprintf)(s->a, "%s", "abc");
FUNC (sprintf)(s->a, "abc%sghi", "def");
__builtin_sprintf (s->a, "%i", 1234);
FUNC (sprintf)(s->a, "%i", 1234);
__builtin_sprintf (buffer (1), "%s", s->a);
__builtin_sprintf (buffer (1), "%s", s [i].a);
FUNC (sprintf)(buffer (1), "%s", s->a);
FUNC (sprintf)(buffer (1), "%s", s [i].a);
}
#undef T
#define T(size, fmt, ...) \
__builtin___sprintf_chk (buffer (size), 0, objsize (size), fmt, \
__VA_ARGS__), sink (buffer, ptr)
#define T(size, fmt, ...) \
(FUNC (__sprintf_chk) (buffer (size), 0, objsize (size), fmt, __VA_ARGS__), \
sink (buffer, ptr))
/* Exercise the "%c" and "%lc" directive with constant arguments. */
@ -286,6 +300,7 @@ void test_sprintf_chk_s_const (void)
T (2, "_%s", "");
T (2, "%%%s", "");
T (2, "%%%%%s", ""); /* { dg-warning "nul past the end" } */
T (2, "%s%%", "");
T (2, "_%s", "1"); /* { dg-warning "nul past the end" } */
T (2, "%%%s", "1"); /* { dg-warning "nul past the end" } */
@ -317,7 +332,10 @@ void test_sprintf_chk_s_const (void)
T (1, "%*ls", 0, L"\0");
T (1, "%*ls", 1, L""); /* { dg-warning "nul past the end" } */
T (1, "%ls", L"1"); /* { dg-warning "nul past the end" } */
/* A wide character string need not convert into any 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 (2, "%.0ls", L"1");
T (2, "%.1ls", L"1");
@ -333,9 +351,9 @@ void test_sprintf_chk_s_const (void)
T (3, "%.0ls", L"1");
T (3, "%.1ls", L"1");
T (3, "%.2ls", L"1");
T (3, "%ls", L"12");
T (3, "%ls", L"12"); /* { dg-warning "directive writing up to 12 bytes" } */
T (3, "%ls", L"123"); /* { dg-warning "nul past the end" } */
T (3, "%ls", L"123"); /* { dg-warning "directive writing up to 18 bytes" } */
T (3, "%.0ls", L"123");
T (3, "%.1ls", L"123");
T (3, "%.2ls", L"123");
@ -579,7 +597,7 @@ void test_sprintf_chk_integer_const (void)
T ( 1, "%i", 0); /* { dg-warning "nul past the end" } */
T ( 1, "%i", 1); /* { dg-warning "nul past the end" } */
T ( 1, "%i", -1); /* { dg-warning "into a region" } */
T ( 1, "%i_", 1); /* { dg-warning "character ._. at offset 2 past the end" } */
T ( 1, "%i_", 1); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 1, "_%i", 1); /* { dg-warning "into a region" } */
T ( 1, "_%i_", 1); /* { dg-warning "into a region" } */
T ( 1, "%o", 0); /* { dg-warning "nul past the end" } */
@ -596,7 +614,7 @@ void test_sprintf_chk_integer_const (void)
T ( 2, "%i", 10); /* { dg-warning "nul past the end" } */
T ( 2, "%i_", 0); /* { dg-warning "nul past the end" } */
T ( 2, "_%i", 0); /* { dg-warning "nul past the end" } */
T ( 2, "_%i_", 0); /* { dg-warning "character ._. at offset 3 past the end" } */
T ( 2, "_%i_", 0); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 2, "%o", 1);
T ( 2, "%o", 7);
T ( 2, "%o", 010); /* { dg-warning "nul past the end" } */
@ -678,7 +696,7 @@ void test_sprintf_chk_j_const (void)
T ( 1, "%ji", I ( 0)); /* { dg-warning "nul past the end" } */
T ( 1, "%ji", I ( 1)); /* { dg-warning "nul past the end" } */
T ( 1, "%ji", I ( -1)); /* { dg-warning "into a region" } */
T ( 1, "%ji_", I ( 1)); /* { dg-warning "character ._. at offset 3 past the end" } */
T ( 1, "%ji_", I ( 1)); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 1, "_%ji", I ( 1)); /* { dg-warning "into a region" } */
T ( 1, "_%ji_",I ( 1)); /* { dg-warning "into a region" } */
T ( 1, "%jo", I ( 0)); /* { dg-warning "nul past the end" } */
@ -695,7 +713,7 @@ void test_sprintf_chk_j_const (void)
T ( 2, "%ji", I ( 10)); /* { dg-warning "nul past the end" } */
T ( 2, "%ji_", I ( 0)); /* { dg-warning "nul past the end" } */
T ( 2, "_%ji", I ( 0)); /* { dg-warning "nul past the end" } */
T ( 2, "_%ji_",I ( 0)); /* { dg-warning "character ._. at offset 4 past the end" } */
T ( 2, "_%ji_",I ( 0)); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 2, "%jo", I ( 1));
T ( 2, "%jo", I ( 7));
T ( 2, "%jo", I ( 010)); /* { dg-warning "nul past the end" } */
@ -754,7 +772,7 @@ void test_sprintf_chk_l_const (void)
T ( 1, "%li", 0L); /* { dg-warning "nul past the end" } */
T ( 1, "%li", 1L); /* { dg-warning "nul past the end" } */
T ( 1, "%li", -1L); /* { dg-warning "into a region" } */
T ( 1, "%li_", 1L); /* { dg-warning "character ._. at offset 3 past the end" } */
T ( 1, "%li_", 1L); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 1, "_%li", 1L); /* { dg-warning "into a region" } */
T ( 1, "_%li_", 1L); /* { dg-warning "into a region" } */
T ( 1, "%lo", 0L); /* { dg-warning "nul past the end" } */
@ -771,7 +789,7 @@ void test_sprintf_chk_l_const (void)
T ( 2, "%li", 10L); /* { dg-warning "nul past the end" } */
T ( 2, "%li_", 0L); /* { dg-warning "nul past the end" } */
T ( 2, "_%li", 0L); /* { dg-warning "nul past the end" } */
T ( 2, "_%li_", 0L); /* { dg-warning "character ._. at offset 4 past the end" } */
T ( 2, "_%li_", 0L); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 2, "%lo", 1L);
T ( 2, "%lo", 7L);
T ( 2, "%lo", 010L); /* { dg-warning "nul past the end" } */
@ -830,7 +848,7 @@ void test_sprintf_chk_ll_const (void)
T ( 1, "%lli", 0LL); /* { dg-warning "nul past the end" } */
T ( 1, "%lli", 1LL); /* { dg-warning "nul past the end" } */
T ( 1, "%lli", -1LL); /* { dg-warning "into a region" } */
T ( 1, "%lli_", 1LL); /* { dg-warning "character ._. at offset 4 past the end" } */
T ( 1, "%lli_", 1LL); /* { dg-warning " 1 byte into a region of size 0 " } */
T ( 1, "_%lli", 1LL); /* { dg-warning "into a region" } */
T ( 1, "_%lli_", 1LL); /* { dg-warning "into a region" } */
T ( 1, "%llo", 0LL); /* { dg-warning "nul past the end" } */
@ -847,7 +865,7 @@ void test_sprintf_chk_ll_const (void)
T ( 2, "%lli", 10LL); /* { dg-warning "nul past the end" } */
T ( 2, "%lli_", 0LL); /* { dg-warning "nul past the end" } */
T ( 2, "_%lli", 0LL); /* { dg-warning "nul past the end" } */
T ( 2, "_%lli_", 0LL); /* { dg-warning "character ._. at offset 5 past the end" } */
T ( 2, "_%lli_", 0LL); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 2, "%llo", 1LL);
T ( 2, "%llo", 7LL);
T ( 2, "%llo", 010LL); /* { dg-warning "nul past the end" } */
@ -909,7 +927,7 @@ void test_sprintf_chk_L_const (void)
T ( 1, "%Li", 0LL); /* { dg-warning "nul past the end" } */
T ( 1, "%Li", 1LL); /* { dg-warning "nul past the end" } */
T ( 1, "%Li", -1LL); /* { dg-warning "into a region" } */
T ( 1, "%Li_", 1LL); /* { dg-warning "character ._. at offset 3 past the end" } */
T ( 1, "%Li_", 1LL); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 1, "_%Li", 1LL); /* { dg-warning "into a region" } */
T ( 1, "_%Li_", 1LL); /* { dg-warning "into a region" } */
}
@ -920,7 +938,7 @@ void test_sprintf_chk_z_const (void)
T ( 1, "%zi", (size_t)0); /* { dg-warning "nul past the end" } */
T ( 1, "%zi", (size_t)1); /* { dg-warning "nul past the end" } */
T ( 1, "%zi", (size_t)-1L);/* { dg-warning "into a region" } */
T ( 1, "%zi_", (size_t)1); /* { dg-warning "character ._. at offset 3 past the end" } */
T ( 1, "%zi_", (size_t)1); /* { dg-warning " 1 byte into a region of size 0" } */
T ( 1, "_%zi", (size_t)1); /* { dg-warning "into a region" } */
T ( 1, "_%zi_", (size_t)1); /* { dg-warning "into a region" } */
@ -942,16 +960,20 @@ void test_sprintf_chk_a_const (void)
/* The least number of bytes on output is 6 for "0x0p+0". When precision
is missing the number of digits after the decimal point isn't fully
specified by C (it seems like a defect). */
T (0, "%a", 0.0); /* { dg-warning "into a region" } */
T (0, "%la", 0.0); /* { dg-warning "into a region" } */
T (1, "%a", 0.0); /* { dg-warning "into a region" } */
T (2, "%a", 0.0); /* { dg-warning "into a region" } */
T (3, "%a", 0.0); /* { dg-warning "into a region" } */
T (4, "%a", 0.0); /* { dg-warning "into a region" } */
T (5, "%a", 0.0); /* { dg-warning "into a region" } */
T (6, "%a", 0.0); /* { dg-warning "writing a terminating nul" } */
T (7, "%a", 0.0);
specified by C (a defect). Two sets of implementations are known to
exist: those that trim trailing zeros (e.g., Glibc) and those that
pad output with trailing zeros so that all floating point numbers
result in the same number of bytes on output (e.g., Solaris). */
T ( 0, "%a", 0.0); /* { dg-warning "writing between 6 and 20 bytes" } */
T ( 0, "%la", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T ( 1, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T ( 2, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T ( 3, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T ( 4, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T ( 5, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T ( 6, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T (19, "%a", 0.0); /* { dg-warning "between 6 and 20 bytes" } */
T (20, "%a", 0.0); /* { dg-warning "may write a terminating nul" } */
T (0, "%.a", 0.0); /* { dg-warning "into a region" } */
T (0, "%.0a", 0.0); /* { dg-warning "into a region" } */
@ -1008,24 +1030,21 @@ void test_sprintf_chk_e_const (void)
T ( 6, "%.e", 1.0);
T ( 6, "%.0e", 1.0);
/* The actual output of the following directives depends on the rounding
mode. Verify that the warning correctly reflects that. At level 1,
since the minimum number of bytes output by the directive fits the
space the directive itself isn't diagnosed but the terminating nul
is. The directive is diagnosed at level 2. */
T (12, "%e", 9.999999e+99); /* { dg-warning "terminating nul" } */
T (12, "%e", 9.9999994e+99); /* { dg-warning "terminating nul" } */
T (12, "%e", 9.9999995e+99); /* { dg-warning "terminating nul" } */
T (12, "%e", 9.9999996e+99); /* { dg-warning "terminating nul" } */
T (12, "%e", 9.9999997e+99); /* { dg-warning "terminating nul" } */
T (12, "%e", 9.9999998e+99); /* { dg-warning "terminating nul" } */
/* The output of the following directives depends on the rounding
mode. */
T (12, "%e", 9.999999e+99); /* { dg-warning "between 12 and 13" } */
T (12, "%e", 9.9999994e+99); /* { dg-warning "between 12 and 13" } */
T (12, "%e", 9.9999995e+99); /* { dg-warning "between 12 and 13" } */
T (12, "%e", 9.9999996e+99); /* { dg-warning "between 12 and 13" } */
T (12, "%e", 9.9999997e+99); /* { dg-warning "between 12 and 13" } */
T (12, "%e", 9.9999998e+99); /* { dg-warning "between 12 and 13" } */
T (12, "%Le", 9.9999994e+99L);/* { dg-warning "terminating nul" } */
T (12, "%Le", 9.9999995e+99L);/* { dg-warning "terminating nul" } */
T (12, "%Le", 9.9999996e+99L);/* { dg-warning "terminating nul" } */
T (12, "%Le", 9.9999997e+99L);/* { dg-warning "terminating nul" } */
T (12, "%Le", 9.9999998e+99L);/* { dg-warning "terminating nul" } */
T (12, "%Le", 9.9999999e+99L);/* { dg-warning "terminating nul" } */
T (12, "%Le", 9.9999994e+99L);/* { dg-warning "between 12 and 13" } */
T (12, "%Le", 9.9999995e+99L);/* { dg-warning "between 12 and 13" } */
T (12, "%Le", 9.9999996e+99L);/* { dg-warning "between 12 and 13" } */
T (12, "%Le", 9.9999997e+99L);/* { dg-warning "between 12 and 13" } */
T (12, "%Le", 9.9999998e+99L);/* { dg-warning "between 12 and 13" } */
T (12, "%Le", 9.9999999e+99L);/* { dg-warning "between 12 and 13" } */
}
/* At -Wformat-overflow level 1 unknown numbers are assumed to have
@ -1035,21 +1054,32 @@ void test_sprintf_chk_e_const (void)
void test_sprintf_chk_s_nonconst (int w, int p, const char *s)
{
T (-1, "%s", s);
T ( 0, "%s", s); /* { dg-warning "nul past the end" } */
T ( 0, "%s", s); /* { dg-warning "writing a terminating nul" } */
T ( 1, "%s", s);
T (-1, "%.0s", s);
T ( 1, "%.0s", s);
T ( 1, "%.1s", s); /* { dg-warning "nul past the end" } */
T (-1, "%.1s", s);
T ( 1, "%.1s", s); /* { dg-warning "may write a terminating nul past the end" } */
T (-1, "%.2s", s);
T ( 1, "%.2s", s); /* { dg-warning "directive writing up to 2 bytes" } */
T ( 2, "%.2s", s); /* { dg-warning "may write a terminating nul" } */
T ( 3, "%.2s", s);
/* The string argument is constant but the width and/or precision
is not. */
T ( 1, "%*s", w, "");
T ( 1, "%*s", w, "1"); /* { dg-warning "nul past the end" } */
T (-1, "%*s", w, "");
T ( 1, "%*s", w, ""); /* { dg-warning "may write a terminating nul past the end" } */
T (-1, "%*s", w, "1");
T ( 1, "%*s", w, "1"); /* { dg-warning "writing a terminating nul past the end" } */
T (-1, "%.*s", p, "");
T ( 1, "%.*s", p, "");
T (-1, "%.*s", p, "1");
T ( 1, "%.*s", p, "1"); /* { dg-warning "may write a terminating nul" } */
T ( 1, "%.*s", w, "123"); /* { dg-warning "writing between 0 and 3 bytes into a region of size 1" } */
T ( 1, "%.*s", w, "123"); /* { dg-warning "writing up to 3 bytes into a region of size 1" } */
T ( 1, "%*s", w, "123"); /* { dg-warning "writing 3 or more bytes into a region of size 1" } */
T ( 2, "%*s", w, "123"); /* { dg-warning "writing 3 or more bytes into a region of size 2" } */
/* Either of the messages below is acceptable. */
T ( 1, "%*s", w, "123"); /* { dg-warning "writing 3 or more bytes into a region of size 1|writing between 3 and 2147483648 bytes" } */
T ( 2, "%*s", w, "123"); /* { dg-warning "writing 3 or more bytes into a region of size 2|writing between 3 and 2147483648 bytes" } */
T ( 3, "%*s", w, "123"); /* { dg-warning "writing a terminating nul past the end" } */
T ( 4, "%*s", w, "123");
@ -1059,6 +1089,10 @@ void test_sprintf_chk_s_nonconst (int w, int p, const char *s)
the end (we don't print "past the end" when we're not
sure which we can't be with an unknown string. */
T (1, "%1s", s); /* { dg-warning "writing a terminating nul past the end" } */
/* Multiple directives. */
T (1, "%s%s", s, s);
T (1, "%s%s%s", s, s, s);
}
/* Exercise the hh length modifier with all integer specifiers and
@ -1167,15 +1201,15 @@ void test_sprintf_chk_hh_nonconst (int w, int p, int a)
/* The argument is known but precision isn't. When the argument
is zero only the first call can be diagnosed since a zero
precision would result in no bytes on output. */
T (0, "%.*hhi", p, 0); /* { dg-warning "nul past the end" } */
T (1, "%.*hhi", p, 0);
T (0, "%.*hhi", p, 0); /* { dg-warning " writing up to \[0-9\]+ bytes" } */
T (1, "%.*hhi", p, 0); /* { dg-warning "may write a terminating nul" }*/
T (2, "%.*hhi", p, 0);
T (2, "%.*hhi", p, 12); /* { dg-warning "nul past the end" } */
T (2, "%.*hhi", p, 123); /* { dg-warning "into a region" } */
/* The argument is known but neither width nor precision is. */
T (0, "%*.*hhi", w, p, 0); /* { dg-warning "nul past the end" } */
T (1, "%*.*hhi", w, p, 0);
T (0, "%*.*hhi", w, p, 0); /* { dg-warning "writing up to \[0-9\]+ bytes" } */
T (1, "%*.*hhi", w, p, 0); /* { dg-warning "may write a terminating nul" } */
T (2, "%*.*hhi", w, p, 0);
T (2, "%*.*hhi", w, p, 12); /* { dg-warning "nul past the end" } */
T (2, "%*.*hhi", w, p, 123); /* { dg-warning "into a region" } */
@ -1298,12 +1332,13 @@ void test_sprintf_chk_int_nonconst (int w, int p, int a)
T (3, "%2u", a);
T (3, "%2x", a);
T (1, "%.*d", p, a);
T (1, "%.*d", p, a); /* { dg-warning "nul past the end" } */
T (2, "%.*d", p, a);
T (4, "%i %i", a, a);
/* The following will definitely be "writing a terminating nul past the end"
(i.e., not "may write".) */
T (4, "%i %i ", a, a); /* { dg-warning "writing a terminating nul past the end" } */
T (4, "%i %i ", a, a); /* { dg-warning "nul past the end" } */
T (4, "%i %i %i", a, a, a); /* { dg-warning "into a region" }*/
}
@ -1347,7 +1382,7 @@ void test_sprintf_chk_e_nonconst (int w, int p, double d)
T ( 8, "%.1e", d);
T ( 0, "%*e", 0, d); /* { dg-warning "writing between 12 and 14 bytes into a region of size 0" } */
T ( 0, "%*e", w, d); /* { dg-warning "writing 12 or more bytes into a region of size 0" } */
T ( 0, "%*e", w, d); /* { dg-warning "writing 12 or more bytes into a region of size 0|writing between 12 and \[0-9\]+ bytes into a region of size 0" } */
}
void test_sprintf_chk_f_nonconst (double d)
@ -1381,9 +1416,10 @@ void test_sprintf_chk_f_nonconst (double d)
__builtin_sprintf_chk with non-constant arguments. */
#undef T
#define T(size, fmt) \
__builtin___vsprintf_chk (buffer (size), 0, objsize (size), fmt, va)
(FUNC (__vsprintf_chk) (buffer (size), 0, objsize (size), fmt, va), \
sink (buffer))
void test_vsprintf_chk_c (__builtin_va_list va)
void test_vsprintf_chk_c (va_list va)
{
T (-1, "%c");
@ -1399,26 +1435,25 @@ void test_vsprintf_chk_c (__builtin_va_list va)
T (3, "%c%c");
/* Wide characters. */
T (0, "%lc"); /* { dg-warning "nul past the end" } */
T (1, "%lc");
T (2, "%lc");
T (0, "%lc"); /* { dg-warning "up to 6 bytes " } */
T (1, "%lc"); /* { dg-warning "up to 6 bytes " } */
T (2, "%lc"); /* { dg-warning "may write a terminating nul" } */
/* The following could result in as few as a single byte and in as many
as MB_CUR_MAX, but since the MB_CUR_MAX value is a runtime property
the write cannot be reliably diagnosed. */
T (2, "%lc");
T (2, "%1lc");
T (2, "%1lc"); /* { dg-warning "may write a terminating nul" } */
/* Writing some unknown number of bytes into a field two characters wide. */
T (2, "%2lc"); /* { dg-warning "nul past the end" } */
T (2, "%lc%lc");
T (2, "%lc%lc"); /* { dg-warning "writing up to 6 bytes into a region of size between 0 and 2" } */
T (3, "%lc%c");
T (3, "%lc%c"); /* { dg-warning "may write a terminating nul" } */
/* Here in the best case each argument will format as single character,
causing the terminating NUL to be written past the end. */
T (3, "%lc%c%c");
T (3, "%lc%c%c"); /* { dg-warning "writing 1 byte into a region of size between 0 and 2" } */
}
void test_vsprintf_chk_int (__builtin_va_list va)
void test_vsprintf_chk_int (va_list va)
{
T (-1, "%d");
@ -1462,8 +1497,9 @@ void test_vsprintf_chk_int (__builtin_va_list va)
}
#undef T
#define T(size, fmt, ...) \
__builtin_snprintf (buffer (size), objsize (size), fmt, __VA_ARGS__)
#define T(size, fmt, ...) \
(FUNC (snprintf) (buffer (size), objsize (size), fmt, __VA_ARGS__), \
sink (buffer))
void test_snprintf_c_const (char *d)
{
@ -1498,24 +1534,27 @@ void test_snprintf_c_const (char *d)
T (2, "%2lc", (wint_t)L'1'); /* { dg-warning "output truncated before the last format character" } */
T (3, "%lc%c", (wint_t)'1', '2');
/* Here in the best case each argument will format as single character,
causing the output to be truncated just before the terminating NUL
(i.e., cutting off the '3'). */
T (3, "%lc%c%c", (wint_t)'1', '2', '3'); /* { dg-warning "output truncated" } */
T (3, "%lc%lc%c", (wint_t)'1', (wint_t)'2', '3'); /* { dg-warning "output truncated" } */
/* Here %lc may result in anywhere between 0 and MB_CUR_MAX characters
so the minimum number of bytes on output is 2 (plus the terminating
nul), but the likely number is 3 (plus the nul). */
T (3, "%lc%c%c", (wint_t)'\x80', '2', '3'); /* { dg-warning ".%c. directive output may be truncated writing 1 byte into a region of size between 0 and 2" } */
/* It's reasonably safe that L'1' converts into the single byte '1'. */
T (3, "%lc%c%c", (wint_t)'1', '2', '3'); /* { dg-warning "output may be truncated" } */
T (3, "%lc%lc%c", (wint_t)'1', (wint_t)'2', '3'); /* { dg-warning "output may be truncated" } */
}
#undef T
#define T(size, fmt, ...) \
__builtin___snprintf_chk (buffer (size), objsize (size), \
0, objsize (size), fmt, __VA_ARGS__)
(FUNC (__snprintf_chk) (buffer (size), objsize (size), \
0, objsize (size), fmt, __VA_ARGS__), \
sink (buffer))
void test_snprintf_chk_c_const (void)
{
/* Verify that specifying a size of the destination buffer that's
bigger than its actual size (normally determined and passed to
the function by __builtin_object_size) is diagnosed. */
__builtin___snprintf_chk (buffer, 3, 0, 2, " "); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" } */
FUNC (__snprintf_chk)(buffer, 3, 0, 2, " "); /* { dg-warning "specified bound 3 exceeds the size 2 of the destination" } */
T (-1, "%c", 0); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
@ -1547,11 +1586,11 @@ void test_snprintf_chk_c_const (void)
T (2, "%2lc", (wint_t)'1'); /* { dg-warning "output truncated before the last format character" } */
T (3, "%lc%c", (wint_t)'1', '2');
/* Here in the best case each argument will format as single character,
causing the output to be truncated just before the terminating NUL
(i.e., cutting off the '3'). */
T (3, "%lc%c%c", (wint_t)'1', '2', '3'); /* { dg-warning "output truncated" } */
T (3, "%lc%lc%c", (wint_t)'1', (wint_t)'2', '3'); /* { dg-warning "output truncated" } */
/* Here %lc may result in anywhere between 0 and MB_CUR_MAX characters
so the minimum number of bytes on output is 2 (plus the terminating
nul), but the likely number is 3 (plus the nul). */
T (3, "%lc%c%c", (wint_t)'1', '2', '3'); /* { dg-warning "output may be truncated" } */
T (3, "%lc%lc%c", (wint_t)'1', (wint_t)'2', '3'); /* { dg-warning "output may be truncated" } */
}
/* Macro to verify that calls to __builtin_vsprintf (i.e., with no size
@ -1559,27 +1598,30 @@ void test_snprintf_chk_c_const (void)
the destination buffer. */
#undef T
#define T(size, fmt) \
__builtin_vsprintf (buffer (size), fmt, va)
(FUNC (vsprintf) (buffer (size), fmt, va), \
sink (buffer))
void test_vsprintf_s (__builtin_va_list va)
void test_vsprintf_s (va_list va)
{
T (-1, "%s");
T (0, "%s"); /* { dg-warning "writing a terminating nul past the end" } */
T (0, "%s"); /* { dg-warning "writing a terminating nul" } */
T (1, "%s");
T (1, "%1s"); /* { dg-warning "writing a terminating nul past the end" } */
T (2, "%s%s");
T (2, "%s%s_");
T (2, "%s%s1");
T (2, "%s%s12"); /* { dg-warning "writing a terminating nul" } */
T (2, "%s%s123"); /* { dg-warning "writing 3 bytes into a region of size 2" } */
T (2, "%s_%s");
T (2, "_%s%s");
T (2, "_%s_%s"); /* { dg-warning "writing a terminating nul past the end" } */
T (2, "_%s_%s"); /* { dg-warning "writing a terminating nul" } */
}
/* Exercise all integer specifiers with no modifier and a non-constant
argument. */
void test_vsprintf_int (__builtin_va_list va)
void test_vsprintf_int (va_list va)
{
T (-1, "%d");
@ -1623,10 +1665,11 @@ void test_vsprintf_int (__builtin_va_list va)
}
#undef T
#define T(size, fmt) \
__builtin_vsnprintf (buffer (size), objsize (size), fmt, va)
#define T(size, fmt) \
(FUNC (vsnprintf) (buffer (size), objsize (size), fmt, va), \
sink (buffer))
void test_vsnprintf_s (__builtin_va_list va)
void test_vsnprintf_s (va_list va)
{
T (-1, "%s"); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
@ -1638,22 +1681,23 @@ void test_vsnprintf_s (__builtin_va_list va)
T (2, "%s%s_");
T (2, "%s_%s");
T (2, "_%s%s");
T (2, "_%s_%s"); /* { dg-warning "output truncated before the last format character" } */
T (2, "_%s_%s"); /* { dg-warning "output truncated" } */
}
#undef T
#define T(size, fmt) \
__builtin___vsnprintf_chk (buffer (size), objsize (size), \
0, objsize (size), fmt, va)
#define T(size, fmt) \
(FUNC (__vsnprintf_chk) (buffer (size), objsize (size), \
0, objsize (size), fmt, va), \
sink (buffer))
void test_vsnprintf_chk_s (__builtin_va_list va)
void test_vsnprintf_chk_s (va_list va)
{
/* Verify that specifying a size of the destination buffer that's
bigger than its actual size (normally determined and passed to
the function by __builtin_object_size) is diagnosed. */
__builtin___vsnprintf_chk (buffer, 123, 0, 122, "%-s", va); /* { dg-warning "specified bound 123 exceeds the size 122 of the destination" } */
FUNC (__vsnprintf_chk)(buffer, 123, 0, 122, "%-s", va); /* { dg-warning "specified bound 123 exceeds the size 122 of the destination" } */
__builtin___vsnprintf_chk (buffer, __SIZE_MAX__, 0, 2, "%-s", va); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
FUNC (__vsnprintf_chk)(buffer, __SIZE_MAX__, 0, 2, "%-s", va); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
T (0, "%s");
T (1, "%s");
@ -1663,5 +1707,5 @@ void test_vsnprintf_chk_s (__builtin_va_list va)
T (2, "%s%s_");
T (2, "%s_%s");
T (2, "_%s%s");
T (2, "_%s_%s"); /* { dg-warning "output truncated before the last format character" } */
T (2, "_%s_%s"); /* { dg-warning "output truncated" } */
}

View file

@ -1,5 +1,5 @@
/* { 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
and avoid exercising any of the others. The buffer and objsize macros
@ -47,12 +47,16 @@ void test_s_const (void)
T (1, "%*ls", 0, L"\0");
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 (2, "%.0ls", L"1");
T (2, "%.1ls", L"1");
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" } */
/* The "%.2ls" directive below will write at a minimum 1 byte (because
@ -71,8 +75,8 @@ void test_s_const (void)
T (3, "%.3ls", L"12"); /* { dg-warning "nul past the end" } */
T (4, "%.3ls", L"123");
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, "%.6ls", L"123"); /* { dg-warning "directive writing between 3 and 6 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 up to 6 bytes into a region of size 4" } */
}
@ -87,37 +91,48 @@ struct Arrays {
/* 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 (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, "%.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, "%.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.
The minus sign disables GCC's sprintf to strcpy transformation. */
T (1, "%-s", a->a1); /* { dg-warning "nul past the end" } */
The minus sign disables GCC's sprintf to strcpy transformation.
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,
their type (the array) is used to bound the maximum length to 1,
which means the "%-s" directive would not overflow the buffer,
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
by the array type to at most 2, the "^-s" directive is diagnosed firts,
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
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->ax); /* { 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 "may write a terminating nul" } */
T (2, "%-s", a->a0);
T (2, "%-s", a->ax);
@ -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
length or flags make it otherwise. */
T (1, "%.*hhi", 0, x); /* { dg-warning "between 0 and 4 bytes" } */
T (2, "%.*hhi", 0, x); /* { dg-warning "between 0 and 4 bytes" } */
T (3, "%.*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 "writing up to 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 (1, "%.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */
T (2, "%.*hhi", 0, y); /* { dg-warning "between 0 and 4 bytes" } */
T (3, "%.*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 "writing up to 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 (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 } */
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", 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)
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", 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 } */
T (1, "%+.*hhi", p, y); /* { dg-warning "writing 1 or more bytes" } */
T (1, "%-.*hhi", p, y); /* { dg-warning "writing 0 or more bytes" } */
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 up to \[0-9\]+ 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 } */
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 } */
T (1, "%-.*hhu", 0, y); /* { dg-warning "between 0 and 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" } */
T (1, "% .*hhu", 0, y); /* { dg-warning "writing up to 3 bytes" } */
/* { dg-warning ". . flag used" "-Wformat" { target *-*-* } .-1 } */
}

View file

@ -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 ? s : "1"); /* { 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 (2, "%s", x ? "" : "1");
@ -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 ( 1)); /* { dg-warning "nul past the end" } */
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, "%o", i ( 0)); /* { dg-warning "nul past the end" } */
@ -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 ( 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 ( 7));
T ( 2, "%o", i ( 010)); /* { dg-warning "nul past the end" } */
@ -211,10 +214,10 @@ void test_sprintf_chk_range_schar (void)
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" } */
/* 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
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" } */
@ -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, 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, 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)

View file

@ -12,14 +12,14 @@ void test (void)
The redundant argument is there to get around GCC bug 77799. */
sprintf (dst + 2, "1", 0);
/* { 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" }
sprintf (dst + 2, "1", 0);
^~~
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst + 2, "1", 0);
~^
^
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" }
sprintf (dst + 2, "1", 0);
@ -29,15 +29,15 @@ void test (void)
/* Verify thet the caret points at the first format character written
past the end of the destination. */
sprintf (dst, "1234", 0);
/* { dg-warning "writing format character .4. at offset 3 past the end of the destination" "nul warning" { target *-*-* } .-1 }
{ dg-message "format output 5 bytes into a destination of size 3" "note" { target *-*-* } .-2 }
/* { dg-warning "writing 4 bytes into a region of size 3" "overlong format string" { target *-*-* } .-1 }
{ dg-message ".sprintf. output 5 bytes into a destination of size 3" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat output: redundant argument" }
sprintf (dst, "1234", 0);
^~~~~~
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst, "1234", 0);
^
~~~^
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" }
sprintf (dst, "1234", 0);
@ -48,15 +48,15 @@ void test (void)
past the end of the destination and the rest of the format string
is underlined. */
sprintf (dst, "12345", 0);
/* { dg-warning "writing format character .4. at offset 3 past the end of the destination" "nul warning" { target *-*-* } .-1 }
{ dg-message "format output 6 bytes into a destination of size 3" "note" { target *-*-* } .-2 }
/* { dg-warning "writing 5 bytes into a region of size 3" "nul warning" { target *-*-* } .-1 }
{ dg-message ".sprintf. output 6 bytes into a destination of size 3" "note" { target *-*-* } .-2 }
{ dg-begin-multiline-output "-Wformat output: redundant argument" }
sprintf (dst, "12345", 0);
^~~~~~~
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "-Wformat-overflow output" }
sprintf (dst, "12345", 0);
^~
~~~^~
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" }
sprintf (dst, "12345", 0);
@ -67,10 +67,10 @@ void test (void)
get around GCC bug 77671. */
sprintf (dst + 2, "%-s", "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" }
sprintf (dst + 2, "%-s", "1");
~~~^
^
{ dg-end-multiline-output "" }
{ dg-begin-multiline-output "note" }
sprintf (dst + 2, "%-s", "1");
@ -79,7 +79,7 @@ void test (void)
sprintf (dst + 2, "%-s", "abcd");
/* { 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" }
sprintf (dst + 2, "%-s", "abcd");
^~~ ~~~~~~
@ -105,8 +105,8 @@ extern char *ptr;
/* 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
an unknown object otherwise. */
#define buffer(size) \
(0 <= size && (!LINE || __LINE__ == LINE) \
#define buffer(size) \
(0 <= size && (!LINE || __LINE__ == LINE) \
? buffer + sizeof buffer - size : ptr)
/* Verify that the note printed along with the diagnostic mentions
@ -124,7 +124,7 @@ void test_sprintf_note (void)
^~
{ 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 "" }
__builtin_sprintf (buffer (0), "%c%s%i", '1', "2", 3);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -137,7 +137,7 @@ void test_sprintf_note (void)
^~ ~~~~
{ 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 "" }
__builtin_sprintf (buffer (1), "%c%s%i", '1', "23", 45);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -150,7 +150,7 @@ void test_sprintf_note (void)
^~
{ 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 "" }
__builtin_sprintf (buffer (2), "%c%s%i", '1', "2", 345);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -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-begin-multiline-output "" }
__builtin_sprintf (buffer (6), "%c%s%i", '1', "2", 3456);
~~~~~~^
^
{ 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 "" }
__builtin_sprintf (buffer (6), "%c%s%i", '1', "2", 3456);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -52,7 +52,7 @@ void fuint (unsigned j, char *p)
if (j > 999)
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)
@ -62,7 +62,7 @@ void fint (int j, char *p)
if (k > 999)
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)
@ -70,7 +70,7 @@ void fulong (unsigned long j, char *p)
if (j > 999)
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)
@ -80,7 +80,7 @@ void flong (long j, char *p)
if (k > 999)
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)
@ -88,7 +88,7 @@ void fullong (unsigned long long j, char *p)
if (j > 999)
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)
@ -98,7 +98,7 @@ void fllong (long long j, char *p)
if (k > 999)
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" } } */

View file

@ -32,14 +32,16 @@ void test_integer_cst (void)
void test_integer_var (int i)
{
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
sign. */
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" } */
/* The following writes INT_MAX digits and, when i is negative, a minus
@ -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_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" } */
@ -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_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" } */
@ -178,14 +183,14 @@ void test_string_cst (void)
void test_string_var (const char *s)
{
T (0, "%*s", INT_MIN, s); /* { dg-warning "writing 2147483648 bytes" } */
T (0, "%*s", INT_MAX, s); /* { dg-warning "writing 2147483647 bytes" } */
T (0, "%*s", INT_MIN, s); /* { dg-warning "writing 2147483648 or more 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_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" } */
}

View file

@ -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", 7); /* { dg-warning "between 7 and 10 bytes" } */
T1 ("%*.a", w); /* { dg-warning "writing 6 or more bytes" } */
T1 ("%*.0a", w); /* { dg-warning "writing 6 or more bytes" } */
T1 ("%*.1a", w); /* { dg-warning "writing 8 or more bytes" } */
T1 ("%*.2a", w); /* { dg-warning "writing 9 or more bytes" } */
T1 ("%*.a", w); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T1 ("%*.0a", w); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T1 ("%*.1a", w); /* { dg-warning "writing between 8 and 2147483648 bytes" } */
T1 ("%*.2a", w); /* { dg-warning "writing between 9 and 2147483648 bytes" } */
T1 ("%.*a", p); /* { dg-warning "writing 6 or more bytes" } */
T1 ("%1.*a", p); /* { dg-warning "writing 6 or more bytes" } */
T1 ("%2.*a", p); /* { dg-warning "writing 6 or more bytes" } */
T1 ("%3.*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 between 6 and 2147483658 bytes" } */
T1 ("%2.*a", p); /* { dg-warning "writing between 6 and 2147483658 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 6 or more bytes" } */
T2 ("%*.*a", w, p); /* { dg-warning "writing 6 or more bytes" } */
T2 ("%*.*a", w, p); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
}
/* Exercise %e. */
@ -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", 7); /* { dg-warning "writing 7 bytes" } */
T1 ("%*.e", w); /* { dg-warning "writing 5 or more bytes" } */
T1 ("%*.0e", w); /* { dg-warning "writing 5 or more bytes" } */
T1 ("%*.1e", w); /* { dg-warning "writing 7 or more bytes" } */
T1 ("%*.2e", w); /* { dg-warning "writing 8 or more bytes" } */
T1 ("%*.e", w); /* { dg-warning "writing between 5 and 2147483648 bytes" } */
T1 ("%*.0e", w); /* { dg-warning "writing between 5 and 2147483648 bytes" } */
T1 ("%*.1e", w); /* { dg-warning "writing between 7 and 2147483648 bytes" } */
T1 ("%*.2e", w); /* { dg-warning "writing between 8 and 2147483648 bytes" } */
T1 ("%.*e", p); /* { dg-warning "writing 5 or more bytes" } */
T1 ("%1.*e", p); /* { dg-warning "writing 5 or more bytes" } */
T1 ("%2.*e", p); /* { dg-warning "writing 5 or more bytes" } */
T1 ("%3.*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 between 5 and 2147483655 bytes" } */
T1 ("%2.*e", p); /* { dg-warning "writing between 5 and 2147483655 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 5 or more bytes" } */
T2 ("%*.*e", w, p); /* { dg-warning "writing 5 or more bytes" } */
T2 ("%*.*e", w, p); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
}
/* Exercise %f. */
@ -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, 313); /* { dg-warning "between 315 and 624 bytes" } */
T1 ("%*.f", w); /* { dg-warning "writing 1 or more bytes" } */
T1 ("%*.0f", w); /* { dg-warning "writing 1 or more bytes" } */
T1 ("%*.1f", w); /* { dg-warning "writing 3 or more bytes" } */
T1 ("%*.2f", w); /* { dg-warning "writing 4 or more bytes" } */
T1 ("%*.f", w); /* { dg-warning "writing between 1 and 2147483648 bytes" } */
T1 ("%*.0f", w); /* { dg-warning "writing between 1 and 2147483648 bytes" } */
T1 ("%*.1f", w); /* { dg-warning "writing between 3 and 2147483648 bytes" } */
T1 ("%*.2f", w); /* { dg-warning "writing between 4 and 2147483648 bytes" } */
T1 ("%.*f", p); /* { dg-warning "writing 1 or more bytes" } */
T1 ("%1.*f", p); /* { dg-warning "writing 1 or more bytes" } */
T1 ("%2.*f", p); /* { dg-warning "writing 2 or more bytes" } */
T1 ("%3.*f", p); /* { dg-warning "writing 3 or more bytes" } */
T1 ("%.*f", p); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T1 ("%1.*f", p); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T1 ("%2.*f", p); /* { dg-warning "writing between 2 and 2147483958 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 1 or more bytes" } */
T2 ("%*.*f", w, p); /* { dg-warning "writing 1 or more bytes" } */
T2 ("%*.*f", w, p); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
}
/* Exercise %g. The expected output is the lesser of %e and %f. */
@ -156,18 +150,18 @@ void test_a_va (va_list va)
T ("%6.a"); /* { dg-warning "between 6 and 10 bytes" } */
T ("%7.a"); /* { dg-warning "between 7 and 10 bytes" } */
T ("%*.a"); /* { dg-warning "writing 6 or more bytes" } */
T ("%*.0a"); /* { dg-warning "writing 6 or more bytes" } */
T ("%*.1a"); /* { dg-warning "writing 8 or more bytes" } */
T ("%*.2a"); /* { dg-warning "writing 9 or more bytes" } */
T ("%*.a"); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T ("%*.0a"); /* { dg-warning "writing between 6 and 2147483648 bytes" } */
T ("%*.1a"); /* { dg-warning "writing between 8 and 2147483648 bytes" } */
T ("%*.2a"); /* { dg-warning "writing between 9 and 2147483648 bytes" } */
T ("%.*a"); /* { dg-warning "writing 6 or more bytes" } */
T ("%1.*a"); /* { dg-warning "writing 6 or more bytes" } */
T ("%2.*a"); /* { dg-warning "writing 6 or more bytes" } */
T ("%6.*a"); /* { dg-warning "writing 6 or more bytes" } */
T ("%9.*a"); /* { dg-warning "writing 9 or more bytes" } */
T ("%.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%1.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%2.*a"); /* { dg-warning "writing between 6 and 2147483658 bytes" } */
T ("%6.*a"); /* { dg-warning "writing between 6 and 2147483658 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. */
@ -195,12 +189,12 @@ void test_e_va (va_list va)
T ("%6.e"); /* { dg-warning "between 6 and 7 bytes" } */
T ("%7.e"); /* { dg-warning "writing 7 bytes" } */
T ("%.*e"); /* { dg-warning "writing 5 or more bytes" } */
T ("%1.*e"); /* { dg-warning "writing 5 or more bytes" } */
T ("%6.*e"); /* { dg-warning "writing 6 or more bytes" } */
T ("%9.*e"); /* { dg-warning "writing 9 or more bytes" } */
T ("%.*e"); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T ("%1.*e"); /* { dg-warning "writing between 5 and 2147483655 bytes" } */
T ("%6.*e"); /* { dg-warning "writing between 6 and 2147483655 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. */
@ -232,11 +226,11 @@ void test_f_va (va_list va)
T ("%312.312f"); /* { dg-warning "between 314 and 623 bytes" } */
T ("%312.313f"); /* { dg-warning "between 315 and 624 bytes" } */
T ("%.*f"); /* { dg-warning "writing 1 or more bytes" } */
T ("%1.*f"); /* { dg-warning "writing 1 or more bytes" } */
T ("%3.*f"); /* { dg-warning "writing 3 or more bytes" } */
T ("%.*f"); /* { dg-warning "writing between 1 and 2147483958 bytes" } */
T ("%1.*f"); /* { dg-warning "writing between 1 and 2147483958 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. */
@ -268,9 +262,9 @@ void test_g_va (va_list va)
T ("%312.313g"); /* { dg-warning "writing 312 bytes" } */
T ("%333.999g"); /* { dg-warning "writing 333 bytes" } */
T ("%.*g"); /* { dg-warning "writing 1 or more bytes" } */
T ("%1.*g"); /* { dg-warning "writing 1 or more bytes" } */
T ("%4.*g"); /* { dg-warning "writing 4 or more bytes" } */
T ("%.*g"); /* { dg-warning "writing between 1 and 310 bytes" } */
T ("%1.*g"); /* { dg-warning "writing between 1 and 310 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" } */
}

View file

@ -3,10 +3,8 @@
constant folding. With optimization enabled the test will fail to
link if any of the assertions fails. Without optimization the test
aborts at runtime if any of the assertions fails. */
/* { dg-do run }
The h and hh length modifiers are a C99 feature (see PR 78959).
{ dg-require-effective-target c99_runtime }
{ dg-additional-options "-O2 -Wall -Wno-pedantic -fprintf-return-value" } */
/* { dg-do run } */
/* { dg-additional-options "-O2 -Wall -Wno-pedantic -fprintf-return-value" } */
#ifndef LINE
# define LINE 0
@ -320,7 +318,6 @@ test_d_i (int i, long li)
#if __SIZEOF_SHORT__ == 2
RNG ( 1, 6, 7, "%hi", i);
RNG ( 1, 5, 6, "%hu", i);
RNG ( 1, 6, 7, "%.1hi", i);
RNG ( 2, 6, 7, "%.2hi", i);
RNG ( 3, 6, 7, "%.3hi", i);
@ -328,7 +325,6 @@ test_d_i (int i, long li)
RNG ( 5, 6, 7, "%.5hi", i);
RNG ( 6, 7, 8, "%.6hi", i);
RNG ( 7, 8, 9, "%.7hi", i);
#elif __SIZEOF_SHORT__ == 4
RNG ( 1, 11, 12, "%hi", i);
RNG ( 1, 10, 11, "%hu", i);
@ -474,16 +470,21 @@ test_a_double (double d)
EQL ( 6, 7, "%.0a", 0.0); /* 0x0p+0 */
EQL ( 6, 7, "%.0a", 1.0); /* 0x8p-3 */
EQL ( 6, 7, "%.0a", 2.0); /* 0x8p-2 */
EQL ( 8, 9, "%.1a", 3.0); /* 0xc.0p-2 */
EQL ( 9, 10, "%.2a", 4.0); /* 0x8.00p-1 */
EQL (10, 11, "%.3a", 5.0); /* 0xa.000p-1 */
EQL (11, 12, "%.*a", 4, 6.0); /* 0xc.0000p-1 */
EQL (12, 13, "%.*a", 5, 7.0); /* 0xe.00000p-1 */
/* The decimal point may be up to MB_LEN_MAX long. */
RNG ( 8, 13, 14, "%.1a", 3.0); /* 0xc.0p-2 */
RNG ( 9, 14, 15, "%.2a", 4.0); /* 0x8.00p-1 */
RNG (10, 15, 16, "%.3a", 5.0); /* 0xa.000p-1 */
RNG (11, 16, 17, "%.*a", 4, 6.0); /* 0xc.0000p-1 */
RNG (12, 17, 18, "%.*a", 5, 7.0); /* 0xe.00000p-1 */
/* d is in [ 0, -DBL_MAX ] */
RNG ( 6, 10, 11, "%.0a", d); /* 0x0p+0 ... -0x2p+1023 */
RNG ( 6, 12, 13, "%.1a", d); /* 0x0p+0 ... -0x2.0p+1023 */
RNG ( 6, 13, 14, "%.2a", d); /* 0x0p+0 ... -0x2.00p+1023 */
/* %a is poorly specified and allows for implementations divergence:
some (such as Glibc) trim redundant trailing zeros after decimal
point and others (e.g., Solaris) don't. */
RNG ( 8, 30, 31, "%.1a", d); /* 0x0.0p+0 ... -0x2.0...0p+1023 */
RNG ( 9, 30, 31, "%.2a", d); /* 0x0.00p+0 ... -0x2.00...0p+1023 */
}
static void __attribute__ ((noinline, noclone))
@ -492,159 +493,161 @@ test_a_long_double (void)
EQL ( 6, 7, "%.0La", 0.0L); /* 0x0p+0 */
EQL ( 6, 7, "%.0La", 1.0L); /* 0x8p-3 */
EQL ( 6, 7, "%.0La", 2.0L); /* 0x8p-2 */
EQL ( 8, 9, "%.1La", 3.0L); /* 0xc.0p-2 */
EQL ( 9, 10, "%.2La", 4.0L); /* 0xa.00p-1 */
RNG ( 8, 13, 14, "%.1La", 3.0L); /* 0xc.0p-2 */
RNG ( 9, 14, 15, "%.2La", 4.0L); /* 0xa.00p-1 */
}
static void __attribute__ ((noinline, noclone))
test_e_double (double d)
{
EQL (12, 13, "%e", 1.0e0);
EQL (13, 14, "%e", -1.0e0);
EQL (12, 13, "%e", 1.0e+1);
EQL (13, 14, "%e", -1.0e+1);
EQL (12, 13, "%e", 1.0e+12);
EQL (13, 14, "%e", -1.0e+12);
EQL (13, 14, "%e", 1.0e+123);
EQL (14, 15, "%e", -1.0e+123);
RNG (12, 17, 18, "%e", 1.0e0);
RNG (13, 18, 19, "%e", -1.0e0);
RNG (12, 17, 18, "%e", 1.0e+1);
RNG (13, 18, 19, "%e", -1.0e+1);
RNG (12, 17, 18, "%e", 1.0e+12);
RNG (13, 18, 19, "%e", -1.0e+12);
RNG (13, 18, 19, "%e", 1.0e+123);
RNG (14, 19, 20, "%e", -1.0e+123);
EQL (12, 13, "%e", 9.999e+99);
EQL (12, 13, "%e", 9.9999e+99);
EQL (12, 13, "%e", 9.99999e+99);
RNG (12, 17, 18, "%e", 9.999e+99);
RNG (12, 17, 18, "%e", 9.9999e+99);
RNG (12, 17, 18, "%e", 9.99999e+99);
/* The actual output of the following directive depends on the rounding
mode. */
/* EQL (12, "%e", 9.9999994e+99); */
/* RNG (12, "%e", 9.9999994e+99); */
EQL (12, 13, "%e", 1.0e-1);
EQL (12, 13, "%e", 1.0e-12);
EQL (13, 14, "%e", 1.0e-123);
RNG (12, 17, 18, "%e", 1.0e-1);
RNG (12, 17, 18, "%e", 1.0e-12);
RNG (13, 18, 19, "%e", 1.0e-123);
RNG (12, 14, 15, "%e", d);
RNG ( 5, 7, 8, "%.e", d);
RNG ( 5, 7, 8, "%.0e", d);
RNG ( 7, 9, 10, "%.1e", d);
RNG ( 8, 10, 11, "%.2e", d);
RNG ( 9, 11, 12, "%.3e", d);
RNG (10, 12, 13, "%.4e", d);
RNG (11, 13, 14, "%.5e", d);
RNG (12, 14, 15, "%.6e", d);
RNG (13, 15, 16, "%.7e", d);
RNG (12, 19, 20, "%e", d);
RNG ( 5, 11, 12, "%.e", d);
RNG ( 5, 12, 13, "%.0e", d);
RNG ( 7, 14, 15, "%.1e", d);
RNG ( 8, 15, 16, "%.2e", d);
RNG ( 9, 16, 17, "%.3e", d);
RNG (10, 17, 18, "%.4e", d);
RNG (11, 18, 19, "%.5e", d);
RNG (12, 19, 20, "%.6e", d);
RNG (13, 20, 21, "%.7e", d);
RNG (4006, 4008, 4009, "%.4000e", d);
RNG (4006, 4013, 4014, "%.4000e", d);
RNG ( 5, 7, 8, "%.*e", 0, d);
RNG ( 7, 9, 10, "%.*e", 1, d);
RNG ( 8, 10, 11, "%.*e", 2, d);
RNG ( 9, 11, 12, "%.*e", 3, d);
RNG (10, 12, 13, "%.*e", 4, d);
RNG (11, 13, 14, "%.*e", 5, d);
RNG (12, 14, 15, "%.*e", 6, d);
RNG (13, 15, 16, "%.*e", 7, d);
RNG ( 7, 14, 15, "%.*e", 1, d);
RNG ( 8, 15, 16, "%.*e", 2, d);
RNG ( 9, 16, 17, "%.*e", 3, d);
RNG (10, 17, 18, "%.*e", 4, d);
RNG (11, 18, 19, "%.*e", 5, d);
RNG (12, 19, 20, "%.*e", 6, d);
RNG (13, 20, 21, "%.*e", 7, d);
RNG (4006, 4008, 4009, "%.*e", 4000, d);
RNG (4006, 4013, 4014, "%.*e", 4000, d);
}
static void __attribute__ ((noinline, noclone))
test_e_long_double (long double d)
{
EQL (12, 13, "%Le", 1.0e0L);
EQL (13, 14, "%Le", -1.0e0L);
EQL (12, 13, "%Le", 1.0e+1L);
EQL (13, 14, "%Le", -1.0e+1L);
EQL (12, 13, "%Le", 1.0e+12L);
EQL (13, 14, "%Le", -1.0e+12L);
EQL (13, 14, "%Le", 1.0e+123L);
EQL (14, 15, "%Le", -1.0e+123L);
RNG (12, 17, 18, "%Le", 1.0e0L);
RNG (13, 18, 19, "%Le", -1.0e0L);
RNG (12, 17, 18, "%Le", 1.0e+1L);
RNG (13, 18, 19, "%Le", -1.0e+1L);
RNG (12, 18, 19, "%Le", 1.0e+12L);
RNG (13, 19, 20, "%Le", -1.0e+12L);
RNG (13, 19, 20, "%Le", 1.0e+123L);
RNG (14, 20, 21, "%Le", -1.0e+123L);
EQL (12, 13, "%Le", 9.999e+99L);
EQL (12, 13, "%Le", 9.9999e+99L);
EQL (12, 13, "%Le", 9.99999e+99L);
RNG (12, 18, 19, "%Le", 9.999e+99L);
RNG (12, 18, 19, "%Le", 9.9999e+99L);
RNG (12, 18, 19, "%Le", 9.99999e+99L);
#if __DBL_DIG__ < __LDBL_DIG__
EQL (12, 13, "%Le", 9.999999e+99L);
RNG (12, 17, 18, "%Le", 9.999999e+99L);
#else
RNG (12, 13, 14, "%Le", 9.999999e+99L);
RNG (12, 18, 19, "%Le", 9.999999e+99L);
#endif
/* The actual output of the following directive depends on the rounding
mode. */
/* EQL (12, "%Le", 9.9999994e+99L); */
/* RNG (12, "%Le", 9.9999994e+99L); */
EQL (12, 13, "%Le", 1.0e-1L);
EQL (12, 13, "%Le", 1.0e-12L);
EQL (13, 14, "%Le", 1.0e-123L);
RNG (12, 17, 18, "%Le", 1.0e-1L);
RNG (12, 17, 18, "%Le", 1.0e-12L);
RNG (13, 18, 19, "%Le", 1.0e-123L);
EQL ( 6, 7, "%.0Le", 1.0e-111L);
EQL ( 8, 9, "%.1Le", 1.0e-111L);
EQL (19, 20, "%.12Le", 1.0e-112L);
EQL (20, 21, "%.13Le", 1.0e-113L);
RNG ( 8, 13, 14, "%.1Le", 1.0e-111L);
RNG (19, 25, 25, "%.12Le", 1.0e-112L);
RNG (20, 26, 27, "%.13Le", 1.0e-113L);
/* The following correspond to the double results plus 1 for the upper
bound accounting for the four-digit exponent. */
RNG (12, 15, 16, "%Le", d); /* 0.000000e+00 ... -1.189732e+4932 */
RNG (12, 20, 21, "%Le", d); /* 0.000000e+00 ... -1.189732e+4932 */
RNG ( 5, 8, 9, "%.Le", d);
RNG ( 5, 9, 10, "%.0Le", d);
RNG ( 7, 10, 11, "%.1Le", d); /* 0.0e+00 ... -1.2e+4932 */
RNG ( 8, 11, 12, "%.2Le", d); /* 0.00e+00 ... -1.19e+4932 */
RNG ( 9, 12, 13, "%.3Le", d);
RNG (10, 13, 14, "%.4Le", d);
RNG (11, 14, 15, "%.5Le", d);
RNG (12, 15, 16, "%.6Le", d); /* same as plain "%Le" */
RNG (13, 16, 17, "%.7Le", d); /* 0.0000000e+00 ... -1.1897315e+4932 */
RNG ( 7, 15, 16, "%.1Le", d); /* 0.0e+00 ... -1.2e+4932 */
RNG ( 8, 16, 17, "%.2Le", d); /* 0.00e+00 ... -1.19e+4932 */
RNG ( 9, 17, 18, "%.3Le", d);
RNG (10, 18, 19, "%.4Le", d);
RNG (11, 19, 20, "%.5Le", d);
RNG (12, 20, 21, "%.6Le", d); /* same as plain "%Le" */
RNG (13, 21, 22, "%.7Le", d); /* 0.0000000e+00 ... -1.1897315e+4932 */
RNG ( 5, 9, 10, "%.*Le", 0, d);
RNG ( 7, 10, 11, "%.*Le", 1, d);
RNG ( 8, 11, 12, "%.*Le", 2, d);
RNG ( 9, 12, 13, "%.*Le", 3, d);
RNG (10, 13, 14, "%.*Le", 4, d);
RNG (11, 14, 15, "%.*Le", 5, d);
RNG (12, 15, 16, "%.*Le", 6, d);
RNG (13, 16, 17, "%.*Le", 7, d);
RNG ( 7, 15, 16, "%.*Le", 1, d);
RNG ( 8, 16, 17, "%.*Le", 2, d);
RNG ( 9, 17, 18, "%.*Le", 3, d);
RNG (10, 18, 19, "%.*Le", 4, d);
RNG (11, 19, 20, "%.*Le", 5, d);
RNG (12, 20, 21, "%.*Le", 6, d);
RNG (13, 21, 22, "%.*Le", 7, d);
}
static void __attribute__ ((noinline, noclone))
test_f_double (double d)
{
EQL ( 8, 9, "%f", 0.0e0);
EQL ( 8, 9, "%f", 0.1e0);
EQL ( 8, 9, "%f", 0.12e0);
EQL ( 8, 9, "%f", 0.123e0);
EQL ( 8, 9, "%f", 0.1234e0);
EQL ( 8, 9, "%f", 0.12345e0);
EQL ( 8, 9, "%f", 0.123456e0);
EQL ( 8, 9, "%f", 1.234567e0);
RNG ( 8, 13, 14, "%f", 0.0e0);
RNG ( 8, 13, 14, "%f", 0.1e0);
RNG ( 8, 13, 14, "%f", 0.12e0);
RNG ( 8, 13, 14, "%f", 0.123e0);
RNG ( 8, 13, 14, "%f", 0.1234e0);
RNG ( 8, 13, 14, "%f", 0.12345e0);
RNG ( 8, 13, 14, "%f", 0.123456e0);
RNG ( 8, 13, 14, "%f", 1.234567e0);
EQL ( 9, 10, "%f", 1.0e+1);
EQL ( 20, 21, "%f", 1.0e+12);
EQL (130, 131, "%f", 1.0e+123);
RNG ( 9, 14, 15, "%f", 1.0e+1);
RNG ( 20, 26, 27, "%f", 1.0e+12);
RNG (130, 136, 137, "%f", 1.0e+123);
EQL ( 8, 9, "%f", 1.0e-1);
EQL ( 8, 9, "%f", 1.0e-12);
EQL ( 8, 9, "%f", 1.0e-123);
RNG ( 8, 13, 14, "%f", 1.0e-1);
RNG ( 8, 13, 14, "%f", 1.0e-12);
RNG ( 8, 13, 14, "%f", 1.0e-123);
RNG ( 8, 317, 318, "%f", d);
RNG ( 8, 322, 323, "%f", d);
}
static void __attribute__ ((noinline, noclone))
test_f_long_double (void)
{
EQL ( 8, 9, "%Lf", 0.0e0L);
EQL ( 8, 9, "%Lf", 0.1e0L);
EQL ( 8, 9, "%Lf", 0.12e0L);
EQL ( 8, 9, "%Lf", 0.123e0L);
EQL ( 8, 9, "%Lf", 0.1234e0L);
EQL ( 8, 9, "%Lf", 0.12345e0L);
EQL ( 8, 9, "%Lf", 0.123456e0L);
EQL ( 8, 9, "%Lf", 1.234567e0L);
RNG ( 8, 15, 16, "%Lf", 0.0e0L);
RNG ( 8, 14, 15, "%Lf", 0.1e0L);
RNG ( 8, 14, 15, "%Lf", 0.12e0L);
RNG ( 8, 14, 15, "%Lf", 0.123e0L);
RNG ( 8, 14, 15, "%Lf", 0.1234e0L);
RNG ( 8, 14, 15, "%Lf", 0.12345e0L);
RNG ( 8, 14, 15, "%Lf", 0.123456e0L);
RNG ( 8, 14, 15, "%Lf", 1.234567e0L);
EQL ( 9, 10, "%Lf", 1.0e+1L);
EQL ( 20, 21, "%Lf", 1.0e+12L);
EQL (130, 131, "%Lf", 1.0e+123L);
RNG ( 9, 15, 16, "%Lf", 1.0e+1L);
RNG ( 20, 26, 27, "%Lf", 1.0e+12L);
RNG (130, 136, 137, "%Lf", 1.0e+123L);
EQL ( 8, 9, "%Lf", 1.0e-1L);
EQL ( 8, 9, "%Lf", 1.0e-12L);
EQL ( 8, 9, "%Lf", 1.0e-123L);
RNG ( 8, 14, 15, "%Lf", 1.0e-1L);
RNG ( 8, 14, 15, "%Lf", 1.0e-12L);
RNG ( 8, 14, 15, "%Lf", 1.0e-123L);
}
static void __attribute__ ((noinline, noclone))
@ -652,52 +655,54 @@ test_g_double (double d)
{
/* Numbers exactly representable in binary floating point. */
EQL ( 1, 2, "%g", 0.0);
EQL ( 3, 4, "%g", 1.0 / 2);
EQL ( 4, 5, "%g", 1.0 / 4);
EQL ( 5, 6, "%g", 1.0 / 8);
EQL ( 6, 7, "%g", 1.0 / 16);
EQL ( 7, 8, "%g", 1.0 / 32);
EQL ( 8, 9, "%g", 1.0 / 64);
EQL ( 9, 10, "%g", 1.0 / 128);
EQL ( 10, 11, "%g", 1.0 / 256);
EQL ( 10, 11, "%g", 1.0 / 512);
RNG ( 3, 8, 9, "%g", 1.0 / 2);
RNG ( 4, 9, 10, "%g", 1.0 / 4);
RNG ( 5, 10, 11, "%g", 1.0 / 8);
RNG ( 6, 11, 12, "%g", 1.0 / 16);
RNG ( 7, 12, 13, "%g", 1.0 / 32);
RNG ( 8, 13, 14, "%g", 1.0 / 64);
RNG ( 9, 14, 15, "%g", 1.0 / 128);
RNG ( 10, 15, 16, "%g", 1.0 / 256);
RNG ( 10, 16, 17, "%g", 1.0 / 512);
/* Numbers that are not exactly representable. */
RNG ( 3, 8, 9, "%g", 0.1);
RNG ( 4, 8, 9, "%g", 0.12);
RNG ( 5, 8, 9, "%g", 0.123);
RNG ( 6, 8, 9, "%g", 0.1234);
RNG ( 7, 8, 9, "%g", 0.12345);
RNG ( 8, 8, 9, "%g", 0.123456);
RNG ( 3, 13, 14, "%g", 0.1);
RNG ( 4, 13, 14, "%g", 0.12);
RNG ( 5, 13, 14, "%g", 0.123);
RNG ( 6, 13, 14, "%g", 0.1234);
RNG ( 7, 13, 14, "%g", 0.12345);
RNG ( 8, 13, 14, "%g", 0.123456);
RNG ( 4, 7, 8, "%g", 0.123e+1);
EQL ( 8, 9, "%g", 0.123e+12);
RNG ( 9, 12, 13, "%g", 0.123e+134);
RNG ( 4, 17, 18, "%g", 0.123e+1);
RNG ( 8, 18, 19, "%g", 0.123e+12);
RNG ( 9, 19, 20, "%g", 0.123e+134);
RNG ( 1, 13, 14, "%g", d);
RNG ( 1, 7, 8, "%.g", d);
RNG ( 1, 7, 8, "%.0g", d);
RNG ( 1, 7, 8, "%.1g", d);
RNG ( 1, 9, 10, "%.2g", d);
RNG ( 1, 10, 11, "%.3g", d);
RNG ( 1, 11, 12, "%.4g", d);
RNG ( 1, 12, 13, "%.5g", d);
RNG ( 1, 13, 14, "%.6g", d);
RNG ( 1, 14, 15, "%.7g", d);
RNG ( 1, 15, 16, "%.8g", d);
RNG ( 1, 18, 19, "%g", d);
RNG ( 1, 12, 13, "%.g", d);
RNG ( 1, 12, 13, "%.0g", d);
RNG ( 1, 12, 13, "%.1g", d);
RNG ( 1, 14, 15, "%.2g", d);
RNG ( 1, 15, 16, "%.3g", d);
RNG ( 1, 16, 17, "%.4g", d);
RNG ( 1, 17, 18, "%.5g", d);
RNG ( 1, 18, 19, "%.6g", d);
RNG ( 1, 19, 20, "%.7g", d);
RNG ( 1, 20, 21, "%.8g", d);
RNG ( 1,310,311, "%.9999g", d);
RNG ( 1, 315, 316, "%.9999g", d);
RNG ( 1, 7, 8, "%.*g", 0, d);
RNG ( 1, 7, 8, "%.*g", 1, d);
RNG ( 1, 9, 10, "%.*g", 2, d);
RNG ( 1, 10, 11, "%.*g", 3, d);
RNG ( 1, 11, 12, "%.*g", 4, d);
RNG ( 1, 12, 13, "%.*g", 5, d);
RNG ( 1, 13, 14, "%.*g", 6, d);
RNG ( 1, 14, 15, "%.*g", 7, d);
RNG ( 1, 15, 16, "%.*g", 8, d);
RNG ( 1,310,311, "%.*g", 9999, d);
RNG ( 1, 12, 13, "%.*g", 0, d);
RNG ( 1, 12, 13, "%.*g", 1, d);
RNG ( 1, 14, 15, "%.*g", 2, d);
RNG ( 1, 15, 16, "%.*g", 3, d);
RNG ( 1, 16, 17, "%.*g", 4, d);
RNG ( 1, 17, 18, "%.*g", 5, d);
RNG ( 1, 18, 19, "%.*g", 6, d);
RNG ( 1, 19, 20, "%.*g", 7, d);
RNG ( 1, 20, 21, "%.*g", 8, d);
RNG ( 1, 315, 316, "%.*g", 9999, d);
}
static void __attribute__ ((noinline, noclone))
@ -705,36 +710,27 @@ test_g_long_double (void)
{
/* Numbers exactly representable in binary floating point. */
EQL ( 1, 2, "%Lg", 0.0L);
EQL ( 3, 4, "%Lg", 1.0L / 2);
EQL ( 4, 5, "%Lg", 1.0L / 4);
EQL ( 5, 6, "%Lg", 1.0L / 8);
EQL ( 6, 7, "%Lg", 1.0L / 16);
EQL ( 7, 8, "%Lg", 1.0L / 32);
EQL ( 8, 9, "%Lg", 1.0L / 64);
EQL ( 9, 10, "%Lg", 1.0L / 128);
EQL ( 10, 11, "%Lg", 1.0L / 256);
EQL ( 10, 11, "%Lg", 1.0L / 512);
RNG ( 3, 8, 9, "%Lg", 1.0L / 2);
RNG ( 4, 9, 10, "%Lg", 1.0L / 4);
RNG ( 5, 10, 11, "%Lg", 1.0L / 8);
RNG ( 6, 11, 12, "%Lg", 1.0L / 16);
RNG ( 7, 12, 13, "%Lg", 1.0L / 32);
RNG ( 8, 13, 14, "%Lg", 1.0L / 64);
RNG ( 9, 14, 15, "%Lg", 1.0L / 128);
RNG ( 10, 15, 16, "%Lg", 1.0L / 256);
RNG ( 10, 15, 16, "%Lg", 1.0L / 512);
/* Numbers that are not exactly representable. */
#if __LDBL_DIG__ < 31
/* x86_64, for example, represents 0.1 as 1.000000...1...e-1
and formats it as either "0.1" (when rounded down) or "0.100001"
(rounded up). */
RNG ( 3, 8, 9, "%Lg", 0.1L);
#else
/* powerpc64 represents 0.1 as 9.999999...6e-2 and formats it
as "0.0999999" (rounded down) or "0.1" (rounded up). */
RNG ( 3, 9, 10, "%Lg", 0.1L);
#endif
RNG ( 4, 8, 9, "%Lg", 0.12L);
RNG ( 5, 8, 9, "%Lg", 0.123L);
RNG ( 6, 8, 9, "%Lg", 0.1234L);
RNG ( 7, 8, 9, "%Lg", 0.12345L);
RNG ( 8, 8, 9, "%Lg", 0.123456L);
RNG ( 3, 13, 14, "%Lg", 0.1L);
RNG ( 4, 13, 14, "%Lg", 0.12L);
RNG ( 5, 13, 14, "%Lg", 0.123L);
RNG ( 6, 13, 14, "%Lg", 0.1234L);
RNG ( 7, 13, 14, "%Lg", 0.12345L);
RNG ( 8, 13, 14, "%Lg", 0.123456L);
RNG ( 4, 7, 8, "%Lg", 0.123e+1L);
EQL ( 8, 9, "%Lg", 0.123e+12L);
RNG ( 9, 12, 13, "%Lg", 0.123e+134L);
RNG ( 4, 12, 13, "%Lg", 0.123e+1L);
RNG ( 8, 13, 14, "%Lg", 0.123e+12L);
RNG ( 9, 17, 18, "%Lg", 0.123e+134L);
}
static void __attribute__ ((noinline, noclone))