(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
format/
ms_c90-printf-1.c
       1  /* Test for printf formats.  Formats using C90 features, including cases
       2     where C90 specifies some aspect of the format to be ignored or where
       3     the behavior is undefined.
       4  */
       5  /* Origin: Joseph Myers <jsm28@cam.ac.uk> */
       6  /* { dg-do compile { target { *-*-mingw* } } } */
       7  /* { dg-options "-std=iso9899:1990 -pedantic -Wformat" } */
       8  
       9  #define USE_SYSTEM_FORMATS
      10  #include "format.h"
      11  
      12  void
      13  foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
      14       int *n, short int *hn, long int l, unsigned long int ul,
      15       long int *ln, long double ld, wint_t lc, wchar_t *ls, llong ll,
      16       ullong ull, unsigned int *un, const int *cn, signed char *ss,
      17       unsigned char *us, const signed char *css, unsigned int u1,
      18       unsigned int u2)
      19  {
      20    /* See ISO/IEC 9899:1990 (E) subclause 7.9.6.1 (pages 131-134).  */
      21    /* Basic sanity checks for the different components of a format.  */
      22    printf ("%d\n", i);
      23    printf ("%+d\n", i);
      24    printf ("%3d\n", i);
      25    printf ("%-3d\n", i);
      26    printf ("%*d\n", i1, i);
      27    printf ("%d %lu\n", i, ul);
      28    /* Bogus use of width.  */
      29    printf ("%5n\n", n); /* { dg-warning "width" "width with %n" } */
      30    /* Valid and invalid %% constructions.  Some of the warning messages
      31       are non-optimal, but they do detect the errorneous nature of the
      32       format string.
      33    */
      34    printf ("%%");
      35    printf ("%-%"); /* { dg-warning "format" "bogus %%" } */
      36    printf ("%-%\n"); /* { dg-warning "format" "bogus %%" } */
      37    printf ("%5%\n"); /* { dg-warning "format" "bogus %%" } */
      38    printf ("%h%\n"); /* { dg-warning "format" "bogus %%" } */
      39    /* Valid and invalid %h, %l, %L constructions.  */
      40    printf ("%hd", i);
      41    printf ("%hi", i);
      42    /* Strictly, these parameters should be int or unsigned int according to
      43       what unsigned short promotes to.  However, GCC ignores sign
      44       differences in format checking here, and this is relied on to get the
      45       correct checking without print_char_table needing to know whether
      46       int and short are the same size.
      47    */
      48    printf ("%ho%hu%hx%hX", u, u, u, u);
      49    printf ("%hn", hn);
      50    printf ("%hf", d); /* { dg-warning "length" "bad use of %h" } */
      51    printf ("%he", d); /* { dg-warning "length" "bad use of %h" } */
      52    printf ("%hE", d); /* { dg-warning "length" "bad use of %h" } */
      53    printf ("%hg", d); /* { dg-warning "length" "bad use of %h" } */
      54    printf ("%hG", d); /* { dg-warning "length" "bad use of %h" } */
      55    printf ("%hc", i);
      56    printf ("%hs", hn);
      57    printf ("%hp", p); /* { dg-warning "length" "bad use of %h" } */
      58    printf ("%h"); /* { dg-warning "conversion lacks type" "bare %h" } */
      59    printf ("%ld%li%lo%lu%lx%lX", l, l, ul, ul, ul, ul);
      60    printf ("%ln", ln);
      61    printf ("%lf", d); /* { dg-warning "length|C" "bad use of %l" } */
      62    printf ("%le", d); /* { dg-warning "length|C" "bad use of %l" } */
      63    printf ("%lE", d); /* { dg-warning "length|C" "bad use of %l" } */
      64    printf ("%lg", d); /* { dg-warning "length|C" "bad use of %l" } */
      65    printf ("%lG", d); /* { dg-warning "length|C" "bad use of %l" } */
      66    printf ("%lp", p); /* { dg-warning "length|C" "bad use of %l" } */
      67    /* These next two were added in C94, but should be objected to in C90.
      68       For the first one, GCC has wanted wchar_t instead of the correct C94
      69       and C99 wint_t.
      70    */
      71    printf ("%lc", lc); /* { dg-warning "length|C" "C90 bad use of %l" } */
      72    printf ("%ls", ls); /* { dg-warning "length|C" "C90 bad use of %l" } */
      73    /* Valid uses of each bare conversion.  */
      74    printf ("%d%i%o%u%x%X%f%e%E%g%G%c%s%p%n%%", i, i, u, u, u, u, d, d, d, d, d,
      75  	  i, s, p, n);
      76    /* Uses of the - flag (valid on all non-%, non-n conversions).  */
      77    printf ("%-d%-i%-o%-u%-x%-X%-f%-e%-E%-g%-G%-c%-s%-p", i, i, u, u, u, u,
      78  	  d, d, d, d, d, i, s, p);
      79    printf ("%-n", n); /* { dg-warning "flag" "bad use of %-n" } */
      80    /* Uses of the + flag (valid on signed conversions only).  */
      81    printf ("%+d%+i%+f%+e%+E%+g%+G\n", i, i, d, d, d, d, d);
      82    printf ("%+o", u); /* { dg-warning "flag" "bad use of + flag" } */
      83    printf ("%+u", u); /* { dg-warning "flag" "bad use of + flag" } */
      84    printf ("%+x", u); /* { dg-warning "flag" "bad use of + flag" } */
      85    printf ("%+X", u); /* { dg-warning "flag" "bad use of + flag" } */
      86    printf ("%+c", i); /* { dg-warning "flag" "bad use of + flag" } */
      87    printf ("%+s", s); /* { dg-warning "flag" "bad use of + flag" } */
      88    printf ("%+p", p); /* { dg-warning "flag" "bad use of + flag" } */
      89    printf ("%+n", n); /* { dg-warning "flag" "bad use of + flag" } */
      90    /* Uses of the space flag (valid on signed conversions only, and ignored
      91       with +).
      92    */
      93    printf ("% +d", i); /* { dg-warning "use of both|ignored" "use of space and + flags" } */
      94    printf ("%+ d", i); /* { dg-warning "use of both|ignored" "use of space and + flags" } */
      95    printf ("% d% i% f% e% E% g% G\n", i, i, d, d, d, d, d);
      96    printf ("% o", u); /* { dg-warning "flag" "bad use of space flag" } */
      97    printf ("% u", u); /* { dg-warning "flag" "bad use of space flag" } */
      98    printf ("% x", u); /* { dg-warning "flag" "bad use of space flag" } */
      99    printf ("% X", u); /* { dg-warning "flag" "bad use of space flag" } */
     100    printf ("% c", i); /* { dg-warning "flag" "bad use of space flag" } */
     101    printf ("% s", s); /* { dg-warning "flag" "bad use of space flag" } */
     102    printf ("% p", p); /* { dg-warning "flag" "bad use of space flag" } */
     103    printf ("% n", n); /* { dg-warning "flag" "bad use of space flag" } */
     104    /* Uses of the # flag.  */
     105    printf ("%#o%#x%#X%#e%#E%#f%#g%#G", u, u, u, d, d, d, d, d);
     106    printf ("%#d", i); /* { dg-warning "flag" "bad use of # flag" } */
     107    printf ("%#i", i); /* { dg-warning "flag" "bad use of # flag" } */
     108    printf ("%#u", u); /* { dg-warning "flag" "bad use of # flag" } */
     109    printf ("%#c", i); /* { dg-warning "flag" "bad use of # flag" } */
     110    printf ("%#s", s); /* { dg-warning "flag" "bad use of # flag" } */
     111    printf ("%#p", p); /* { dg-warning "flag" "bad use of # flag" } */
     112    printf ("%#n", n); /* { dg-warning "flag" "bad use of # flag" } */
     113    /* Uses of the 0 flag.  */
     114    printf ("%08d%08i%08o%08u%08x%08X%08e%08E%08f%08g%08G", i, i, u, u, u, u,
     115  	  d, d, d, d, d);
     116    printf ("%0c", i); /* { dg-warning "flag" "bad use of 0 flag" } */
     117    printf ("%0s", s); /* { dg-warning "flag" "bad use of 0 flag" } */
     118    printf ("%0p", p); /* { dg-warning "flag" "bad use of 0 flag" } */
     119    printf ("%0n", n); /* { dg-warning "flag" "bad use of 0 flag" } */
     120    /* 0 flag ignored with - flag.  */
     121    printf ("%-08d", i); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     122    printf ("%-08i", i); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     123    printf ("%-08o", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     124    printf ("%-08u", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     125    printf ("%-08x", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     126    printf ("%-08X", u); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     127    printf ("%-08e", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     128    printf ("%-08E", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     129    printf ("%-08f", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     130    printf ("%-08g", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     131    printf ("%-08G", d); /* { dg-warning "flags|ignored" "0 flag ignored with - flag" } */
     132    /* Various tests of bad argument types.  */
     133    printf ("%d", l); /* { dg-warning "format" "bad argument types" } */
     134    printf ("%ld", i); /* { dg-warning "format" "bad argument types" } */
     135    printf ("%s", n); /* { dg-warning "format" "bad argument types" } */
     136    printf ("%p", i); /* { dg-warning "format" "bad argument types" } */
     137    printf ("%n", p); /* { dg-warning "format" "bad argument types" } */
     138    /* With -pedantic, we want some further checks for pointer targets:
     139       %p should allow only pointers to void (possibly qualified) and
     140       to character types (possibly qualified), but not function pointers
     141       or pointers to other types.  (Whether, in fact, character types are
     142       allowed here is unclear; see thread on comp.std.c, July 2000 for
     143       discussion of the requirements of rules on identical representation,
     144       and of the application of the as if rule with the new va_arg
     145       allowances in C99 to printf.)  Likewise, we should warn if
     146       pointer targets differ in signedness, except in some circumstances
     147       for character pointers.  (In C99 we should consider warning for
     148       char * or unsigned char * being passed to %hhn, even if strictly
     149       legitimate by the standard.)
     150    */
     151    printf ("%p", foo); /* { dg-warning "format" "bad argument types" } */
     152    printf ("%n", un); /* { dg-warning "format" "bad argument types" } */
     153    printf ("%p", n); /* { dg-warning "format" "bad argument types" } */
     154    /* Allow character pointers with %p.  */
     155    printf ("%p%p%p%p", s, ss, us, css);
     156    /* %s allows any character type.  */
     157    printf ("%s%s%s%s", s, ss, us, css);
     158    /* Warning for void * arguments for %s is GCC's historical behavior,
     159       and seems useful to keep, even if some standard versions might be
     160       read to permit it.
     161    */
     162    printf ("%s", p); /* { dg-warning "format" "bad argument types" } */
     163    /* The historical behavior is to allow signed / unsigned types
     164       interchangeably as arguments.  For values representable in both types,
     165       such usage may be correct.  For now preserve the behavior of GCC
     166       in such cases.
     167    */
     168    printf ("%d", u);
     169    /* Wrong number of arguments.  */
     170    printf ("%d%d", i); /* { dg-warning "matching" "wrong number of args" } */
     171    printf ("%d", i, i); /* { dg-warning "arguments" "wrong number of args" } */
     172    /* Miscellaneous bogus constructions.  */
     173    printf (""); /* { dg-warning "zero-length" "warning for empty format" } */
     174    printf ("\0"); /* { dg-warning "embedded" "warning for embedded NUL" } */
     175    printf ("%d\0", i); /* { dg-warning "embedded" "warning for embedded NUL" } */
     176    printf ("%d\0%d", i, i); /* { dg-warning "embedded|too many" "warning for embedded NUL" } */
     177    printf (NULL); /* { dg-warning "null" "null format string warning" } */
     178    printf ("%"); /* { dg-warning "trailing" "trailing % warning" } */
     179    printf ("%++d", i); /* { dg-warning "repeated" "repeated flag warning" } */
     180    printf ("%n", cn); /* { dg-warning "constant" "%n with const" } */
     181    printf ((const char *)L"foo"); /* { dg-warning "wide" "wide string" } */
     182    printf ("%n", (int *)0); /* { dg-warning "null" "%n with NULL" } */
     183    printf ("%s", (char *)0); /* { dg-warning "null" "%s with NULL" } */
     184  }