| 1 | 689 | jeremybenn | /* Test for X/Open format extensions, as found in the
 | 
      
         | 2 |  |  |    Single Unix Specification and in Austin Group draft 7.
 | 
      
         | 3 |  |  | */
 | 
      
         | 4 |  |  | /* Origin: Joseph Myers <jsm28@cam.ac.uk> */
 | 
      
         | 5 |  |  | /* { dg-do compile } */
 | 
      
         | 6 |  |  | /* { dg-options "-std=gnu99 -Wformat" } */
 | 
      
         | 7 |  |  |  
 | 
      
         | 8 |  |  | #include "format.h"
 | 
      
         | 9 |  |  |  
 | 
      
         | 10 |  |  | void
 | 
      
         | 11 |  |  | foo (int i, unsigned int u, wint_t lc, wchar_t *ls, int *ip, double d,
 | 
      
         | 12 |  |  |      char *s, void *p, int *n, long int l, int i2, float *fp, long int *lp,
 | 
      
         | 13 |  |  |      va_list va)
 | 
      
         | 14 |  |  | {
 | 
      
         | 15 |  |  |   /* The conversion specifiers C and S, for both printf and scanf,
 | 
      
         | 16 |  |  |      are X/Open extensions.
 | 
      
         | 17 |  |  |   */
 | 
      
         | 18 |  |  |   printf ("%C", lc);
 | 
      
         | 19 |  |  |   printf ("%3C", lc);
 | 
      
         | 20 |  |  |   printf ("%.3C", lc); /* { dg-warning "precision" "precision with %C" } */
 | 
      
         | 21 |  |  |   printf ("%hC", lc); /* { dg-warning "length" "bad %hC" } */
 | 
      
         | 22 |  |  |   printf ("%hhC", lc); /* { dg-warning "length" "bad %hhC" } */
 | 
      
         | 23 |  |  |   printf ("%lC", lc); /* { dg-warning "length" "bad %lC" } */
 | 
      
         | 24 |  |  |   printf ("%llC", lc); /* { dg-warning "length" "bad %llC" } */
 | 
      
         | 25 |  |  |   printf ("%jC", lc); /* { dg-warning "length" "bad %jC" } */
 | 
      
         | 26 |  |  |   printf ("%zC", lc); /* { dg-warning "length" "bad %zC" } */
 | 
      
         | 27 |  |  |   printf ("%tC", lc); /* { dg-warning "length" "bad %tC" } */
 | 
      
         | 28 |  |  |   printf ("%LC", lc); /* { dg-warning "length" "bad %LC" } */
 | 
      
         | 29 |  |  |   printf ("%-C", lc);
 | 
      
         | 30 |  |  |   printf ("%+C", lc); /* { dg-warning "flag" "bad %+C" } */
 | 
      
         | 31 |  |  |   printf ("% C", lc); /* { dg-warning "flag" "bad % C" } */
 | 
      
         | 32 |  |  |   printf ("%#C", lc); /* { dg-warning "flag" "bad %#C" } */
 | 
      
         | 33 |  |  |   printf ("%0C", lc); /* { dg-warning "flag" "bad %0C" } */
 | 
      
         | 34 |  |  |   printf ("%'C", lc); /* { dg-warning "flag" "bad %'C" } */
 | 
      
         | 35 |  |  |   printf ("%S", ls);
 | 
      
         | 36 |  |  |   printf ("%3S", ls);
 | 
      
         | 37 |  |  |   printf ("%.3S", ls);
 | 
      
         | 38 |  |  |   printf ("%hS", ls); /* { dg-warning "length" "bad %hS" } */
 | 
      
         | 39 |  |  |   printf ("%hhS", ls); /* { dg-warning "length" "bad %hhS" } */
 | 
      
         | 40 |  |  |   printf ("%lS", ls); /* { dg-warning "length" "bad %lS" } */
 | 
      
         | 41 |  |  |   printf ("%llS", ls); /* { dg-warning "length" "bad %llS" } */
 | 
      
         | 42 |  |  |   printf ("%jS", ls); /* { dg-warning "length" "bad %jS" } */
 | 
      
         | 43 |  |  |   printf ("%zS", ls); /* { dg-warning "length" "bad %zS" } */
 | 
      
         | 44 |  |  |   printf ("%tS", ls); /* { dg-warning "length" "bad %tS" } */
 | 
      
         | 45 |  |  |   printf ("%LS", ls); /* { dg-warning "length" "bad %LS" } */
 | 
      
         | 46 |  |  |   printf ("%-S", ls);
 | 
      
         | 47 |  |  |   printf ("%+S", ls); /* { dg-warning "flag" "bad %+S" } */
 | 
      
         | 48 |  |  |   printf ("% S", ls); /* { dg-warning "flag" "bad % S" } */
 | 
      
         | 49 |  |  |   printf ("%#S", ls); /* { dg-warning "flag" "bad %#S" } */
 | 
      
         | 50 |  |  |   printf ("%0S", ls); /* { dg-warning "flag" "bad %0S" } */
 | 
      
         | 51 |  |  |   printf ("%'S", ls); /* { dg-warning "flag" "bad %'S" } */
 | 
      
         | 52 |  |  |   scanf ("%C", ls);
 | 
      
         | 53 |  |  |   scanf ("%S", ls);
 | 
      
         | 54 |  |  |   scanf ("%*C%*S");
 | 
      
         | 55 |  |  |   scanf ("%2C%3S", ls, ls);
 | 
      
         | 56 |  |  |   scanf ("%hC", ls); /* { dg-warning "length" "bad %hC" } */
 | 
      
         | 57 |  |  |   scanf ("%hhC", ls); /* { dg-warning "length" "bad %hhC" } */
 | 
      
         | 58 |  |  |   scanf ("%lC", ls); /* { dg-warning "length" "bad %lC" } */
 | 
      
         | 59 |  |  |   scanf ("%llC", ls); /* { dg-warning "length" "bad %llC" } */
 | 
      
         | 60 |  |  |   scanf ("%jC", ls); /* { dg-warning "length" "bad %jC" } */
 | 
      
         | 61 |  |  |   scanf ("%zC", ls); /* { dg-warning "length" "bad %zC" } */
 | 
      
         | 62 |  |  |   scanf ("%tC", ls); /* { dg-warning "length" "bad %tC" } */
 | 
      
         | 63 |  |  |   scanf ("%LC", ls); /* { dg-warning "length" "bad %LC" } */
 | 
      
         | 64 |  |  |   scanf ("%hS", ls); /* { dg-warning "length" "bad %hS" } */
 | 
      
         | 65 |  |  |   scanf ("%hhS", ls); /* { dg-warning "length" "bad %hhS" } */
 | 
      
         | 66 |  |  |   scanf ("%lS", ls); /* { dg-warning "length" "bad %lS" } */
 | 
      
         | 67 |  |  |   scanf ("%llS", ls); /* { dg-warning "length" "bad %llS" } */
 | 
      
         | 68 |  |  |   scanf ("%jS", ls); /* { dg-warning "length" "bad %jS" } */
 | 
      
         | 69 |  |  |   scanf ("%zS", ls); /* { dg-warning "length" "bad %zS" } */
 | 
      
         | 70 |  |  |   scanf ("%tS", ls); /* { dg-warning "length" "bad %tS" } */
 | 
      
         | 71 |  |  |   scanf ("%LS", ls); /* { dg-warning "length" "bad %LS" } */
 | 
      
         | 72 |  |  |   /* In C99 mode (even with extensions), %aS is a floating point
 | 
      
         | 73 |  |  |      format followed by an S.
 | 
      
         | 74 |  |  |   */
 | 
      
         | 75 |  |  |   scanf ("%aS", fp);
 | 
      
         | 76 |  |  |   /* The printf flag character ' is an X/Open extension.  */
 | 
      
         | 77 |  |  |   printf ("%'d%'i%'u%'f%'F%'g%'G", i, i, u, d, d, d, d);
 | 
      
         | 78 |  |  |   printf ("%'o", u); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 79 |  |  |   printf ("%'x", u); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 80 |  |  |   printf ("%'X", u); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 81 |  |  |   printf ("%'e", d); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 82 |  |  |   printf ("%'E", d); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 83 |  |  |   printf ("%'a", d); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 84 |  |  |   printf ("%'A", d); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 85 |  |  |   printf ("%'c", i); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 86 |  |  |   printf ("%'s", s); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 87 |  |  |   printf ("%'p", p); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 88 |  |  |   printf ("%'n", n); /* { dg-warning "flag" "bad use of ' flag" } */
 | 
      
         | 89 |  |  |   /* The use of operand number $ formats is an X/Open extension.  */
 | 
      
         | 90 |  |  |   scanf ("%1$d", ip);
 | 
      
         | 91 |  |  |   printf ("%1$d", i);
 | 
      
         | 92 |  |  |   printf ("%1$d", l); /* { dg-warning "arg 2|argument 2" "mismatched args with $ format" } */
 | 
      
         | 93 |  |  |   printf ("%3$*2$.*1$ld", i2, i, l);
 | 
      
         | 94 |  |  |   printf ("%4$ld%7$ld%5$d%6$d%3$d%1$d%2$d", i, i, i, l, i, i, l);
 | 
      
         | 95 |  |  |   scanf ("%4$ld%7$ld%5$d%6$d%3$d%1$d%2$d", ip, ip, ip, lp, ip, ip, lp);
 | 
      
         | 96 |  |  |   printf ("%1$d%d", i, i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
 | 
      
         | 97 |  |  |   printf ("%%%1$d%%%2$d", i, i);
 | 
      
         | 98 |  |  |   printf ("%d%2$d", i); /* { dg-warning "used after format" "mixing $ and non-$ formats" } */
 | 
      
         | 99 |  |  |   printf ("%1$*d", i, i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
 | 
      
         | 100 |  |  |   printf ("%*1$d", i); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
 | 
      
         | 101 |  |  |   scanf ("%1$d%d", ip, ip); /* { dg-warning "missing" "mixing $ and non-$ formats" } */
 | 
      
         | 102 |  |  |   scanf ("%*f%%%1$d%%%2$d", ip, ip);
 | 
      
         | 103 |  |  |   printf ("%2$d", i); /* { dg-warning "operand" "$ number too large" } */
 | 
      
         | 104 |  |  |   printf ("%0$d", i); /* { dg-warning "operand" "$ number too small" } */
 | 
      
         | 105 |  |  |   printf ("%3$d%1$d", i, i, i); /* { dg-warning "before used" "unused $ operand" } */
 | 
      
         | 106 |  |  |   printf ("%2$d%1$d", i, i, i); /* { dg-warning "unused" "unused $ operand" } */
 | 
      
         | 107 |  |  |   vprintf ("%3$d%1$d", va); /* { dg-warning "before used" "unused $ operand" } */
 | 
      
         | 108 |  |  |   /* With scanf formats, gaps in the used arguments are allowed only if the
 | 
      
         | 109 |  |  |      arguments are all pointers.  In such a case, should only give the lesser
 | 
      
         | 110 |  |  |      warning about unused arguments rather than the more serious one about
 | 
      
         | 111 |  |  |      argument gaps.  */
 | 
      
         | 112 |  |  |   scanf ("%3$d%1$d", ip, ip, ip); /* { dg-bogus "before used" "unused $ scanf pointer operand" } */
 | 
      
         | 113 |  |  |   /* { dg-warning "unused" "unused $ scanf pointer operand" { target *-*-* } 112 } */
 | 
      
         | 114 |  |  |   /* If there are non-pointer arguments unused at the end, this is also OK.  */
 | 
      
         | 115 |  |  |   scanf ("%3$d%1$d", ip, ip, ip, i); /* { dg-bogus "before used" "unused $ scanf pointer operand" } */
 | 
      
         | 116 |  |  |   /* { dg-warning "unused" "unused $ scanf pointer operand" { target *-*-* } 115 } */
 | 
      
         | 117 |  |  |   scanf ("%3$d%1$d", ip, i, ip); /* { dg-warning "before used" "unused $ scanf non-pointer operand" } */
 | 
      
         | 118 |  |  |   /* Can't check the arguments in the vscanf case, so should suppose the
 | 
      
         | 119 |  |  |      lesser problem.  */
 | 
      
         | 120 |  |  |   vscanf ("%3$d%1$d", va); /* { dg-bogus "before used" "unused $ scanf pointer operand" } */
 | 
      
         | 121 |  |  |   /* { dg-warning "unused" "unused $ scanf pointer operand" { target *-*-* } 120 } */
 | 
      
         | 122 |  |  |   scanf ("%2$*d%1$d", ip, ip); /* { dg-warning "operand" "operand number with suppression" } */
 | 
      
         | 123 |  |  |   printf ("%1$d%1$d", i);
 | 
      
         | 124 |  |  |   scanf ("%1$d%1$d", ip); /* { dg-warning "more than once" "multiple use of scanf argument" } */
 | 
      
         | 125 |  |  | }
 |