Nico Weber | 55080a7 | 2011-06-15 04:50:13 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 2 | // |
| 3 | extern "C" void *memset(void *, int, unsigned); |
| 4 | extern "C" void *memmove(void *s1, const void *s2, unsigned n); |
| 5 | extern "C" void *memcpy(void *s1, const void *s2, unsigned n); |
Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 6 | extern "C" void *memcmp(void *s1, const void *s2, unsigned n); |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 7 | |
| 8 | struct S {int a, b, c, d;}; |
| 9 | typedef S* PS; |
| 10 | |
| 11 | struct Foo {}; |
| 12 | typedef const Foo& CFooRef; |
| 13 | typedef const Foo CFoo; |
| 14 | typedef volatile Foo VFoo; |
| 15 | typedef const volatile Foo CVFoo; |
| 16 | |
| 17 | typedef double Mat[4][4]; |
| 18 | |
| 19 | template <class Dest, class Source> |
| 20 | inline Dest bit_cast(const Source& source) { |
| 21 | Dest dest; |
| 22 | memcpy(&dest, &source, sizeof(dest)); |
| 23 | return dest; |
| 24 | } |
| 25 | |
| 26 | // http://www.lysator.liu.se/c/c-faq/c-2.html#2-6 |
Chandler Carruth | c7b993b | 2011-06-16 04:13:47 +0000 | [diff] [blame] | 27 | void f(Mat m, const Foo& const_foo, char *buffer) { |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 28 | S s; |
| 29 | S* ps = &s; |
| 30 | PS ps2 = &s; |
| 31 | char arr[5]; |
| 32 | char* parr[5]; |
| 33 | Foo foo; |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 34 | char* heap_buffer = new char[42]; |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 35 | |
| 36 | /* Should warn */ |
| 37 | memset(&s, 0, sizeof(&s)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 38 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 39 | memset(ps, 0, sizeof(ps)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 40 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 41 | memset(ps2, 0, sizeof(ps2)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 42 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 43 | memset(ps2, 0, sizeof(typeof(ps2))); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 44 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 45 | memset(ps2, 0, sizeof(PS)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 46 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} |
| 47 | memset(heap_buffer, 0, sizeof(heap_buffer)); // \ |
| 48 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 49 | |
| 50 | memcpy(&s, 0, sizeof(&s)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 51 | // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the destination}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 52 | memcpy(0, &s, sizeof(&s)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 53 | // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source}} |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 54 | |
Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 55 | memmove(ps, 0, sizeof(ps)); // \ |
| 56 | // expected-warning {{argument to 'sizeof' in 'memmove' call is the same expression as the destination}} |
| 57 | memcmp(ps, 0, sizeof(ps)); // \ |
| 58 | // expected-warning {{argument to 'sizeof' in 'memcmp' call is the same expression as the destination}} |
| 59 | |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 60 | /* Shouldn't warn */ |
| 61 | memset((void*)&s, 0, sizeof(&s)); |
| 62 | memset(&s, 0, sizeof(s)); |
| 63 | memset(&s, 0, sizeof(S)); |
| 64 | memset(&s, 0, sizeof(const S)); |
| 65 | memset(&s, 0, sizeof(volatile S)); |
| 66 | memset(&s, 0, sizeof(volatile const S)); |
| 67 | memset(&foo, 0, sizeof(CFoo)); |
| 68 | memset(&foo, 0, sizeof(VFoo)); |
| 69 | memset(&foo, 0, sizeof(CVFoo)); |
| 70 | memset(ps, 0, sizeof(*ps)); |
| 71 | memset(ps2, 0, sizeof(*ps2)); |
| 72 | memset(ps2, 0, sizeof(typeof(*ps2))); |
| 73 | memset(arr, 0, sizeof(arr)); |
| 74 | memset(parr, 0, sizeof(parr)); |
| 75 | |
| 76 | memcpy(&foo, &const_foo, sizeof(Foo)); |
| 77 | memcpy((void*)&s, 0, sizeof(&s)); |
| 78 | memcpy(0, (void*)&s, sizeof(&s)); |
Chandler Carruth | c7b993b | 2011-06-16 04:13:47 +0000 | [diff] [blame] | 79 | char *cptr; |
| 80 | memcpy(&cptr, buffer, sizeof(cptr)); |
| 81 | memcpy((char*)&cptr, buffer, sizeof(cptr)); |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 82 | |
| 83 | CFooRef cfoo = foo; |
| 84 | memcpy(&foo, &cfoo, sizeof(Foo)); |
| 85 | |
| 86 | memcpy(0, &arr, sizeof(arr)); |
| 87 | typedef char Buff[8]; |
| 88 | memcpy(0, &arr, sizeof(Buff)); |
| 89 | |
| 90 | unsigned char* puc; |
| 91 | bit_cast<char*>(puc); |
| 92 | |
| 93 | float* pf; |
| 94 | bit_cast<int*>(pf); |
| 95 | |
| 96 | int iarr[14]; |
| 97 | memset(&iarr[0], 0, sizeof iarr); |
| 98 | |
| 99 | int* iparr[14]; |
| 100 | memset(&iparr[0], 0, sizeof iparr); |
| 101 | |
| 102 | memset(m, 0, sizeof(Mat)); |
| 103 | |
| 104 | // Copy to raw buffer shouldn't warn either |
| 105 | memcpy(&foo, &arr, sizeof(Foo)); |
| 106 | memcpy(&arr, &foo, sizeof(Foo)); |
| 107 | } |
Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 108 | |
| 109 | namespace ns { |
| 110 | void memset(void* s, char c, int n); |
| 111 | void f(int* i) { |
| 112 | memset(i, 0, sizeof(i)); |
| 113 | } |
| 114 | } |
Nico Weber | cda5782 | 2011-10-13 22:30:23 +0000 | [diff] [blame^] | 115 | |
| 116 | extern "C" int strncmp(const char *s1, const char *s2, unsigned n); |
| 117 | extern "C" int strncasecmp(const char *s1, const char *s2, unsigned n); |
| 118 | extern "C" char *strncpy(char *det, const char *src, unsigned n); |
| 119 | extern "C" char *strncat(char *dst, const char *src, unsigned n); |
| 120 | extern "C" char *strndup(const char *src, unsigned n); |
| 121 | |
| 122 | void strcpy_and_friends() { |
| 123 | const char* FOO = "<- should be an array instead"; |
| 124 | const char* BAR = "<- this, too"; |
| 125 | |
| 126 | strncmp(FOO, BAR, sizeof(FOO)); // \ |
| 127 | // expected-warning {{argument to 'sizeof' in 'strncmp' call is the same expression as the destination}} |
| 128 | strncasecmp(FOO, BAR, sizeof(FOO)); // \ |
| 129 | // expected-warning {{argument to 'sizeof' in 'strncasecmp' call is the same expression as the destination}} |
| 130 | |
| 131 | char buff[80]; |
| 132 | |
| 133 | strncpy(buff, BAR, sizeof(BAR)); // \ |
| 134 | // expected-warning {{argument to 'sizeof' in 'strncpy' call is the same expression as the source}} |
| 135 | strncat(buff, BAR, sizeof(BAR)); // \ |
| 136 | // expected-warning {{argument to 'sizeof' in 'strncat' call is the same expression as the source}} |
| 137 | strndup(FOO, sizeof(FOO)); // \ |
| 138 | // expected-warning {{argument to 'sizeof' in 'strndup' call is the same expression as the source}} |
| 139 | } |