Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
      2 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
      3 // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
      4 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
      5 
      6 //===----------------------------------------------------------------------===
      7 // Declarations
      8 //===----------------------------------------------------------------------===
      9 
     10 // Some functions are so similar to each other that they follow the same code
     11 // path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
     12 // defined, make sure to use the variants instead to make sure they are still
     13 // checked by the analyzer.
     14 
     15 // Some functions are implemented as builtins. These should be #defined as
     16 // BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
     17 
     18 // Functions that have variants and are also available as builtins should be
     19 // declared carefully! See memcpy() for an example.
     20 
     21 #ifdef USE_BUILTINS
     22 # define BUILTIN(f) __builtin_ ## f
     23 #else /* USE_BUILTINS */
     24 # define BUILTIN(f) f
     25 #endif /* USE_BUILTINS */
     26 
     27 typedef typeof(sizeof(int)) size_t;
     28 
     29 void clang_analyzer_eval(int);
     30 
     31 //===----------------------------------------------------------------------===
     32 // memcpy()
     33 //===----------------------------------------------------------------------===
     34 
     35 #ifdef VARIANT
     36 
     37 #define __memcpy_chk BUILTIN(__memcpy_chk)
     38 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
     39                    size_t destlen);
     40 
     41 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
     42 
     43 #else /* VARIANT */
     44 
     45 #define memcpy BUILTIN(memcpy)
     46 void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
     47 
     48 #endif /* VARIANT */
     49 
     50 
     51 void memcpy0 () {
     52   char src[] = {1, 2, 3, 4};
     53   char dst[4] = {0};
     54 
     55   memcpy(dst, src, 4); // no-warning
     56 
     57   clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
     58 
     59   // If we actually model the copy, we can make this known.
     60   // The important thing for now is that the old value has been invalidated.
     61   clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
     62 }
     63 
     64 void memcpy1 () {
     65   char src[] = {1, 2, 3, 4};
     66   char dst[10];
     67 
     68   memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
     69 }
     70 
     71 void memcpy2 () {
     72   char src[] = {1, 2, 3, 4};
     73   char dst[1];
     74 
     75   memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
     76 }
     77 
     78 void memcpy3 () {
     79   char src[] = {1, 2, 3, 4};
     80   char dst[3];
     81 
     82   memcpy(dst+1, src+2, 2); // no-warning
     83 }
     84 
     85 void memcpy4 () {
     86   char src[] = {1, 2, 3, 4};
     87   char dst[10];
     88 
     89   memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
     90 }
     91 
     92 void memcpy5() {
     93   char src[] = {1, 2, 3, 4};
     94   char dst[3];
     95 
     96   memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
     97 }
     98 
     99 void memcpy6() {
    100   int a[4] = {0};
    101   memcpy(a, a, 8); // expected-warning{{overlapping}}
    102 }
    103 
    104 void memcpy7() {
    105   int a[4] = {0};
    106   memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
    107 }
    108 
    109 void memcpy8() {
    110   int a[4] = {0};
    111   memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
    112 }
    113 
    114 void memcpy9() {
    115   int a[4] = {0};
    116   memcpy(a+2, a+1, 4); // no-warning
    117   memcpy(a+1, a+2, 4); // no-warning
    118 }
    119 
    120 void memcpy10() {
    121   char a[4] = {0};
    122   memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    123 }
    124 
    125 void memcpy11() {
    126   char a[4] = {0};
    127   memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    128 }
    129 
    130 void memcpy12() {
    131   char a[4] = {0};
    132   memcpy(0, a, 0); // no-warning
    133 }
    134 
    135 void memcpy13() {
    136   char a[4] = {0};
    137   memcpy(a, 0, 0); // no-warning
    138 }
    139 
    140 void memcpy_unknown_size (size_t n) {
    141   char a[4], b[4] = {1};
    142   clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
    143 }
    144 
    145 void memcpy_unknown_size_warn (size_t n) {
    146   char a[4];
    147   void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
    148   clang_analyzer_eval(result == a); // no-warning (above is fatal)
    149 }
    150 
    151 //===----------------------------------------------------------------------===
    152 // mempcpy()
    153 //===----------------------------------------------------------------------===
    154 
    155 #ifdef VARIANT
    156 
    157 #define __mempcpy_chk BUILTIN(__mempcpy_chk)
    158 void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
    159                    size_t destlen);
    160 
    161 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
    162 
    163 #else /* VARIANT */
    164 
    165 #define mempcpy BUILTIN(mempcpy)
    166 void *mempcpy(void *restrict s1, const void *restrict s2, size_t n);
    167 
    168 #endif /* VARIANT */
    169 
    170 
    171 void mempcpy0 () {
    172   char src[] = {1, 2, 3, 4};
    173   char dst[5] = {0};
    174 
    175   mempcpy(dst, src, 4); // no-warning
    176 
    177   clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
    178 
    179   // If we actually model the copy, we can make this known.
    180   // The important thing for now is that the old value has been invalidated.
    181   clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
    182 }
    183 
    184 void mempcpy1 () {
    185   char src[] = {1, 2, 3, 4};
    186   char dst[10];
    187 
    188   mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
    189 }
    190 
    191 void mempcpy2 () {
    192   char src[] = {1, 2, 3, 4};
    193   char dst[1];
    194 
    195   mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
    196 }
    197 
    198 void mempcpy3 () {
    199   char src[] = {1, 2, 3, 4};
    200   char dst[3];
    201 
    202   mempcpy(dst+1, src+2, 2); // no-warning
    203 }
    204 
    205 void mempcpy4 () {
    206   char src[] = {1, 2, 3, 4};
    207   char dst[10];
    208 
    209   mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
    210 }
    211 
    212 void mempcpy5() {
    213   char src[] = {1, 2, 3, 4};
    214   char dst[3];
    215 
    216   mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
    217 }
    218 
    219 void mempcpy6() {
    220   int a[4] = {0};
    221   mempcpy(a, a, 8); // expected-warning{{overlapping}}
    222 }
    223 
    224 void mempcpy7() {
    225   int a[4] = {0};
    226   mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
    227 }
    228 
    229 void mempcpy8() {
    230   int a[4] = {0};
    231   mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
    232 }
    233 
    234 void mempcpy9() {
    235   int a[4] = {0};
    236   mempcpy(a+2, a+1, 4); // no-warning
    237   mempcpy(a+1, a+2, 4); // no-warning
    238 }
    239 
    240 void mempcpy10() {
    241   char a[4] = {0};
    242   mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    243 }
    244 
    245 void mempcpy11() {
    246   char a[4] = {0};
    247   mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    248 }
    249 
    250 void mempcpy12() {
    251   char a[4] = {0};
    252   mempcpy(0, a, 0); // no-warning
    253 }
    254 
    255 void mempcpy13() {
    256   char a[4] = {0};
    257   mempcpy(a, 0, 0); // no-warning
    258 }
    259 
    260 void mempcpy14() {
    261   int src[] = {1, 2, 3, 4};
    262   int dst[5] = {0};
    263   int *p;
    264 
    265   p = mempcpy(dst, src, 4 * sizeof(int));
    266 
    267   clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}}
    268 }
    269 
    270 struct st {
    271   int i;
    272   int j;
    273 };
    274 
    275 void mempcpy15() {
    276   struct st s1 = {0};
    277   struct st s2;
    278   struct st *p1;
    279   struct st *p2;
    280 
    281   p1 = (&s2) + 1;
    282   p2 = mempcpy(&s2, &s1, sizeof(struct st));
    283 
    284   clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
    285 }
    286 
    287 void mempcpy16() {
    288   struct st s1[10] = {{0}};
    289   struct st s2[10];
    290   struct st *p1;
    291   struct st *p2;
    292 
    293   p1 = (&s2[0]) + 5;
    294   p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st));
    295 
    296   clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}}
    297 }
    298 
    299 void mempcpy_unknown_size_warn (size_t n) {
    300   char a[4];
    301   void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
    302   clang_analyzer_eval(result == a); // no-warning (above is fatal)
    303 }
    304 
    305 void mempcpy_unknownable_size (char *src, float n) {
    306   char a[4];
    307   // This used to crash because we don't model floats.
    308   mempcpy(a, src, (size_t)n);
    309 }
    310 
    311 //===----------------------------------------------------------------------===
    312 // memmove()
    313 //===----------------------------------------------------------------------===
    314 
    315 #ifdef VARIANT
    316 
    317 #define __memmove_chk BUILTIN(__memmove_chk)
    318 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
    319 
    320 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
    321 
    322 #else /* VARIANT */
    323 
    324 #define memmove BUILTIN(memmove)
    325 void *memmove(void *s1, const void *s2, size_t n);
    326 
    327 #endif /* VARIANT */
    328 
    329 
    330 void memmove0 () {
    331   char src[] = {1, 2, 3, 4};
    332   char dst[4] = {0};
    333 
    334   memmove(dst, src, 4); // no-warning
    335 
    336   clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
    337 
    338   // If we actually model the copy, we can make this known.
    339   // The important thing for now is that the old value has been invalidated.
    340   clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
    341 }
    342 
    343 void memmove1 () {
    344   char src[] = {1, 2, 3, 4};
    345   char dst[10];
    346 
    347   memmove(dst, src, 5); // expected-warning{{out-of-bound}}
    348 }
    349 
    350 void memmove2 () {
    351   char src[] = {1, 2, 3, 4};
    352   char dst[1];
    353 
    354   memmove(dst, src, 4); // expected-warning{{overflow}}
    355 }
    356 
    357 //===----------------------------------------------------------------------===
    358 // memcmp()
    359 //===----------------------------------------------------------------------===
    360 
    361 #ifdef VARIANT
    362 
    363 #define bcmp BUILTIN(bcmp)
    364 // __builtin_bcmp is not defined with const in Builtins.def.
    365 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
    366 #define memcmp bcmp
    367 //
    368 #else /* VARIANT */
    369 
    370 #define memcmp BUILTIN(memcmp)
    371 int memcmp(const void *s1, const void *s2, size_t n);
    372 
    373 #endif /* VARIANT */
    374 
    375 
    376 void memcmp0 () {
    377   char a[] = {1, 2, 3, 4};
    378   char b[4] = { 0 };
    379 
    380   memcmp(a, b, 4); // no-warning
    381 }
    382 
    383 void memcmp1 () {
    384   char a[] = {1, 2, 3, 4};
    385   char b[10] = { 0 };
    386 
    387   memcmp(a, b, 5); // expected-warning{{out-of-bound}}
    388 }
    389 
    390 void memcmp2 () {
    391   char a[] = {1, 2, 3, 4};
    392   char b[1] = { 0 };
    393 
    394   memcmp(a, b, 4); // expected-warning{{out-of-bound}}
    395 }
    396 
    397 void memcmp3 () {
    398   char a[] = {1, 2, 3, 4};
    399 
    400   clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
    401 }
    402 
    403 void memcmp4 (char *input) {
    404   char a[] = {1, 2, 3, 4};
    405 
    406   clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
    407 }
    408 
    409 void memcmp5 (char *input) {
    410   char a[] = {1, 2, 3, 4};
    411 
    412   clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
    413   clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
    414   clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
    415 }
    416 
    417 void memcmp6 (char *a, char *b, size_t n) {
    418   int result = memcmp(a, b, n);
    419   if (result != 0)
    420     clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
    421   // else
    422   //   analyzer_assert_unknown(n == 0);
    423 
    424   // We can't do the above comparison because n has already been constrained.
    425   // On one path n == 0, on the other n != 0.
    426 }
    427 
    428 int memcmp7 (char *a, size_t x, size_t y, size_t n) {
    429   // We used to crash when either of the arguments was unknown.
    430   return memcmp(a, &a[x*y], n) +
    431          memcmp(&a[x*y], a, n);
    432 }
    433 
    434 //===----------------------------------------------------------------------===
    435 // bcopy()
    436 //===----------------------------------------------------------------------===
    437 
    438 #define bcopy BUILTIN(bcopy)
    439 // __builtin_bcopy is not defined with const in Builtins.def.
    440 void bcopy(/*const*/ void *s1, void *s2, size_t n);
    441 
    442 
    443 void bcopy0 () {
    444   char src[] = {1, 2, 3, 4};
    445   char dst[4] = {0};
    446 
    447   bcopy(src, dst, 4); // no-warning
    448 
    449   // If we actually model the copy, we can make this known.
    450   // The important thing for now is that the old value has been invalidated.
    451   clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
    452 }
    453 
    454 void bcopy1 () {
    455   char src[] = {1, 2, 3, 4};
    456   char dst[10];
    457 
    458   bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
    459 }
    460 
    461 void bcopy2 () {
    462   char src[] = {1, 2, 3, 4};
    463   char dst[1];
    464 
    465   bcopy(src, dst, 4); // expected-warning{{overflow}}
    466 }
    467 
    468 void *malloc(size_t);
    469 void free(void *);
    470 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) {
    471   char *bytes = malloc(sizeof(char) * (length + 1));
    472   memcpy(bytes, input, length);
    473   char x = bytes[0]; // no warning
    474   free(bytes);
    475   return x;
    476 }
    477