1 /* PR tree-optimization/87756 - missing unterminated argument warning
2    using address of a constant character
3    { dg-do compile }
4    { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
5 
6 int sprintf (char*, const char*, ...);
7 
8 extern char* dest (void);
9 extern void sink (int, ...);
10 
11 #define D dest ()
12 #define T(expr)   sink (0, (expr))
13 
14 
15 const char cnul = '\0';
16 const char cnonul = 'a';
17 const char str3[] = "123";
18 
19 const struct
20 {
21   char a, b, s[3];
22 } s1 = { '\0', 'b', "123" },
23   s2[2] = {
24   { '\0', 'c', "12" },
25   { 'd', '\0', "123" }
26   };
27 
test_sprintf_s(void)28 void test_sprintf_s (void)
29 {
30   T (sprintf (D, "%s", &cnul));
31   T (sprintf (D, "%s", &cnonul));       /* { dg-warning "nul-terminated" } */
32   T (sprintf (D, "%.1s", &cnonul));
33   T (sprintf (D, "%.2s", &cnonul));     /* { dg-warning "nul-terminated" } */
34 
35   T (sprintf (D, "%s", &s1.a));
36   T (sprintf (D, "%s", &s1.b));         /* { dg-warning "nul-terminated" } */
37   T (sprintf (D, "%.1s", &s1.b));
38   T (sprintf (D, "%.2s", &s1.b));       /* { dg-warning "nul-terminated" } */
39   T (sprintf (D, "%s", s1.s));          /* { dg-warning "nul-terminated" } */
40   T (sprintf (D, "%.3s", s1.s));
41   T (sprintf (D, "%.4s", s1.s));        /* { dg-warning "nul-terminated" } */
42 
43   T (sprintf (D, "%.2s", s1.s + 1));
44   T (sprintf (D, "%.3s", s1.s + 1));    /* { dg-warning "nul-terminated" } */
45 
46   T (sprintf (D, "%s", &s2[0].a));
47   T (sprintf (D, "%s", &s2[0].b));      /* { dg-warning "nul-terminated" } */
48   T (sprintf (D, "%.1s", &s2[0].b));
49   T (sprintf (D, "%.2s", &s2[0].b));    /* { dg-warning "nul-terminated" } */
50   T (sprintf (D, "%s", s2[0].s));
51   T (sprintf (D, "%.3s", s2[0].s));
52   T (sprintf (D, "%.4s", s2[0].s));
53 
54   T (sprintf (D, "%.2s", s2[0].s + 1));
55   T (sprintf (D, "%.3s", s2[0].s + 1));
56 
57   T (sprintf (D, "%s", &s2[1].a));      /* { dg-warning "nul-terminated" } */
58   T (sprintf (D, "%.1s", &s2[1].a));
59   T (sprintf (D, "%.2s", &s2[1].a));    /* { dg-warning "nul-terminated" } */
60   T (sprintf (D, "%s", &s2[1].b));
61   T (sprintf (D, "%s", s2[1].s));       /* { dg-warning "nul-terminated" } */
62   T (sprintf (D, "%.3s", s2[1].s));
63   T (sprintf (D, "%.4s", s2[1].s));     /* { dg-warning "nul-terminated" } */
64 
65   T (sprintf (D, "%.2s", s2[1].s + 1));
66   T (sprintf (D, "%.3s", s2[1].s + 1)); /* { dg-warning "nul-terminated" } */
67 
68   T (sprintf (D, "%s", &str3[3]));
69   T (sprintf (D, "%s", &str3[4]));      /* { dg-warning "\\\[-Warray-bounds" } */
70 }
71