Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.unix.CString -analyzer-store=region -Wno-null-dereference -verify %s
      2 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,experimental.unix.CString -analyzer-store=region -Wno-null-dereference -verify %s
      3 // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,experimental.unix.CString -analyzer-store=region -Wno-null-dereference -verify %s
      4 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,experimental.unix.CString -analyzer-store=region -Wno-null-dereference -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 //===----------------------------------------------------------------------===
     30 // memcpy()
     31 //===----------------------------------------------------------------------===
     32 
     33 #ifdef VARIANT
     34 
     35 #define __memcpy_chk BUILTIN(__memcpy_chk)
     36 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n,
     37                    size_t destlen);
     38 
     39 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1)
     40 
     41 #else /* VARIANT */
     42 
     43 #define memcpy BUILTIN(memcpy)
     44 void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
     45 
     46 #endif /* VARIANT */
     47 
     48 
     49 void memcpy0 () {
     50   char src[] = {1, 2, 3, 4};
     51   char dst[4] = {0};
     52 
     53   memcpy(dst, src, 4); // no-warning
     54 
     55   if (memcpy(dst, src, 4) != dst) {
     56     (void)*(char*)0; // no-warning
     57   }
     58 
     59   if (dst[0] != 0)
     60     (void)*(char*)0; // expected-warning{{null}}
     61 }
     62 
     63 void memcpy1 () {
     64   char src[] = {1, 2, 3, 4};
     65   char dst[10];
     66 
     67   memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
     68 }
     69 
     70 void memcpy2 () {
     71   char src[] = {1, 2, 3, 4};
     72   char dst[1];
     73 
     74   memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
     75 }
     76 
     77 void memcpy3 () {
     78   char src[] = {1, 2, 3, 4};
     79   char dst[3];
     80 
     81   memcpy(dst+1, src+2, 2); // no-warning
     82 }
     83 
     84 void memcpy4 () {
     85   char src[] = {1, 2, 3, 4};
     86   char dst[10];
     87 
     88   memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
     89 }
     90 
     91 void memcpy5() {
     92   char src[] = {1, 2, 3, 4};
     93   char dst[3];
     94 
     95   memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
     96 }
     97 
     98 void memcpy6() {
     99   int a[4] = {0};
    100   memcpy(a, a, 8); // expected-warning{{overlapping}}
    101 }
    102 
    103 void memcpy7() {
    104   int a[4] = {0};
    105   memcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
    106 }
    107 
    108 void memcpy8() {
    109   int a[4] = {0};
    110   memcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
    111 }
    112 
    113 void memcpy9() {
    114   int a[4] = {0};
    115   memcpy(a+2, a+1, 4); // no-warning
    116   memcpy(a+1, a+2, 4); // no-warning
    117 }
    118 
    119 void memcpy10() {
    120   char a[4] = {0};
    121   memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    122 }
    123 
    124 void memcpy11() {
    125   char a[4] = {0};
    126   memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    127 }
    128 
    129 void memcpy12() {
    130   char a[4] = {0};
    131   memcpy(0, a, 0); // no-warning
    132 }
    133 
    134 void memcpy13() {
    135   char a[4] = {0};
    136   memcpy(a, 0, 0); // no-warning
    137 }
    138 
    139 void memcpy_unknown_size (size_t n) {
    140   char a[4], b[4] = {1};
    141   if (memcpy(a, b, n) != a)
    142     (void)*(char*)0; // no-warning
    143 }
    144 
    145 void memcpy_unknown_size_warn (size_t n) {
    146   char a[4];
    147   if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
    148     (void)*(char*)0; // no-warning
    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   if (mempcpy(dst, src, 4) != &dst[4]) {
    178     (void)*(char*)0; // no-warning
    179   }
    180 
    181   if (dst[0] != 0)
    182     (void)*(char*)0; // expected-warning{{null}}
    183 }
    184 
    185 void mempcpy1 () {
    186   char src[] = {1, 2, 3, 4};
    187   char dst[10];
    188 
    189   mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}}
    190 }
    191 
    192 void mempcpy2 () {
    193   char src[] = {1, 2, 3, 4};
    194   char dst[1];
    195 
    196   mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
    197 }
    198 
    199 void mempcpy3 () {
    200   char src[] = {1, 2, 3, 4};
    201   char dst[3];
    202 
    203   mempcpy(dst+1, src+2, 2); // no-warning
    204 }
    205 
    206 void mempcpy4 () {
    207   char src[] = {1, 2, 3, 4};
    208   char dst[10];
    209 
    210   mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}}
    211 }
    212 
    213 void mempcpy5() {
    214   char src[] = {1, 2, 3, 4};
    215   char dst[3];
    216 
    217   mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
    218 }
    219 
    220 void mempcpy6() {
    221   int a[4] = {0};
    222   mempcpy(a, a, 8); // expected-warning{{overlapping}}
    223 }
    224 
    225 void mempcpy7() {
    226   int a[4] = {0};
    227   mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}}
    228 }
    229 
    230 void mempcpy8() {
    231   int a[4] = {0};
    232   mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}}
    233 }
    234 
    235 void mempcpy9() {
    236   int a[4] = {0};
    237   mempcpy(a+2, a+1, 4); // no-warning
    238   mempcpy(a+1, a+2, 4); // no-warning
    239 }
    240 
    241 void mempcpy10() {
    242   char a[4] = {0};
    243   mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    244 }
    245 
    246 void mempcpy11() {
    247   char a[4] = {0};
    248   mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
    249 }
    250 
    251 void mempcpy12() {
    252   char a[4] = {0};
    253   mempcpy(0, a, 0); // no-warning
    254 }
    255 
    256 void mempcpy13() {
    257   char a[4] = {0};
    258   mempcpy(a, 0, 0); // no-warning
    259 }
    260 
    261 void mempcpy_unknown_size_warn (size_t n) {
    262   char a[4];
    263   if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
    264     (void)*(char*)0; // no-warning
    265 }
    266 
    267 void mempcpy_unknownable_size (char *src, float n) {
    268   char a[4];
    269   // This used to crash because we don't model floats.
    270   mempcpy(a, src, (size_t)n);
    271 }
    272 
    273 //===----------------------------------------------------------------------===
    274 // memmove()
    275 //===----------------------------------------------------------------------===
    276 
    277 #ifdef VARIANT
    278 
    279 #define __memmove_chk BUILTIN(__memmove_chk)
    280 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen);
    281 
    282 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1)
    283 
    284 #else /* VARIANT */
    285 
    286 #define memmove BUILTIN(memmove)
    287 void *memmove(void *s1, const void *s2, size_t n);
    288 
    289 #endif /* VARIANT */
    290 
    291 
    292 void memmove0 () {
    293   char src[] = {1, 2, 3, 4};
    294   char dst[4] = {0};
    295 
    296   memmove(dst, src, 4); // no-warning
    297 
    298   if (memmove(dst, src, 4) != dst) {
    299     (void)*(char*)0; // no-warning
    300   }
    301 
    302   if (dst[0] != 0)
    303     (void)*(char*)0; // expected-warning{{null}}
    304 }
    305 
    306 void memmove1 () {
    307   char src[] = {1, 2, 3, 4};
    308   char dst[10];
    309 
    310   memmove(dst, src, 5); // expected-warning{{out-of-bound}}
    311 }
    312 
    313 void memmove2 () {
    314   char src[] = {1, 2, 3, 4};
    315   char dst[1];
    316 
    317   memmove(dst, src, 4); // expected-warning{{overflow}}
    318 }
    319 
    320 //===----------------------------------------------------------------------===
    321 // memcmp()
    322 //===----------------------------------------------------------------------===
    323 
    324 #ifdef VARIANT
    325 
    326 #define bcmp BUILTIN(bcmp)
    327 // __builtin_bcmp is not defined with const in Builtins.def.
    328 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
    329 #define memcmp bcmp
    330 
    331 #else /* VARIANT */
    332 
    333 #define memcmp BUILTIN(memcmp)
    334 int memcmp(const void *s1, const void *s2, size_t n);
    335 
    336 #endif /* VARIANT */
    337 
    338 
    339 void memcmp0 () {
    340   char a[] = {1, 2, 3, 4};
    341   char b[4] = { 0 };
    342 
    343   memcmp(a, b, 4); // no-warning
    344 }
    345 
    346 void memcmp1 () {
    347   char a[] = {1, 2, 3, 4};
    348   char b[10] = { 0 };
    349 
    350   memcmp(a, b, 5); // expected-warning{{out-of-bound}}
    351 }
    352 
    353 void memcmp2 () {
    354   char a[] = {1, 2, 3, 4};
    355   char b[1] = { 0 };
    356 
    357   memcmp(a, b, 4); // expected-warning{{out-of-bound}}
    358 }
    359 
    360 void memcmp3 () {
    361   char a[] = {1, 2, 3, 4};
    362 
    363   if (memcmp(a, a, 4))
    364     (void)*(char*)0; // no-warning
    365 }
    366 
    367 void memcmp4 (char *input) {
    368   char a[] = {1, 2, 3, 4};
    369 
    370   if (memcmp(a, input, 4))
    371     (void)*(char*)0; // expected-warning{{null}}
    372 }
    373 
    374 void memcmp5 (char *input) {
    375   char a[] = {1, 2, 3, 4};
    376 
    377   if (memcmp(a, 0, 0)) // no-warning
    378     (void)*(char*)0;   // no-warning
    379   if (memcmp(0, a, 0)) // no-warning
    380     (void)*(char*)0;   // no-warning
    381   if (memcmp(a, input, 0)) // no-warning
    382     (void)*(char*)0;   // no-warning
    383 }
    384 
    385 void memcmp6 (char *a, char *b, size_t n) {
    386   int result = memcmp(a, b, n);
    387   if (result != 0)
    388     return;
    389   if (n == 0)
    390     (void)*(char*)0; // expected-warning{{null}}
    391 }
    392 
    393 int memcmp7 (char *a, size_t x, size_t y, size_t n) {
    394   // We used to crash when either of the arguments was unknown.
    395   return memcmp(a, &a[x*y], n) +
    396          memcmp(&a[x*y], a, n);
    397 }
    398 
    399 //===----------------------------------------------------------------------===
    400 // bcopy()
    401 //===----------------------------------------------------------------------===
    402 
    403 #define bcopy BUILTIN(bcopy)
    404 // __builtin_bcopy is not defined with const in Builtins.def.
    405 void bcopy(/*const*/ void *s1, void *s2, size_t n);
    406 
    407 
    408 void bcopy0 () {
    409   char src[] = {1, 2, 3, 4};
    410   char dst[4] = {0};
    411 
    412   bcopy(src, dst, 4); // no-warning
    413 
    414   if (dst[0] != 0)
    415     (void)*(char*)0; // expected-warning{{null}}
    416 }
    417 
    418 void bcopy1 () {
    419   char src[] = {1, 2, 3, 4};
    420   char dst[10];
    421 
    422   bcopy(src, dst, 5); // expected-warning{{out-of-bound}}
    423 }
    424 
    425 void bcopy2 () {
    426   char src[] = {1, 2, 3, 4};
    427   char dst[1];
    428 
    429   bcopy(src, dst, 4); // expected-warning{{overflow}}
    430 }
    431