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