Mercurial > hg > CbC > CbC_gcc
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 } |