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 6void test1(int x) { 7 int buf[100]; 8 buf[100] = 1; // expected-warning{{Out of bound memory access}} 9} 10 11void test1_ok(int x) { 12 int buf[100]; 13 buf[99] = 1; // no-warning 14} 15 16const 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 21const 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 26const 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 35void 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 41void 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 51void 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 58void 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 65void 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 72void 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 82void 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 91void 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 101void 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 112void 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 121void test2_multi_b(int x) { 122 int buf[100][100]; 123 buf[-1][0] = 1; // expected-warning{{Out of bound memory access}} 124} 125 126void 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 134void 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 143void 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. 151int *get_symbolic(); 152void test_index_below_symboloc() { 153 int *buf = get_symbolic(); 154 buf[-1] = 0; // no-warning; 155} 156 157