blob: 208ff6909f109f12bcd1640277c225dcda97a46a [file] [log] [blame]
Erik Pilkingtonb6e16ea2019-03-18 19:23:45 +00001// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify
2// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_PASS_OBJECT_SIZE
3// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
4
5typedef unsigned long size_t;
6
7#if defined(USE_PASS_OBJECT_SIZE)
8void *memcpy(void *dst, const void *src, size_t c);
9static void *memcpy(void *dst __attribute__((pass_object_size(1))), const void *src, size_t c) __attribute__((overloadable)) __asm__("merp");
10static void *memcpy(void *const dst __attribute__((pass_object_size(1))), const void *src, size_t c) __attribute__((overloadable)) {
11 return 0;
12}
13#elif defined(USE_BUILTINS)
14#define memcpy(x,y,z) __builtin_memcpy(x,y,z)
15#else
16void *memcpy(void *dst, const void *src, size_t c);
17#endif
18
19void call_memcpy() {
20 char dst[10];
21 char src[20];
22 memcpy(dst, src, 20); // expected-warning {{memcpy' will always overflow; destination buffer has size 10, but size argument is 20}}
23}
24
25void call_memcpy_type() {
26 struct pair {
27 int first;
28 int second;
29 };
30 struct pair p;
31 char buf[20];
32 memcpy(&p.first, buf, 20);
33#ifdef USE_PASS_OBJECT_SIZE
34 // Use the more strict checking mode on the pass_object_size attribute:
35 // expected-warning@-3 {{memcpy' will always overflow; destination buffer has size 4, but size argument is 20}}
36#else
37 // Or just fallback to type 0:
38 // expected-warning@-6 {{memcpy' will always overflow; destination buffer has size 8, but size argument is 20}}
39#endif
40}
41
42void call_strncat() {
43 char s1[10], s2[20];
44 __builtin_strncat(s2, s1, 20);
45 __builtin_strncat(s1, s2, 20); // expected-warning {{'strncat' size argument is too large; destination buffer has size 10, but size argument is 20}}
46}
47
48void call_strncpy() {
49 char s1[10], s2[20];
50 __builtin_strncpy(s2, s1, 20);
51 __builtin_strncpy(s1, s2, 20); // expected-warning {{'strncpy' size argument is too large; destination buffer has size 10, but size argument is 20}}
52}
53
54void call_stpncpy() {
55 char s1[10], s2[20];
56 __builtin_stpncpy(s2, s1, 20);
57 __builtin_stpncpy(s1, s2, 20); // expected-warning {{'stpncpy' size argument is too large; destination buffer has size 10, but size argument is 20}}
58}
59
60void call_memmove() {
61 char s1[10], s2[20];
62 __builtin_memmove(s2, s1, 20);
63 __builtin_memmove(s1, s2, 20); // expected-warning {{'memmove' will always overflow; destination buffer has size 10, but size argument is 20}}
64}
65
66void call_memset() {
67 char buf[10];
68 __builtin_memset(buf, 0xff, 10);
69 __builtin_memset(buf, 0xff, 11); // expected-warning {{'memset' will always overflow; destination buffer has size 10, but size argument is 11}}
70}
71
72void call_snprintf() {
73 char buf[10];
74 __builtin_snprintf(buf, 10, "merp");
75 __builtin_snprintf(buf, 11, "merp"); // expected-warning {{'snprintf' size argument is too large; destination buffer has size 10, but size argument is 11}}
76}
77
78void call_vsnprintf() {
79 char buf[10];
80 __builtin_va_list list;
81 __builtin_vsnprintf(buf, 10, "merp", list);
82 __builtin_vsnprintf(buf, 11, "merp", list); // expected-warning {{'vsnprintf' size argument is too large; destination buffer has size 10, but size argument is 11}}
83}