1 /* PR middle-end/78519 - missing warning for sprintf %s with null pointer
2    Also exercises null destination pointer and null format string.
3    { dg-do compile }
4    { dg-options "-O2 -Wformat -Wformat-overflow -Wno-nonnull -ftrack-macro-expansion=0" } */
5 
6 typedef __builtin_va_list va_list;
7 
8 #define sprintf   __builtin_sprintf
9 #define snprintf  __builtin_snprintf
10 #define vsprintf  __builtin_vsprintf
11 #define vsnprintf __builtin_vsnprintf
12 
13 
null(void)14 static char* null (void)
15 {
16   return 0;
17 }
18 
19 
20 void sink (int);
21 #define T sink
22 
23 
24 /* Verify that calls with a null destination pointer are diagnosed.  */
25 
test_null_dest(va_list va)26 void test_null_dest (va_list va)
27 {
28   char *p = null ();
29   T (sprintf (null (), "%i", 0));   /* { dg-warning "null destination pointer" } */
30   T (sprintf (p, "%i", 0));         /* { dg-warning "null destination pointer" } */
31   T (sprintf (p, "%i abc", 0));     /* { dg-warning "null destination pointer" } */
32 
33   T (snprintf (null (), 1, "%i", 0));   /* { dg-warning "null destination pointer" } */
34   T (snprintf (p, 2, "%i", 0));         /* { dg-warning "null destination pointer" } */
35   T (snprintf (p, 3, "%i abc", 0));     /* { dg-warning "null destination pointer" } */
36 
37   /* Snprintf with a null pointer and a zero size is a special request
38      to determine the size of output without writing any.  Such calls
39      are valid must not be diagnosed.  */
40   T (snprintf (p, 0, "%i", 0));
41 
42   T (vsprintf (null (), "%i", va)); /* { dg-warning "null destination pointer" } */
43   T (vsprintf (p,       "%i", va)); /* { dg-warning "null destination pointer" } */
44 
45   T (vsnprintf (null (), 1, "%i", va)); /* { dg-warning "null destination pointer" } */
46   T (vsnprintf (p,       2, "%i", va));       /* { dg-warning "null destination pointer" } */
47   T (vsnprintf (p,       0, "%i", va));
48 }
49 
test_null_format(char * d,va_list va)50 void test_null_format (char *d, va_list va)
51 {
52   char *fmt = null ();
53 
54   T (sprintf (d, null ()));    /* { dg-warning "null format string" } */
55   T (sprintf (d, fmt));        /* { dg-warning "null format string" } */
56 
57   T (snprintf (d, 0, null ()));    /* { dg-warning "null format string" } */
58   T (snprintf (d, 1, fmt));        /* { dg-warning "null format string" } */
59 
60   T (vsprintf (d, null (), va));   /* { dg-warning "null format string" } */
61   T (vsprintf (d, fmt, va));       /* { dg-warning "null format string" } */
62 
63   T (vsnprintf (d, 0, null (), va));  /* { dg-warning "null format string" } */
64   T (vsnprintf (d, 1, fmt, va));      /* { dg-warning "null format string" } */
65 }
66 
test_null_arg(char * d,const char * s)67 void test_null_arg (char *d, const char *s)
68 {
69   char *p = null ();
70 
71   T (sprintf (d, "%-s", null ()));  /* { dg-warning "directive argument is null" } */
72   T (sprintf (d, "%-s", p));        /* { dg-warning "directive argument is null" } */
73   T (sprintf (d, "%s %s", p, s));   /* { dg-warning "directive argument is null" } */
74   T (sprintf (d, "%s %s", s, p));   /* { dg-warning "directive argument is null" } */
75   T (sprintf (d, "%s %i", p, 1));   /* { dg-warning "directive argument is null" } */
76   T (sprintf (d, "%i %s", 1, p));   /* { dg-warning "directive argument is null" } */
77   T (sprintf (d, "%.0s", p));       /* { dg-warning "directive argument is null" } */
78   T (sprintf (d, "%1.0s", p));      /* { dg-warning "directive argument is null" } */
79 
80   T (snprintf (d, 0, "%-s", null ()));  /* { dg-warning "directive argument is null" } */
81   T (snprintf (d, 1, "%-s", p));        /* { dg-warning "directive argument is null" } */
82 
83   T (sprintf (d, "%i %s", 1, null ()));  /* { dg-warning "directive argument is null" } */
84   T (sprintf (d, "%i %s", 2, p));        /* { dg-warning "directive argument is null" } */
85 
86   T (snprintf (d, 0, "%i %s", 1, null ()));  /* { dg-warning "directive argument is null" } */
87   T (snprintf (d, 9, "%i %s", 2, p));        /* { dg-warning "directive argument is null" } */
88 
89   /* A sanity check that the %p directive doesn't emit a warning
90      with a null pointer.  */
91   T (sprintf (d, "%p", null ()));
92   T (sprintf (d, "%p", p));
93 }
94