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); |
| 6 | |
| 7 | struct S {int a, b, c, d;}; |
| 8 | typedef S* PS; |
| 9 | |
| 10 | struct Foo {}; |
| 11 | typedef const Foo& CFooRef; |
| 12 | typedef const Foo CFoo; |
| 13 | typedef volatile Foo VFoo; |
| 14 | typedef const volatile Foo CVFoo; |
| 15 | |
| 16 | typedef double Mat[4][4]; |
| 17 | |
| 18 | template <class Dest, class Source> |
| 19 | inline Dest bit_cast(const Source& source) { |
| 20 | Dest dest; |
| 21 | memcpy(&dest, &source, sizeof(dest)); |
| 22 | return dest; |
| 23 | } |
| 24 | |
| 25 | // 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] | 26 | void f(Mat m, const Foo& const_foo, char *buffer) { |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 27 | S s; |
| 28 | S* ps = &s; |
| 29 | PS ps2 = &s; |
| 30 | char arr[5]; |
| 31 | char* parr[5]; |
| 32 | Foo foo; |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 33 | char* heap_buffer = new char[42]; |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 34 | |
| 35 | /* Should warn */ |
| 36 | memset(&s, 0, sizeof(&s)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 37 | // 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] | 38 | memset(ps, 0, sizeof(ps)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 39 | // 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] | 40 | memset(ps2, 0, sizeof(ps2)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 41 | // 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] | 42 | memset(ps2, 0, sizeof(typeof(ps2))); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 43 | // 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] | 44 | memset(ps2, 0, sizeof(PS)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 45 | // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} |
| 46 | memset(heap_buffer, 0, sizeof(heap_buffer)); // \ |
| 47 | // 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] | 48 | |
| 49 | memcpy(&s, 0, sizeof(&s)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 50 | // 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] | 51 | memcpy(0, &s, sizeof(&s)); // \ |
Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 52 | // 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] | 53 | |
| 54 | /* Shouldn't warn */ |
| 55 | memset((void*)&s, 0, sizeof(&s)); |
| 56 | memset(&s, 0, sizeof(s)); |
| 57 | memset(&s, 0, sizeof(S)); |
| 58 | memset(&s, 0, sizeof(const S)); |
| 59 | memset(&s, 0, sizeof(volatile S)); |
| 60 | memset(&s, 0, sizeof(volatile const S)); |
| 61 | memset(&foo, 0, sizeof(CFoo)); |
| 62 | memset(&foo, 0, sizeof(VFoo)); |
| 63 | memset(&foo, 0, sizeof(CVFoo)); |
| 64 | memset(ps, 0, sizeof(*ps)); |
| 65 | memset(ps2, 0, sizeof(*ps2)); |
| 66 | memset(ps2, 0, sizeof(typeof(*ps2))); |
| 67 | memset(arr, 0, sizeof(arr)); |
| 68 | memset(parr, 0, sizeof(parr)); |
| 69 | |
| 70 | memcpy(&foo, &const_foo, sizeof(Foo)); |
| 71 | memcpy((void*)&s, 0, sizeof(&s)); |
| 72 | memcpy(0, (void*)&s, sizeof(&s)); |
Chandler Carruth | c7b993b | 2011-06-16 04:13:47 +0000 | [diff] [blame] | 73 | char *cptr; |
| 74 | memcpy(&cptr, buffer, sizeof(cptr)); |
| 75 | memcpy((char*)&cptr, buffer, sizeof(cptr)); |
Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 76 | |
| 77 | CFooRef cfoo = foo; |
| 78 | memcpy(&foo, &cfoo, sizeof(Foo)); |
| 79 | |
| 80 | memcpy(0, &arr, sizeof(arr)); |
| 81 | typedef char Buff[8]; |
| 82 | memcpy(0, &arr, sizeof(Buff)); |
| 83 | |
| 84 | unsigned char* puc; |
| 85 | bit_cast<char*>(puc); |
| 86 | |
| 87 | float* pf; |
| 88 | bit_cast<int*>(pf); |
| 89 | |
| 90 | int iarr[14]; |
| 91 | memset(&iarr[0], 0, sizeof iarr); |
| 92 | |
| 93 | int* iparr[14]; |
| 94 | memset(&iparr[0], 0, sizeof iparr); |
| 95 | |
| 96 | memset(m, 0, sizeof(Mat)); |
| 97 | |
| 98 | // Copy to raw buffer shouldn't warn either |
| 99 | memcpy(&foo, &arr, sizeof(Foo)); |
| 100 | memcpy(&arr, &foo, sizeof(Foo)); |
| 101 | } |