Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
      2 
      3 // Tests doing an out-of-bounds access after the end of an array using:
      4 // - constant integer index
      5 // - constant integer size for buffer
      6 void test1(int x) {
      7   int buf[100];
      8   buf[100] = 1; // expected-warning{{Out of bound memory access}}
      9 }
     10 
     11 void test1_ok(int x) {
     12   int buf[100];
     13   buf[99] = 1; // no-warning
     14 }
     15 
     16 const char test1_strings_underrun(int x) {
     17   const char *mystr = "mary had a little lamb";
     18   return mystr[-1]; // expected-warning{{Out of bound memory access}}
     19 }
     20 
     21 const char test1_strings_overrun(int x) {
     22   const char *mystr = "mary had a little lamb";
     23   return mystr[1000];  // expected-warning{{Out of bound memory access}}
     24 }
     25 
     26 const char test1_strings_ok(int x) {
     27   const char *mystr = "mary had a little lamb";
     28   return mystr[5]; // no-warning
     29 }
     30 
     31 // Tests doing an out-of-bounds access after the end of an array using:
     32 // - indirect pointer to buffer
     33 // - constant integer index
     34 // - constant integer size for buffer
     35 void test1_ptr(int x) {
     36   int buf[100];
     37   int *p = buf;
     38   p[101] = 1; // expected-warning{{Out of bound memory access}}
     39 }
     40 
     41 void test1_ptr_ok(int x) {
     42   int buf[100];
     43   int *p = buf;
     44   p[99] = 1; // no-warning
     45 }
     46 
     47 // Tests doing an out-of-bounds access before the start of an array using:
     48 // - indirect pointer to buffer, manipulated using simple pointer arithmetic
     49 // - constant integer index
     50 // - constant integer size for buffer
     51 void test1_ptr_arith(int x) {
     52   int buf[100];
     53   int *p = buf;
     54   p = p + 100;
     55   p[0] = 1; // expected-warning{{Out of bound memory access}}
     56 }
     57 
     58 void test1_ptr_arith_ok(int x) {
     59   int buf[100];
     60   int *p = buf;
     61   p = p + 99;
     62   p[0] = 1; // no-warning
     63 }
     64 
     65 void test1_ptr_arith_bad(int x) {
     66   int buf[100];
     67   int *p = buf;
     68   p = p + 99;
     69   p[1] = 1; // expected-warning{{Out of bound memory access}}
     70 }
     71 
     72 void test1_ptr_arith_ok2(int x) {
     73   int buf[100];
     74   int *p = buf;
     75   p = p + 99;
     76   p[-1] = 1; // no-warning
     77 }
     78 
     79 // Tests doing an out-of-bounds access before the start of an array using:
     80 // - constant integer index
     81 // - constant integer size for buffer
     82 void test2(int x) {
     83   int buf[100];
     84   buf[-1] = 1; // expected-warning{{Out of bound memory access}}
     85 }
     86 
     87 // Tests doing an out-of-bounds access before the start of an array using:
     88 // - indirect pointer to buffer
     89 // - constant integer index
     90 // - constant integer size for buffer
     91 void test2_ptr(int x) {
     92   int buf[100];
     93   int *p = buf;
     94   p[-1] = 1; // expected-warning{{Out of bound memory access}}
     95 }
     96 
     97 // Tests doing an out-of-bounds access before the start of an array using:
     98 // - indirect pointer to buffer, manipulated using simple pointer arithmetic
     99 // - constant integer index
    100 // - constant integer size for buffer
    101 void test2_ptr_arith(int x) {
    102   int buf[100];
    103   int *p = buf;
    104   --p;
    105   p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
    106 }
    107 
    108 // Tests doing an out-of-bounds access before the start of a multi-dimensional
    109 // array using:
    110 // - constant integer indices
    111 // - constant integer sizes for the array
    112 void test2_multi(int x) {
    113   int buf[100][100];
    114   buf[0][-1] = 1; // expected-warning{{Out of bound memory access}}
    115 }
    116 
    117 // Tests doing an out-of-bounds access before the start of a multi-dimensional
    118 // array using:
    119 // - constant integer indices
    120 // - constant integer sizes for the array
    121 void test2_multi_b(int x) {
    122   int buf[100][100];
    123   buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
    124 }
    125 
    126 void test2_multi_ok(int x) {
    127   int buf[100][100];
    128   buf[0][0] = 1; // no-warning
    129 }
    130 
    131 // *** FIXME ***
    132 // We don't get a warning here yet because our symbolic constraint solving
    133 // doesn't handle:  (symbol * constant) < constant
    134 void test3(int x) {
    135   int buf[100];
    136   if (x < 0)
    137     buf[x] = 1;
    138 }
    139 
    140 // *** FIXME ***
    141 // We don't get a warning here yet because our symbolic constraint solving
    142 // doesn't handle:  (symbol * constant) < constant
    143 void test4(int x) {
    144   int buf[100];
    145   if (x > 99)
    146     buf[x] = 1;
    147 }
    148 
    149 // Don't warn when indexing below the start of a symbolic region's whose
    150 // base extent we don't know.
    151 int *get_symbolic();
    152 void test_index_below_symboloc() {
    153   int *buf = get_symbolic();
    154   buf[-1] = 0; // no-warning;
    155 }
    156 
    157 void test_incomplete_struct() {
    158   extern struct incomplete incomplete;
    159   int *p = (int *)&incomplete;
    160   p[1] = 42; // no-warning
    161 }
    162 
    163 void test_extern_void() {
    164   extern void v;
    165   int *p = (int *)&v;
    166   p[1] = 42; // no-warning
    167 }
    168 
    169