c-common.c (print_char_table): Allow 'I' flag with %d, %i and %u.
* c-common.c (print_char_table): Allow 'I' flag with %d, %i and %u. (check_format_info): Support printf 'I' flag; warn about it with -pedantic. testsuite: * gcc.dg/c99-printf-2.c, gcc.dg/format-xopen-1.c: Add some more tests. * gcc.dg/format-ext-1.c: New test. From-SVN: r35917
This commit is contained in:
parent
94350948fb
commit
d8eceea40c
@ -1,3 +1,10 @@
|
|||||||
|
2000-08-23 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||||
|
|
||||||
|
* c-common.c (print_char_table): Allow 'I' flag with %d, %i and
|
||||||
|
%u.
|
||||||
|
(check_format_info): Support printf 'I' flag; warn about it with
|
||||||
|
-pedantic.
|
||||||
|
|
||||||
2000-08-23 Richard Earnshaw (rearnsha@arm.com)
|
2000-08-23 Richard Earnshaw (rearnsha@arm.com)
|
||||||
|
|
||||||
* arm.c (arm_expand_prologue): Ensure that the stack-adjustment
|
* arm.c (arm_expand_prologue): Ensure that the stack-adjustment
|
||||||
|
@ -1236,9 +1236,9 @@ typedef struct {
|
|||||||
} format_char_info;
|
} format_char_info;
|
||||||
|
|
||||||
static format_char_info print_char_table[] = {
|
static format_char_info print_char_table[] = {
|
||||||
{ "di", 0, T_I, T_I, T_I, T_L, T_LL, T_LL, T_SST, T_PD, T_IM, "-wp0 +'" },
|
{ "di", 0, T_I, T_I, T_I, T_L, T_LL, T_LL, T_SST, T_PD, T_IM, "-wp0 +'I" },
|
||||||
{ "oxX", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, T_UPD, T_UIM, "-wp0#" },
|
{ "oxX", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, T_UPD, T_UIM, "-wp0#" },
|
||||||
{ "u", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, T_UPD, T_UIM, "-wp0'" },
|
{ "u", 0, T_UI, T_UI, T_UI, T_UL, T_ULL, T_ULL, T_ST, T_UPD, T_UIM, "-wp0'I" },
|
||||||
/* A GNU extension. */
|
/* A GNU extension. */
|
||||||
{ "m", 0, T_V, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" },
|
{ "m", 0, T_V, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" },
|
||||||
{ "fFgG", 0, T_D, NULL, NULL, T_D, NULL, T_LD, NULL, NULL, NULL, "-wp0 +#'" },
|
{ "fFgG", 0, T_D, NULL, NULL, T_D, NULL, T_LD, NULL, NULL, NULL, "-wp0 +#'" },
|
||||||
@ -1916,7 +1916,7 @@ check_format_info (info, params)
|
|||||||
has_operand_number = 0;
|
has_operand_number = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*format_chars != 0 && index (" +#0-'", *format_chars) != 0)
|
while (*format_chars != 0 && index (" +#0-'I", *format_chars) != 0)
|
||||||
{
|
{
|
||||||
if (index (flag_chars, *format_chars) != 0)
|
if (index (flag_chars, *format_chars) != 0)
|
||||||
warning ("repeated `%c' flag in format", *format_chars++);
|
warning ("repeated `%c' flag in format", *format_chars++);
|
||||||
@ -1939,6 +1939,8 @@ check_format_info (info, params)
|
|||||||
warning ("use of both `0' and `-' flags in format");
|
warning ("use of both `0' and `-' flags in format");
|
||||||
if (index (flag_chars, '\'') && pedantic)
|
if (index (flag_chars, '\'') && pedantic)
|
||||||
warning ("ISO C does not support the `'' format flag");
|
warning ("ISO C does not support the `'' format flag");
|
||||||
|
if (index (flag_chars, 'I') && pedantic)
|
||||||
|
warning ("ISO C does not support the `I' format flag");
|
||||||
if (*format_chars == '*')
|
if (*format_chars == '*')
|
||||||
{
|
{
|
||||||
wide = TRUE;
|
wide = TRUE;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2000-08-23 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||||
|
|
||||||
|
* gcc.dg/c99-printf-2.c, gcc.dg/format-xopen-1.c: Add some more
|
||||||
|
tests.
|
||||||
|
* gcc.dg/format-ext-1.c: New test.
|
||||||
|
|
||||||
2000-08-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
2000-08-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||||
|
|
||||||
* gcc.dg/cpp/tr-warn4.c, gcc.dg/cpp/tr-warn5.c,
|
* gcc.dg/cpp/tr-warn4.c, gcc.dg/cpp/tr-warn5.c,
|
||||||
|
@ -31,4 +31,6 @@ foo (int i, long long ll, size_t z, wint_t lc, wchar_t *ls)
|
|||||||
*/
|
*/
|
||||||
printf ("%'d", i); /* { dg-warning "C" "printf ' flag" } */
|
printf ("%'d", i); /* { dg-warning "C" "printf ' flag" } */
|
||||||
printf ("%1$d", i); /* { dg-warning "C" "printf $ format" } */
|
printf ("%1$d", i); /* { dg-warning "C" "printf $ format" } */
|
||||||
|
/* The flag character I is a GNU extension. */
|
||||||
|
printf ("%Id", i); /* { dg-warning "C" "printf I flag" } */
|
||||||
}
|
}
|
||||||
|
120
gcc/testsuite/gcc.dg/format-ext-1.c
Normal file
120
gcc/testsuite/gcc.dg/format-ext-1.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* Test for format extensions beyond the C standard and X/Open standard.
|
||||||
|
Test for printf formats.
|
||||||
|
*/
|
||||||
|
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-std=gnu99 -Wformat" } */
|
||||||
|
|
||||||
|
/* %q formats want a "quad"; GCC considers this to be a long long. */
|
||||||
|
typedef long long int quad_t;
|
||||||
|
typedef unsigned long long int u_quad_t;
|
||||||
|
|
||||||
|
typedef __WCHAR_TYPE__ wchar_t;
|
||||||
|
typedef __WINT_TYPE__ wint_t;
|
||||||
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
|
||||||
|
extern int printf (const char *, ...);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (quad_t q, u_quad_t uq, quad_t *qn, size_t z, size_t *zn, long long int ll,
|
||||||
|
unsigned long long int ull, int i, unsigned int u, double d,
|
||||||
|
char *s, void *p, wchar_t *ls, wint_t lc, int *n)
|
||||||
|
{
|
||||||
|
/* As an extension, GCC allows the BSD length "q" for integer formats.
|
||||||
|
This is largely obsoleted in C99 by %j, %ll and PRId64.
|
||||||
|
*/
|
||||||
|
printf ("%qd%qi%qo%qu%qx%qX%qn", q, q, uq, uq, uq, uq, qn);
|
||||||
|
printf ("%qf", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qF", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qe", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qE", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qg", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qG", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qa", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qA", d); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qc", i); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qs", s); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qp", p); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qC", lc); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
printf ("%qS", ls); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
/* With a bad length character GCC wants some argument, any argument,
|
||||||
|
to devour with the format conversion, as a synchronisation heuristic.
|
||||||
|
This may get improved later.
|
||||||
|
*/
|
||||||
|
printf ("%qm", i); /* { dg-warning "length character" "bad use of %q" } */
|
||||||
|
/* As an extension, GCC allows the length "Z" as a synonym for "z".
|
||||||
|
This was an extension predating C99 which should now be considered
|
||||||
|
deprecated; use the standard "z" instead.
|
||||||
|
*/
|
||||||
|
printf ("%Zd%Zi%Zo%Zu%Zx%ZX", z, z, z, z, z, z);
|
||||||
|
printf ("%Zn", zn);
|
||||||
|
printf ("%Zf", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%ZF", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Ze", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%ZE", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Zg", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%ZG", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Za", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%ZA", d); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Zc", i); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Zs", s); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Zp", p); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%ZC", lc); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%ZS", ls); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
printf ("%Zm", i); /* { dg-warning "length character" "bad use of %Z" } */
|
||||||
|
/* As an extension, GCC allows the length "L" on integer formats
|
||||||
|
(but not %n) as a synonym for "ll".
|
||||||
|
This should be considered deprecated.
|
||||||
|
*/
|
||||||
|
printf ("%Ld%Li%Lo%Lu%Lx%LX", ll, ll, ull, ull, ull, ull);
|
||||||
|
/* As an extension, derived from syslog, GCC allows the conversion
|
||||||
|
specifier "m" for formatting strerror(errno). This may be used
|
||||||
|
with width, precision and the "-" flag, the same as %s.
|
||||||
|
*/
|
||||||
|
printf ("%m%3m%.4m%5.6m");
|
||||||
|
printf ("%*m", i);
|
||||||
|
printf ("%.*m", i);
|
||||||
|
printf ("%*.*m", i, i);
|
||||||
|
printf ("%3.*m", i);
|
||||||
|
printf ("%*.4m", i);
|
||||||
|
printf ("%-m");
|
||||||
|
printf ("%+m"); /* { dg-warning "flag" "bad %+m" } */
|
||||||
|
printf ("% m"); /* { dg-warning "flag" "bad % m" } */
|
||||||
|
printf ("%#m"); /* { dg-warning "flag" "bad %#m" } */
|
||||||
|
printf ("%0m"); /* { dg-warning "flag" "bad %0m" } */
|
||||||
|
printf ("%'m"); /* { dg-warning "flag" "bad %'m" } */
|
||||||
|
printf ("%hm", i); /* { dg-warning "length character" "bad %hm" } */
|
||||||
|
printf ("%hhm", i); /* { dg-warning "length character" "bad %hhm" } */
|
||||||
|
printf ("%lm", i); /* { dg-warning "length character" "bad %lm" } */
|
||||||
|
printf ("%llm", i); /* { dg-warning "length character" "bad %llm" } */
|
||||||
|
printf ("%jm", i); /* { dg-warning "length character" "bad %jm" } */
|
||||||
|
printf ("%zm", i); /* { dg-warning "length character" "bad %zm" } */
|
||||||
|
printf ("%tm", i); /* { dg-warning "length character" "bad %tm" } */
|
||||||
|
printf ("%Lm", i); /* { dg-warning "length character" "bad %Lm" } */
|
||||||
|
printf ("%qm", i); /* { dg-warning "length character" "bad %qm" } */
|
||||||
|
printf ("%Zm", i); /* { dg-warning "length character" "bad %Zm" } */
|
||||||
|
/* As an extension, glibc includes the "I" flag for decimal integer
|
||||||
|
formats, to output using the locale's digits (e.g. in Arabic).
|
||||||
|
In GCC, we require this to be in the standard place for flags, though
|
||||||
|
glibc allows it also after width or precision.
|
||||||
|
*/
|
||||||
|
printf ("%Id%Ii%Iu", i, i, u);
|
||||||
|
printf ("%Io", u); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Ix", u); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IX", u); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%In", n); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%If", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IF", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Ie", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IE", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Ig", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IG", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Ia", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IA", d); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Ic", i); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Is", s); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Ip", p); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IC", lc); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%IS", ls); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
printf ("%Im"); /* { dg-warning "flag" "bad use of I flag" } */
|
||||||
|
}
|
@ -38,6 +38,7 @@ foo (int i, unsigned int u, wint_t lc, wchar_t *ls, int *ip, double d,
|
|||||||
printf ("% C", lc); /* { dg-warning "flag" "bad % C" } */
|
printf ("% C", lc); /* { dg-warning "flag" "bad % C" } */
|
||||||
printf ("%#C", lc); /* { dg-warning "flag" "bad %#C" } */
|
printf ("%#C", lc); /* { dg-warning "flag" "bad %#C" } */
|
||||||
printf ("%0C", lc); /* { dg-warning "flag" "bad %0C" } */
|
printf ("%0C", lc); /* { dg-warning "flag" "bad %0C" } */
|
||||||
|
printf ("%'C", lc); /* { dg-warning "flag" "bad %'C" } */
|
||||||
printf ("%S", ls);
|
printf ("%S", ls);
|
||||||
printf ("%3S", ls);
|
printf ("%3S", ls);
|
||||||
printf ("%.3S", ls);
|
printf ("%.3S", ls);
|
||||||
@ -54,6 +55,7 @@ foo (int i, unsigned int u, wint_t lc, wchar_t *ls, int *ip, double d,
|
|||||||
printf ("% S", ls); /* { dg-warning "flag" "bad % S" } */
|
printf ("% S", ls); /* { dg-warning "flag" "bad % S" } */
|
||||||
printf ("%#S", ls); /* { dg-warning "flag" "bad %#S" } */
|
printf ("%#S", ls); /* { dg-warning "flag" "bad %#S" } */
|
||||||
printf ("%0S", ls); /* { dg-warning "flag" "bad %0S" } */
|
printf ("%0S", ls); /* { dg-warning "flag" "bad %0S" } */
|
||||||
|
printf ("%'S", ls); /* { dg-warning "flag" "bad %'S" } */
|
||||||
scanf ("%C", ls);
|
scanf ("%C", ls);
|
||||||
scanf ("%S", ls);
|
scanf ("%S", ls);
|
||||||
scanf ("%*C%*S");
|
scanf ("%*C%*S");
|
||||||
|
Loading…
Reference in New Issue
Block a user