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)
|
||||
|
||||
* arm.c (arm_expand_prologue): Ensure that the stack-adjustment
|
||||
|
@ -1236,9 +1236,9 @@ typedef struct {
|
||||
} format_char_info;
|
||||
|
||||
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#" },
|
||||
{ "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. */
|
||||
{ "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 +#'" },
|
||||
@ -1916,7 +1916,7 @@ check_format_info (info, params)
|
||||
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)
|
||||
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");
|
||||
if (index (flag_chars, '\'') && pedantic)
|
||||
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 == '*')
|
||||
{
|
||||
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>
|
||||
|
||||
* 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 ("%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 ("%0C", lc); /* { dg-warning "flag" "bad %0C" } */
|
||||
printf ("%'C", lc); /* { dg-warning "flag" "bad %'C" } */
|
||||
printf ("%S", 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 ("%0S", ls); /* { dg-warning "flag" "bad %0S" } */
|
||||
printf ("%'S", ls); /* { dg-warning "flag" "bad %'S" } */
|
||||
scanf ("%C", ls);
|
||||
scanf ("%S", ls);
|
||||
scanf ("%*C%*S");
|
||||
|
Loading…
Reference in New Issue
Block a user