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:
Joseph Myers 2000-08-23 18:32:50 +01:00 committed by Joseph Myers
parent 94350948fb
commit d8eceea40c
6 changed files with 142 additions and 3 deletions

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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" } */
} }

View 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" } */
}

View File

@ -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");