George Karpenkov | a393e68 | 2018-08-29 20:29:17 +0000 | [diff] [blame] | 1 | // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s |
| 2 | // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s |
| 3 | // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s |
| 4 | // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s |
| 5 | // RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s |
Devin Coughlin | 9165df1 | 2016-02-07 16:55:44 +0000 | [diff] [blame] | 6 | |
| 7 | #include "Inputs/system-header-simulator-cxx.h" |
| 8 | #include "Inputs/system-header-simulator-for-malloc.h" |
| 9 | |
Artem Dergachev | db65f96 | 2017-10-13 20:11:00 +0000 | [diff] [blame] | 10 | // This provides us with four possible mempcpy() definitions. |
| 11 | // See also comments in bstring.c. |
| 12 | |
| 13 | #ifdef USE_BUILTINS |
| 14 | #define BUILTIN(f) __builtin_##f |
| 15 | #else /* USE_BUILTINS */ |
| 16 | #define BUILTIN(f) f |
| 17 | #endif /* USE_BUILTINS */ |
| 18 | |
| 19 | #ifdef VARIANT |
| 20 | |
| 21 | #define __mempcpy_chk BUILTIN(__mempcpy_chk) |
| 22 | void *__mempcpy_chk(void *__restrict__ s1, const void *__restrict__ s2, |
| 23 | size_t n, size_t destlen); |
| 24 | |
| 25 | #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1) |
| 26 | |
| 27 | #else /* VARIANT */ |
| 28 | |
| 29 | #define mempcpy BUILTIN(mempcpy) |
| 30 | void *mempcpy(void *__restrict__ s1, const void *__restrict__ s2, size_t n); |
| 31 | |
| 32 | #endif /* VARIANT */ |
| 33 | |
Devin Coughlin | 9165df1 | 2016-02-07 16:55:44 +0000 | [diff] [blame] | 34 | void clang_analyzer_eval(int); |
| 35 | |
| 36 | int *testStdCopyInvalidatesBuffer(std::vector<int> v) { |
| 37 | int n = v.size(); |
| 38 | int *buf = (int *)malloc(n * sizeof(int)); |
| 39 | |
| 40 | buf[0] = 66; |
| 41 | |
| 42 | // Call to copy should invalidate buf. |
| 43 | std::copy(v.begin(), v.end(), buf); |
| 44 | |
| 45 | int i = buf[0]; |
| 46 | |
| 47 | clang_analyzer_eval(i == 66); // expected-warning {{UNKNOWN}} |
| 48 | |
| 49 | return buf; |
| 50 | } |
| 51 | |
| 52 | int *testStdCopyBackwardInvalidatesBuffer(std::vector<int> v) { |
| 53 | int n = v.size(); |
| 54 | int *buf = (int *)malloc(n * sizeof(int)); |
| 55 | |
| 56 | buf[0] = 66; |
| 57 | |
| 58 | // Call to copy_backward should invalidate buf. |
| 59 | std::copy_backward(v.begin(), v.end(), buf + n); |
| 60 | |
| 61 | int i = buf[0]; |
| 62 | |
| 63 | clang_analyzer_eval(i == 66); // expected-warning {{UNKNOWN}} |
| 64 | |
| 65 | return buf; |
| 66 | } |
Artem Dergachev | db65f96 | 2017-10-13 20:11:00 +0000 | [diff] [blame] | 67 | |
| 68 | namespace pr34460 { |
| 69 | short a; |
| 70 | class b { |
| 71 | int c; |
| 72 | long g; |
| 73 | void d() { |
| 74 | int e = c; |
| 75 | f += e; |
| 76 | mempcpy(f, &a, g); |
| 77 | } |
| 78 | unsigned *f; |
| 79 | }; |
| 80 | } |
Henry Wong | afe62cd | 2018-05-16 12:37:53 +0000 | [diff] [blame] | 81 | |
| 82 | void *memset(void *dest, int ch, std::size_t count); |
| 83 | namespace memset_non_pod { |
| 84 | class Base { |
| 85 | public: |
| 86 | int b_mem; |
| 87 | Base() : b_mem(1) {} |
| 88 | }; |
| 89 | |
| 90 | class Derived : public Base { |
| 91 | public: |
| 92 | int d_mem; |
| 93 | Derived() : d_mem(2) {} |
| 94 | }; |
| 95 | |
| 96 | void memset1_inheritance() { |
| 97 | Derived d; |
| 98 | memset(&d, 0, sizeof(Derived)); |
| 99 | clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}} |
| 100 | clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}} |
| 101 | } |
| 102 | |
| 103 | #ifdef SUPPRESS_OUT_OF_BOUND |
| 104 | void memset2_inheritance_field() { |
| 105 | Derived d; |
| 106 | memset(&d.d_mem, 0, sizeof(Derived)); |
| 107 | clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}} |
| 108 | clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}} |
| 109 | } |
| 110 | |
| 111 | void memset3_inheritance_field() { |
| 112 | Derived d; |
| 113 | memset(&d.b_mem, 0, sizeof(Derived)); |
| 114 | clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}} |
| 115 | clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}} |
| 116 | } |
| 117 | #endif |
| 118 | |
| 119 | void memset4_array_nonpod_object() { |
| 120 | Derived array[10]; |
| 121 | clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}} |
| 122 | clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}} |
| 123 | memset(&array[1], 0, sizeof(Derived)); |
| 124 | clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{UNKNOWN}} |
| 125 | clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{UNKNOWN}} |
| 126 | } |
| 127 | |
| 128 | void memset5_array_nonpod_object() { |
| 129 | Derived array[10]; |
| 130 | clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}} |
| 131 | clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}} |
| 132 | memset(array, 0, sizeof(array)); |
| 133 | clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{TRUE}} |
| 134 | clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{TRUE}} |
| 135 | } |
| 136 | |
| 137 | void memset6_new_array_nonpod_object() { |
| 138 | Derived *array = new Derived[10]; |
| 139 | clang_analyzer_eval(array[2].b_mem == 1); // expected-warning{{UNKNOWN}} |
| 140 | clang_analyzer_eval(array[2].d_mem == 2); // expected-warning{{UNKNOWN}} |
| 141 | memset(array, 0, 10 * sizeof(Derived)); |
| 142 | clang_analyzer_eval(array[2].b_mem == 0); // expected-warning{{TRUE}} |
| 143 | clang_analyzer_eval(array[2].d_mem == 0); // expected-warning{{TRUE}} |
| 144 | delete[] array; |
| 145 | } |
| 146 | |
| 147 | void memset7_placement_new() { |
| 148 | Derived *d = new Derived(); |
| 149 | clang_analyzer_eval(d->b_mem == 1); // expected-warning{{TRUE}} |
| 150 | clang_analyzer_eval(d->d_mem == 2); // expected-warning{{TRUE}} |
| 151 | |
| 152 | memset(d, 0, sizeof(Derived)); |
| 153 | clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}} |
| 154 | clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}} |
| 155 | |
| 156 | Derived *d1 = new (d) Derived(); |
| 157 | clang_analyzer_eval(d1->b_mem == 1); // expected-warning{{TRUE}} |
| 158 | clang_analyzer_eval(d1->d_mem == 2); // expected-warning{{TRUE}} |
| 159 | |
| 160 | memset(d1, 0, sizeof(Derived)); |
| 161 | clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}} |
| 162 | clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}} |
| 163 | } |
| 164 | |
| 165 | class BaseVirtual { |
| 166 | public: |
| 167 | int b_mem; |
| 168 | virtual int get() { return 1; } |
| 169 | }; |
| 170 | |
| 171 | class DerivedVirtual : public BaseVirtual { |
| 172 | public: |
| 173 | int d_mem; |
| 174 | }; |
| 175 | |
| 176 | #ifdef SUPPRESS_OUT_OF_BOUND |
| 177 | void memset8_virtual_inheritance_field() { |
| 178 | DerivedVirtual d; |
| 179 | memset(&d.b_mem, 0, sizeof(Derived)); |
| 180 | clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}} |
| 181 | clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}} |
| 182 | } |
| 183 | #endif |
| 184 | } // namespace memset_non_pod |
| 185 | |
| 186 | #ifdef SUPPRESS_OUT_OF_BOUND |
| 187 | void memset1_new_array() { |
| 188 | int *array = new int[10]; |
| 189 | memset(array, 0, 10 * sizeof(int)); |
| 190 | clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}} |
| 191 | memset(array + 1, 'a', 10 * sizeof(9)); |
| 192 | clang_analyzer_eval(array[2] == 0); // expected-warning{{UNKNOWN}} |
| 193 | delete[] array; |
| 194 | } |
| 195 | #endif |