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