182 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,security.ArrayBound -verify %s2 3// Test the interactions of `security.ArrayBound` with C++ features.4 5// Tests doing an out-of-bounds access after the end of an array using:6// - constant integer index7// - constant integer size for buffer8void test1(int x) {9 int *buf = new int[100];10 buf[100] = 1; // expected-warning{{Out of bound access to memory}}11}12 13void test1_ok(int x) {14 int *buf = new int[100];15 buf[99] = 1; // no-warning16}17 18// Tests doing an out-of-bounds access after the end of an array using:19// - indirect pointer to buffer20// - constant integer index21// - constant integer size for buffer22void test1_ptr(int x) {23 int *buf = new int[100];24 int *p = buf;25 p[101] = 1; // expected-warning{{Out of bound access to memory}}26}27 28void test1_ptr_ok(int x) {29 int *buf = new int[100];30 int *p = buf;31 p[99] = 1; // no-warning32}33 34// Tests doing an out-of-bounds access before the start of an array using:35// - indirect pointer to buffer, manipulated using simple pointer arithmetic36// - constant integer index37// - constant integer size for buffer38void test1_ptr_arith(int x) {39 int *buf = new int[100];40 int *p = buf;41 p = p + 100;42 p[0] = 1; // expected-warning{{Out of bound access to memory}}43}44 45void test1_ptr_arith_ok(int x) {46 int *buf = new int[100];47 int *p = buf;48 p = p + 99;49 p[0] = 1; // no-warning50}51 52void test1_ptr_arith_bad(int x) {53 int *buf = new int[100];54 int *p = buf;55 p = p + 99;56 p[1] = 1; // expected-warning{{Out of bound access to memory}}57}58 59void test1_ptr_arith_ok2(int x) {60 int *buf = new int[100];61 int *p = buf;62 p = p + 99;63 p[-1] = 1; // no-warning64}65 66// Tests doing an out-of-bounds access before the start of an array using:67// - constant integer index68// - constant integer size for buffer69void test2(int x) {70 int *buf = new int[100];71 buf[-1] = 1; // expected-warning{{Out of bound access to memory}}72}73 74// Tests doing an out-of-bounds access before the start of an array using:75// - indirect pointer to buffer76// - constant integer index77// - constant integer size for buffer78void test2_ptr(int x) {79 int *buf = new int[100];80 int *p = buf;81 p[-1] = 1; // expected-warning{{Out of bound access to memory}}82}83 84// Tests doing an out-of-bounds access before the start of an array using:85// - indirect pointer to buffer, manipulated using simple pointer arithmetic86// - constant integer index87// - constant integer size for buffer88void test2_ptr_arith(int x) {89 int *buf = new int[100];90 int *p = buf;91 --p;92 p[0] = 1; // expected-warning {{Out of bound access to memory preceding}}93}94 95// Tests under-indexing96// of a multi-dimensional array97void test2_multi(int x) {98 auto buf = new int[100][100];99 buf[0][-1] = 1; // expected-warning{{Out of bound access to memory}}100}101 102// Tests under-indexing103// of a multi-dimensional array104void test2_multi_b(int x) {105 auto buf = new int[100][100];106 buf[-1][0] = 1; // expected-warning{{Out of bound access to memory}}107}108 109// Tests over-indexing110// of a multi-dimensional array111void test2_multi_c(int x) {112 auto buf = new int[100][100];113 buf[100][0] = 1; // expected-warning{{Out of bound access to memory}}114}115 116// Tests over-indexing117// of a multi-dimensional array118void test2_multi_2(int x) {119 auto buf = new int[100][100];120 buf[99][100] = 1; // expected-warning{{Out of bound access to memory}}121}122 123// Tests normal access of124// a multi-dimensional array125void test2_multi_ok(int x) {126 auto buf = new int[100][100];127 buf[0][0] = 1; // no-warning128}129 130// Tests over-indexing using different types131// array132void test_diff_types(int x) {133 int *buf = new int[10]; //10*sizeof(int) Bytes allocated134 char *cptr = (char *)buf;135 cptr[sizeof(int) * 9] = 1; // no-warning136 cptr[sizeof(int) * 10] = 1; // expected-warning{{Out of bound access to memory}}137}138 139// Tests over-indexing140//if the allocated area is non-array141void test_non_array(int x) {142 int *ip = new int;143 ip[0] = 1; // no-warning144 ip[1] = 2; // expected-warning{{Out of bound access to memory}}145}146 147//Tests over-indexing148//if the allocated area size is a runtime parameter149void test_dynamic_size(int s) {150 int *buf = new int[s];151 buf[0] = 1; // no-warning152}153//Tests complex arithmetic154//in new expression155void test_dynamic_size2(unsigned m, unsigned n){156 unsigned *U = nullptr;157 U = new unsigned[m + n + 1];158}159 160//Test creating invalid references, which break the invariant that a reference161//is always holding a value, and could lead to nasty runtime errors.162int array[10] = {0};163 164void test_after_the_end_reference() {165 int &ref = array[10]; // expected-warning{{Out of bound access to memory}}166}167 168void test_after_after_the_end_reference() {169 int &ref = array[11]; // expected-warning{{Out of bound access to memory}}170}171 172int test_reference_that_might_be_after_the_end(int idx) {173 // This TC produces no warning because separate analysis of (idx == 10) is174 // only introduced _after_ the creation of the reference ref.175 if (idx < 0 || idx > 10)176 return -2;177 int &ref = array[idx];178 if (idx == 10)179 return -1;180 return ref;181}182