/gcc/testsuite/gcc.dg/Wstringop-overread-6.c

https://gitlab.com/adotout/gcc · C · 574 lines · 420 code · 132 blank · 22 comment · 0 complexity · 2a60502d5e73aa4d4f7ef9b994688f46 MD5 · raw file

  1. /* Verify -Wstringop-overread is issued appropriately for calls to string
  2. functions at -O0 and without -Wall.
  3. { dg-do compile }
  4. { dg-options "-O0 -ftrack-macro-expansion=0" } */
  5. typedef __SIZE_TYPE__ size_t;
  6. #define S2 "12"
  7. #define S9 "123456789"
  8. // <libint.h> functions.
  9. char* gettext (const char *);
  10. // <stdio.h> functions.
  11. typedef struct FILE FILE;
  12. int fputs (const char*, FILE*);
  13. int fputs_unlocked (const char*, FILE*);
  14. int puts (const char*);
  15. int puts_unlocked (const char*);
  16. // <string.h> functions.
  17. void* memchr (const void*, int, size_t);
  18. int memcmp (const void*, const void*, size_t);
  19. void* memcpy (void*, const void*, size_t);
  20. void* mempcpy (void*, const void*, size_t);
  21. void* memmove (void*, const void*, size_t);
  22. char* strchr (const char*, int);
  23. char* strrchr (const char*, int);
  24. int strcmp (const char*, const char*);
  25. int strncmp (const char*, const char*, size_t);
  26. char* strcat (char*, const char*);
  27. char* stpcpy (char*, const char*);
  28. char* strcpy (char*, const char*);
  29. char* stpncpy (char*, const char*, size_t);
  30. char* strncpy (char*, const char*, size_t);
  31. char* strdup (const char*);
  32. char* strndup (const char*, size_t);
  33. char* strpbrk (const char*, const char*);
  34. size_t strcspn (const char*, const char*);
  35. size_t strspn (const char*, const char*);
  36. char* strstr (const char*, const char*);
  37. size_t strlen (const char*);
  38. size_t strnlen (const char*, size_t);
  39. extern void* malloc (size_t);
  40. void sink (void*);
  41. extern char *d;
  42. extern char a0[0];
  43. const char arr[7] = "abc\0def";
  44. /* Unterminated array at the end of ARR above. */
  45. #define unterm (arr + __builtin_strlen (arr) + 1)
  46. /* Size of the unterminated array - 1. */
  47. #define unterm_size (sizeof arr - __builtin_strlen (arr) - 1)
  48. const void* nowarn_memchr (int x)
  49. {
  50. const char *p1 = unterm;
  51. return memchr (p1, x, unterm_size);
  52. }
  53. const void* warn_memchr (int x)
  54. {
  55. const char *p1 = unterm;
  56. return memchr (p1, x, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  57. }
  58. void* nowarn_memcpy (void)
  59. {
  60. const char *s = unterm;
  61. return memcpy (d, s, unterm_size);
  62. }
  63. void* warn_memcpy (void)
  64. {
  65. const char *s = unterm;
  66. /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
  67. from defeating the warning (for now). */
  68. return memcpy (d, s, unterm_size + 2 | 1); // { dg-warning "-Wstringop-overread" }
  69. }
  70. void* nowarn_mempcpy (void)
  71. {
  72. const char *s = unterm;
  73. return mempcpy (d, s, unterm_size);
  74. }
  75. void* warn_mempcpy (void)
  76. {
  77. const char *s = unterm;
  78. /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
  79. from defeating the warning (for now). */
  80. return mempcpy (d, s, unterm_size + 2 | 1); // { dg-warning "-Wstringop-overread" }
  81. }
  82. void* nowarn_memmove (void)
  83. {
  84. const char *s = unterm;
  85. return memmove (d, s, unterm_size);
  86. }
  87. void* warn_memmove (void)
  88. {
  89. const char *s = unterm;
  90. /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
  91. from defeating the warning (for now). */
  92. return memmove (d, s, unterm_size + 2); // { dg-warning "-Wstringop-overread" }
  93. }
  94. int nowarn_memcmp_1 (const char *p2)
  95. {
  96. const char *p1 = unterm;
  97. return memcmp (p1, p2, unterm_size);
  98. }
  99. int warn_memcmp_1 (const char *p2)
  100. {
  101. const char *p1 = unterm;
  102. return memcmp (p1, p2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  103. }
  104. int nowarn_memcmp_2 (const char *p1)
  105. {
  106. const char *p2 = unterm;
  107. return memcmp (p1, p2, unterm_size);
  108. }
  109. int warn_memcmp_2 (const char *p1)
  110. {
  111. const char *p2 = unterm;
  112. return memcmp (p1, p2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  113. }
  114. void warn_strcat (void)
  115. {
  116. strcat (d, unterm); // { dg-warning "-Wstringop-overread" }
  117. }
  118. void warn_strcat_a0 (void)
  119. {
  120. strcat (d, a0); // { dg-warning "-Wstringop-overread" }
  121. }
  122. void warn_strcat_end (void)
  123. {
  124. const char *s = arr + sizeof arr;
  125. strcat (d, s); // { dg-warning "-Wstringop-overread" }
  126. }
  127. char* warn_stpcpy (void)
  128. {
  129. return stpcpy (d, unterm); // { dg-warning "-Wstringop-overread" }
  130. }
  131. char* warn_stpcpy_a0 (void)
  132. {
  133. return stpcpy (d, a0); // { dg-warning "-Wstringop-overread" }
  134. }
  135. char* warn_stpcpy_end (void)
  136. {
  137. const char *s = arr + sizeof arr;
  138. return stpcpy (d, s); // { dg-warning "-Wstringop-overread" }
  139. }
  140. char* warn_stpcpy_malloc0 (void)
  141. {
  142. char *s = malloc (0);
  143. sink (s);
  144. return stpcpy (d, s); // { dg-warning "-Wstringop-overread" }
  145. }
  146. void warn_strcpy (void)
  147. {
  148. strcpy (d, unterm); // { dg-warning "-Wstringop-overread" }
  149. }
  150. void warn_strcpy_a0 (void)
  151. {
  152. strcpy (d, a0); // { dg-warning "-Wstringop-overread" }
  153. }
  154. void warn_strcpy_end (void)
  155. {
  156. const char *s = arr + sizeof arr;
  157. strcpy (d, s); // { dg-warning "-Wstringop-overread" }
  158. }
  159. void warn_strcpy_malloc0 (void)
  160. {
  161. char *s = malloc (0);
  162. sink (s);
  163. strcpy (d, s); // { dg-warning "-Wstringop-overread" }
  164. }
  165. char* nowarn_stpncpy (void)
  166. {
  167. const char *s = unterm;
  168. return stpncpy (d, s, unterm_size);
  169. }
  170. char* warn_stpncpy (void)
  171. {
  172. const char *s = unterm;
  173. return stpncpy (d, s, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  174. }
  175. char* warn_stpncpy_a0 (void)
  176. {
  177. return stpncpy (d, a0, 3); // { dg-warning "-Wstringop-overread" }
  178. }
  179. char* warn_stpncpy_end (void)
  180. {
  181. const char *s = arr + sizeof arr;
  182. return stpncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" }
  183. }
  184. void nowarn_strncpy (void)
  185. {
  186. const char *s = unterm;
  187. strncpy (d, s, unterm_size);
  188. }
  189. void warn_strncpy (void)
  190. {
  191. const char *s = unterm;
  192. strncpy (d, s, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  193. }
  194. void warn_strncpy_a0 (void)
  195. {
  196. const char *s = a0;
  197. strncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" }
  198. }
  199. void warn_strncpy_end (void)
  200. {
  201. const char *s = arr + sizeof arr;
  202. strncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" }
  203. }
  204. int warn_strlen (void)
  205. {
  206. return strlen (unterm); // { dg-warning "-Wstringop-overread" }
  207. }
  208. int warn_strlen_a0 (void)
  209. {
  210. return strlen (a0); // { dg-warning "-Wstringop-overread" }
  211. }
  212. int warn_strlen_end (void)
  213. {
  214. const char *s = arr + sizeof arr;
  215. return strlen (s); // { dg-warning "-Wstringop-overread" }
  216. }
  217. int warn_strlen_malloc0 (void)
  218. {
  219. char *s = malloc (0);
  220. sink (s);
  221. return strlen (s); // { dg-warning "-Wstringop-overread" }
  222. }
  223. int nowarn_strnlen (void)
  224. {
  225. return strnlen (unterm, unterm_size);
  226. }
  227. int warn_strnlen (void)
  228. {
  229. return strnlen (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  230. }
  231. int warn_strnlen_end (void)
  232. {
  233. const char *s = arr + sizeof arr;
  234. return strnlen (s, 2); // { dg-warning "-Wstringop-overread" }
  235. }
  236. int warn_strcmp_1 (const char *s)
  237. {
  238. return strcmp (unterm, s); // { dg-warning "-Wstringop-overread" }
  239. }
  240. int warn_strcmp_2 (const char *s)
  241. {
  242. return strcmp (s, unterm); // { dg-warning "-Wstringop-overread" }
  243. }
  244. int warn_strcmp_2_end (const char *s)
  245. {
  246. const char *t = arr + sizeof arr;
  247. return strcmp (s, t); // { dg-warning "-Wstringop-overread" }
  248. }
  249. int nowarn_strncmp_1 (const char *s2)
  250. {
  251. const char *s1 = unterm;
  252. return strncmp (s1, s2, unterm_size);
  253. }
  254. int warn_strncmp_1 (const char *s2)
  255. {
  256. const char *s1 = unterm;
  257. return strncmp (s1, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  258. }
  259. int nowarn_strncmp_2 (const char *s1)
  260. {
  261. const char *s2 = unterm;
  262. return strncmp (s1, s2, unterm_size);
  263. }
  264. int warn_strncmp_2 (const char *s1)
  265. {
  266. const char *s2 = unterm;
  267. return strncmp (s1, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  268. }
  269. int warn_strncmp_2_end (const char *s1)
  270. {
  271. const char *s2 = arr + sizeof arr;;
  272. return strncmp (s1, s2, sizeof arr); // { dg-warning "-Wstringop-overread" }
  273. }
  274. int nowarn_strncmp_1_s2 (void)
  275. {
  276. /* Since the read is also bounded by the length of the S2 literal
  277. and so safe, expect no warning. */
  278. const char *s = unterm;
  279. return strncmp (s, S2, unterm_size + 1); // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } }
  280. }
  281. int warn_strncmp_2_s2 (void)
  282. {
  283. /* Same as above. */
  284. const char *t = unterm;
  285. return strncmp (S2, t, unterm_size + 1); // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } }
  286. }
  287. int warn_strncmp_1_s9 (void)
  288. {
  289. /* Since both the bound and the length of the S9 literal are greater
  290. than the size of UNNTERM the call reads past the end of the array.
  291. Expect a warning. */
  292. const char *s1 = unterm;
  293. return strncmp (s1, S9, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  294. }
  295. int warn_strncmp_2_s9 (void)
  296. {
  297. /* Same as above. */
  298. const char *s2 = unterm;
  299. return strncmp (S9, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  300. }
  301. const char* warn_strchr (int x)
  302. {
  303. return strchr (unterm, x); // { dg-warning "-Wstringop-overread" }
  304. }
  305. const char* warn_strchr_end (int x)
  306. {
  307. const char *s = arr + sizeof arr;
  308. return strchr (s, x); // { dg-warning "-Wstringop-overread" }
  309. }
  310. const char* warn_strrchr (int x)
  311. {
  312. return strrchr (unterm, x); // { dg-warning "-Wstringop-overread" }
  313. }
  314. const char* warn_strrchr_end (int x)
  315. {
  316. const char *s = arr + sizeof arr;
  317. return strrchr (s, x); // { dg-warning "-Wstringop-overread" }
  318. }
  319. char* warn_strdup (void)
  320. {
  321. return strdup (unterm); // { dg-warning "-Wstringop-overread" }
  322. }
  323. char* warn_strdup_end (void)
  324. {
  325. const char *s = arr + sizeof arr;
  326. return strdup (s); // { dg-warning "-Wstringop-overread" }
  327. }
  328. char* nowarn_strndup (void)
  329. {
  330. return strndup (unterm, unterm_size);
  331. }
  332. char* warn_strndup (void)
  333. {
  334. return strndup (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
  335. }
  336. char* warn_strndup_end (void)
  337. {
  338. const char *s = arr + sizeof arr;
  339. return strndup (s, sizeof arr); // { dg-warning "-Wstringop-overread" }
  340. }
  341. const char* warn_strpbrk_1 (const char *s2)
  342. {
  343. return strpbrk (unterm, s2); // { dg-warning "-Wstringop-overread" }
  344. }
  345. const char* warn_strpbrk_2 (const char *s1)
  346. {
  347. return strpbrk (s1, unterm); // { dg-warning "-Wstringop-overread" }
  348. }
  349. size_t warn_strspn_1 (const char *s2)
  350. {
  351. return strspn (unterm, s2); // { dg-warning "-Wstringop-overread" }
  352. }
  353. size_t warn_strspn_1_end (const char *s2)
  354. {
  355. const char *s1 = arr + sizeof arr;
  356. return strspn (s1, s2); // { dg-warning "-Wstringop-overread" }
  357. }
  358. size_t warn_strspn_2 (const char *s1)
  359. {
  360. return strspn (s1, unterm); // { dg-warning "-Wstringop-overread" }
  361. }
  362. size_t warn_strspn_2_end (const char *s1)
  363. {
  364. const char *s2 = arr + sizeof arr;
  365. return strspn (s1, s2); // { dg-warning "-Wstringop-overread" }
  366. }
  367. size_t warn_strcspn_1 (const char *s2)
  368. {
  369. return strcspn (unterm, s2); // { dg-warning "-Wstringop-overread" }
  370. }
  371. size_t warn_strcspn_1_end (const char *s2)
  372. {
  373. const char *s1 = arr + sizeof arr;
  374. return strcspn (s1, s2); // { dg-warning "-Wstringop-overread" }
  375. }
  376. size_t warn_strcspn_2 (const char *s1)
  377. {
  378. return strcspn (s1, unterm); // { dg-warning "-Wstringop-overread" }
  379. }
  380. size_t warn_strcspn_2_end (const char *s1)
  381. {
  382. const char *s2 = arr + sizeof arr;
  383. return strcspn (s1, s2); // { dg-warning "-Wstringop-overread" }
  384. }
  385. const char* warn_strstr_1 (const char *s2)
  386. {
  387. return strstr (unterm, s2); // { dg-warning "-Wstringop-overread" }
  388. }
  389. const char* warn_strstr_1_end (const char *s2)
  390. {
  391. const char *s1 = arr + sizeof arr;
  392. return strstr (s1, s2); // { dg-warning "-Wstringop-overread" }
  393. }
  394. const char* warn_strstr_2 (const char *s1)
  395. {
  396. return strstr (s1, unterm); // { dg-warning "-Wstringop-overread" }
  397. }
  398. const char* warn_strstr_2_end (const char *s1)
  399. {
  400. const char *s2 = arr + sizeof arr;
  401. return strstr (s1, s2); // { dg-warning "-Wstringop-overread" }
  402. }
  403. void warn_puts (void)
  404. {
  405. puts (unterm); // { dg-warning "-Wstringop-overread" }
  406. }
  407. void warn_puts_end (void)
  408. {
  409. const char *s = arr + sizeof arr;
  410. puts (s); // { dg-warning "-Wstringop-overread" }
  411. }
  412. void warn_fputs (FILE *f)
  413. {
  414. fputs (unterm, f); // { dg-warning "-Wstringop-overread" }
  415. }
  416. void warn_fputs_end (FILE *f)
  417. {
  418. const char *s = arr + sizeof arr;
  419. fputs (s, f); // { dg-warning "-Wstringop-overread" }
  420. }
  421. void warn_puts_unlocked (void)
  422. {
  423. puts_unlocked (unterm); // { dg-warning "-Wstringop-overread" }
  424. }
  425. void warn_puts_unlocked_end (void)
  426. {
  427. const char *s = arr + sizeof arr;
  428. puts_unlocked (s); // { dg-warning "-Wstringop-overread" }
  429. }
  430. void warn_fputs_unlocked (FILE *f)
  431. {
  432. fputs_unlocked (unterm, f); // { dg-warning "-Wstringop-overread" }
  433. }
  434. const char* warn_gettext (void)
  435. {
  436. return gettext (unterm); // { dg-warning "-Wstringop-overread" }
  437. }
  438. const char* warn_gettext_end (void)
  439. {
  440. const char *s = arr + sizeof arr;
  441. return gettext (s); // { dg-warning "-Wstringop-overread" }
  442. }