summaryrefslogtreecommitdiff
path: root/clang/test/Analysis/out-of-bounds.c
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/out-of-bounds.c')
-rw-r--r--clang/test/Analysis/out-of-bounds.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/clang/test/Analysis/out-of-bounds.c b/clang/test/Analysis/out-of-bounds.c
new file mode 100644
index 0000000..a97bba5
--- /dev/null
+++ b/clang/test/Analysis/out-of-bounds.c
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,experimental.security.ArrayBoundV2 -verify %s
+
+// Tests doing an out-of-bounds access after the end of an array using:
+// - constant integer index
+// - constant integer size for buffer
+void test1(int x) {
+ int buf[100];
+ buf[100] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+void test1_ok(int x) {
+ int buf[100];
+ buf[99] = 1; // no-warning
+}
+
+const char test1_strings_underrun(int x) {
+ const char *mystr = "mary had a little lamb";
+ return mystr[-1]; // expected-warning{{Out of bound memory access}}
+}
+
+const char test1_strings_overrun(int x) {
+ const char *mystr = "mary had a little lamb";
+ return mystr[1000]; // expected-warning{{Out of bound memory access}}
+}
+
+const char test1_strings_ok(int x) {
+ const char *mystr = "mary had a little lamb";
+ return mystr[5]; // no-warning
+}
+
+// Tests doing an out-of-bounds access after the end of an array using:
+// - indirect pointer to buffer
+// - constant integer index
+// - constant integer size for buffer
+void test1_ptr(int x) {
+ int buf[100];
+ int *p = buf;
+ p[101] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+void test1_ptr_ok(int x) {
+ int buf[100];
+ int *p = buf;
+ p[99] = 1; // no-warning
+}
+
+// Tests doing an out-of-bounds access before the start of an array using:
+// - indirect pointer to buffer, manipulated using simple pointer arithmetic
+// - constant integer index
+// - constant integer size for buffer
+void test1_ptr_arith(int x) {
+ int buf[100];
+ int *p = buf;
+ p = p + 100;
+ p[0] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+void test1_ptr_arith_ok(int x) {
+ int buf[100];
+ int *p = buf;
+ p = p + 99;
+ p[0] = 1; // no-warning
+}
+
+void test1_ptr_arith_bad(int x) {
+ int buf[100];
+ int *p = buf;
+ p = p + 99;
+ p[1] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+void test1_ptr_arith_ok2(int x) {
+ int buf[100];
+ int *p = buf;
+ p = p + 99;
+ p[-1] = 1; // no-warning
+}
+
+// Tests doing an out-of-bounds access before the start of an array using:
+// - constant integer index
+// - constant integer size for buffer
+void test2(int x) {
+ int buf[100];
+ buf[-1] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+// Tests doing an out-of-bounds access before the start of an array using:
+// - indirect pointer to buffer
+// - constant integer index
+// - constant integer size for buffer
+void test2_ptr(int x) {
+ int buf[100];
+ int *p = buf;
+ p[-1] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+// Tests doing an out-of-bounds access before the start of an array using:
+// - indirect pointer to buffer, manipulated using simple pointer arithmetic
+// - constant integer index
+// - constant integer size for buffer
+void test2_ptr_arith(int x) {
+ int buf[100];
+ int *p = buf;
+ --p;
+ p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
+}
+
+// Tests doing an out-of-bounds access before the start of a multi-dimensional
+// array using:
+// - constant integer indices
+// - constant integer sizes for the array
+void test2_multi(int x) {
+ int buf[100][100];
+ buf[0][-1] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+// Tests doing an out-of-bounds access before the start of a multi-dimensional
+// array using:
+// - constant integer indices
+// - constant integer sizes for the array
+void test2_multi_b(int x) {
+ int buf[100][100];
+ buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
+}
+
+void test2_multi_ok(int x) {
+ int buf[100][100];
+ buf[0][0] = 1; // no-warning
+}
+
+// Testing if solver handles (symbol * constant) < constant
+void test3(int x) {
+ int buf[100];
+ if (x < 0)
+ buf[x] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
+}
+
+// *** FIXME ***
+// We don't get a warning here yet because our symbolic constraint solving
+// doesn't handle: (symbol * constant) < constant
+void test4(int x) {
+ int buf[100];
+ if (x > 99)
+ buf[x] = 1;
+}
+
+// Don't warn when indexing below the start of a symbolic region's whose
+// base extent we don't know.
+int *get_symbolic();
+void test_index_below_symboloc() {
+ int *buf = get_symbolic();
+ buf[-1] = 0; // no-warning;
+}
+