comparison gcc/testsuite/c-c++-common/Wstringop-overflow.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents
children
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* PR middle-end/81117 - Improve buffer overflow checking in strncpy
2 { dg-do compile }
3 { dg-options "-O2 -Wstringop-overflow -Wno-stringop-truncation -ftrack-macro-expansion=0" } */
4
5 typedef __SIZE_TYPE__ size_t;
6
7 #if __cplusplus
8 extern "C" {
9 #endif
10
11 size_t strlen (const char*);
12 char* strncat (char*, const char*, size_t);
13 char* strncpy (char*, const char*, size_t);
14 #if __cplusplus
15 }
16 #endif
17
18 const char ar[] = "123";
19
20 void test_strncat (char **d, const char* s, int i)
21 {
22 /* Use a fresh pointer for each test to prevent the optimizer from
23 eliminating redundant writes into the same destination. Avoid
24 calling functions like sink() on the result that would have to
25 be assumed to change the source string by the alias oracle. */
26 #define T(d, s, len) strncat (*d++, (s), (len))
27
28 T (d, "", 0);
29 T (d, "", 1);
30 T (d, "", 2);
31 T (d, "", 3);
32 T (d, "123", 0);
33 /* The following two calls truncate the copy and are diagnosed
34 by -Wstringop-truncation but there is evidence of overflow so
35 they're not diagnosed by -Wstringop-overflow. */
36 T (d, "123", 1);
37 T (d, "123", 2);
38
39 T (d, "123", 3); /* { dg-warning ".strncat\[^\n\r\]* specified bound 3 equals source length" } */
40 T (d, "123", 4);
41 T (d, "123", 9);
42
43 T (d, s, strlen (s)); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
44 T (d, s, strlen (s) + 1); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
45 /* The following could also be diagnosed by -Wstringop-truncation
46 (with some effort to distinguish the pattern from others like
47 the one above. */
48 T (d, s, strlen (s) - 1); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
49 T (d, s, strlen (s) - i); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
50
51 /* The following is dubious but not necessarily a smoking gun. */
52 T (d, s, strlen (s) - strlen (s));
53
54 {
55 signed char n = strlen (s); /* { dg-message "length computed here" } */
56 T (d, s, n); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
57 }
58
59 {
60 short n = strlen (s); /* { dg-message "length computed here" } */
61 T (d, s, n); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
62 }
63
64 {
65 int n = strlen (s); /* { dg-message "length computed here" } */
66 T (d, s, n); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
67 }
68
69 {
70 unsigned n = strlen (s); /* { dg-message "length computed here" } */
71 T (d, s, n); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
72 }
73
74 {
75 size_t n;
76 n = strlen (s); /* { dg-message "length computed here" } */
77 T (d, s, n); /* { dg-warning ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
78 }
79
80 {
81 size_t n;
82 n = strlen (s) - 1; /* { dg-message "length computed here" } */
83 T (d, s, n); /* { dg-message ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
84 }
85
86 {
87 /* This doesn't overflow so iit should not be diagnosed. */
88 size_t n = strlen (s) - strlen (s);
89 T (d, s, n);
90 }
91
92 {
93 size_t n = i < strlen (s) ? i : strlen (s); /* { dg-message "length computed here" } */
94 T (d, s, n); /* { dg-message ".strncat\[^\n\r\]* specified bound depends on the length of the source argument" } */
95 }
96 }
97
98
99 void test_strncpy (char **d, const char* s, int i)
100 {
101 #undef T
102 #define T(d, s, len) strncpy (*d++, (s), (len))
103
104 T (d, "", 0);
105 T (d, "", 1);
106 T (d, "", 2);
107 T (d, "", 3);
108 T (d, "123", 0);
109 T (d, "123", 1);
110 T (d, "123", 2);
111 T (d, "123", 3);
112 T (d, "123", 4);
113 T (d, "123", 9);
114
115 T (d, "123", sizeof "123");
116 T (d, ar, sizeof ar);
117
118 T (d, s, strlen (s)); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
119
120 {
121 int n = strlen (s); /* { dg-message "length computed here" } */
122 T (d, s, n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
123 }
124
125 {
126 unsigned n = strlen (s); /* { dg-message "length computed here" } */
127 T (d, s, n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
128 }
129
130 {
131 size_t n;
132 n = strlen (s); /* { dg-message "length computed here" } */
133 T (d, s, n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
134 }
135
136 {
137 size_t n;
138 n = strlen (s) - 1; /* { dg-message "length computed here" } */
139 T (d, s, n); /* { dg-warning "\\\[-Wstringop-overflow=]" } */
140 }
141
142 {
143 /* This is diagnosed by -Wstringop-truncation. Verify that it isn't
144 also diagnosed by -Wstringop-overflow. */
145 size_t n = strlen (s) - strlen (s);
146 T (d, s, n);
147 }
148
149 {
150 /* This use of strncpy is certainly dubious and it could well be
151 diagnosed by -Wstringop-truncation but it isn't. That it is
152 diagnosed with -Wstringop-overflow is more by accident than
153 by design. -Wstringop-overflow considers any dependency of
154 the bound on strlen(s) a potential bug. */
155 size_t n = i < strlen (s) ? i : strlen (s); /* { dg-message "length computed here" } */
156 T (d, s, n); /* { dg-message ".strncpy\[^\n\r]* specified bound depends on the length of the source argument" } */
157 }
158 }