1/* 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 10void 11foo (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} 126