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