1 /* Test whether buffer overflow warnings for __*_chk builtins
2    are emitted properly.  */
3 /* { dg-do compile } */
4 /* { dg-options "-O2 -std=gnu99 -ftrack-macro-expansion=0" } */
5 /* { dg-additional-options "-mstructure-size-boundary=8" { target arm*-*-* } } */
6 // { dg-skip-if "packed attribute missing for t" { "epiphany-*-*" } { "*" } { "" } }
7 
8 extern void abort (void);
9 
10 #include "../gcc.c-torture/execute/builtins/chk.h"
11 #include <stdarg.h>
12 
13 volatile void *vx;
14 char buf1[20];
15 int x;
16 
17 void
test(int arg,...)18 test (int arg, ...)
19 {
20   char buf2[20];
21   va_list ap;
22   char *p = &buf1[10], *q;
23 
24   memcpy (&buf2[19], "ab", 1);
25   memcpy (&buf2[19], "ab", 2); /* { dg-warning "will always overflow" "memcpy" } */
26   vx = mempcpy (&buf2[19], "ab", 1);
27   vx = mempcpy (&buf2[19], "ab", 2); /* { dg-warning "will always overflow" "mempcpy" } */
28   memmove (&buf2[18], &buf1[10], 2);
29   memmove (&buf2[18], &buf1[10], 3); /* { dg-warning "will always overflow" "memmove" } */
30   memset (&buf2[16], 'a', 4);
31   memset (&buf2[15], 'b', 6); /* { dg-warning "will always overflow" "memset" } */
32   strcpy (&buf2[18], "a");
33   strcpy (&buf2[18], "ab"); /* { dg-warning "will always overflow" "strcpy" } */
34   vx = stpcpy (&buf2[18], "a");
35   vx = stpcpy (&buf2[18], "ab"); /* { dg-warning "will always overflow" "stpcpy" } */
36   strncpy (&buf2[18], "a", 2);
37   strncpy (&buf2[18], "a", 3); /* { dg-warning "will always overflow" "strncpy" } */
38   strncpy (&buf2[18], "abc", 2);
39   strncpy (&buf2[18], "abc", 3); /* { dg-warning "will always overflow" "strncpy" } */
40   memset (buf2, '\0', sizeof (buf2));
41   strcat (&buf2[18], "a");
42   memset (buf2, '\0', sizeof (buf2));
43   strcat (&buf2[18], "ab"); /* { dg-warning "will always overflow" "strcat" } */
44   sprintf (&buf2[18], "%s", buf1);
45   sprintf (&buf2[18], "%s", "a");
46   sprintf (&buf2[18], "%s", "ab"); /* { dg-warning "will always overflow" "sprintf" } */
47   sprintf (&buf2[18], "a");
48   sprintf (&buf2[18], "ab"); /* { dg-warning "will always overflow" "sprintf" } */
49   snprintf (&buf2[18], 2, "%d", x);
50   /* N argument to snprintf is the size of the buffer.
51      Although this particular call wouldn't overflow buf2,
52      incorrect buffer size was passed to it and therefore
53      we want a warning and runtime failure.  */
54   snprintf (&buf2[18], 3, "%d", x); /* { dg-warning "will always overflow" "snprintf" } */
55   va_start (ap, arg);
56   vsprintf (&buf2[18], "a", ap);
57   va_end (ap);
58   va_start (ap, arg);
59   vsprintf (&buf2[18], "ab", ap); /* { dg-warning "will always overflow" "vsprintf" } */
60   va_end (ap);
61   va_start (ap, arg);
62   vsnprintf (&buf2[18], 2, "%s", ap);
63   va_end (ap);
64   va_start (ap, arg);
65   /* See snprintf above.  */
66   vsnprintf (&buf2[18], 3, "%s", ap); /* { dg-warning "will always overflow" "vsnprintf" } */
67   va_end (ap);
68 
69   p = p + 10;
70   memset (p, 'd', 0);
71   q = strcpy (p, ""); /* { dg-warning "will always overflow" "strcpy" } */
72 
73   /* This invokes undefined behavior, since we are past the end of buf1.  */
74   p = p + 10;
75   memset (p, 'd', 1); /* { dg-warning "will always overflow" "memset" } */
76 
77   memset (q, 'd', 0);
78   memset (q, 'd', 1); /* { dg-warning "will always overflow" "memset" } */
79   q = q - 10;
80   memset (q, 'd', 10);
81 }
82 
83 char *str = "ABCDEFG";
84 typedef struct { char b[16]; } H;
85 
86 /* Some brown paper bag bugs found in real applications.
87    This test is here merely for amusement.  */
88 
89 void
test2(const H h)90 test2 (const H h)
91 {
92   char c;
93   strncpy (&c, str, 3); /* { dg-warning "will always overflow" "strncpy" } */
94 
95   struct { char b[4]; } x;
96   sprintf (x.b, "%s", "ABCD"); /* { dg-warning "will always overflow" "sprintf" } */
97 
98   unsigned int i;
99   memcpy (&i, &h, sizeof (h)); /* { dg-warning "will always overflow" "memcpy" } */
100 
101   unsigned char buf[21];
102   memset (buf + 16, 0, 8); /* { dg-warning "will always overflow" "memset" } */
103 
104   typedef struct { int i, j, k, l; } S;
105   S *s[3];
106   memset (s, 0, sizeof (S) * 3); /* { dg-warning "will always overflow" "memset" } */
107 
108   struct T { char a[8]; char b[4]; char c[10]; } t;
109   stpcpy (t.c,"Testing..."); /* { dg-warning "will always overflow" "stpcpy" } */
110 
111   char b1[7];
112   char b2[4];
113   memset (b1, 0, sizeof (b1));
114   memset (b2, 0, sizeof (b1)); /* { dg-warning "will always overflow" "memset" } */
115 }
116