1cdc3a89d5de90b2299c56f4a46c3de590c5184d1Ted Kremenek// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
2c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
3c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access after the end of an array using:
4c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index
5c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer
6c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1(int x) {
7c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
8c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  buf[100] = 1; // expected-warning{{Out of bound memory access}}
9c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
10c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
11c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ok(int x) {
12c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
13c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  buf[99] = 1; // no-warning
14c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
15c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
1615a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenekconst char test1_strings_underrun(int x) {
1715a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  const char *mystr = "mary had a little lamb";
1815a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  return mystr[-1]; // expected-warning{{Out of bound memory access}}
1915a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek}
2015a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek
2115a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenekconst char test1_strings_overrun(int x) {
2215a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  const char *mystr = "mary had a little lamb";
2315a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  return mystr[1000];  // expected-warning{{Out of bound memory access}}
2415a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek}
2515a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek
2615a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenekconst char test1_strings_ok(int x) {
2715a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  const char *mystr = "mary had a little lamb";
2815a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  return mystr[5]; // no-warning
2915a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek}
3015a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek
31c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access after the end of an array using:
32c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer
33c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index
34c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer
35c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr(int x) {
36c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
37c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
38c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  p[101] = 1; // expected-warning{{Out of bound memory access}}
39c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
40c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
41c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_ok(int x) {
42c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
43c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
4415a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  p[99] = 1; // no-warning
45c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
46c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
47c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using:
48c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer, manipulated using simple pointer arithmetic
49c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index
50c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer
51c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith(int x) {
52c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
53c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
54c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  p = p + 100;
55a6b0b96e5376cd9cf182a3e240e0537feed43cdeTed Kremenek  p[0] = 1; // expected-warning{{Out of bound memory access}}
56c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
57c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
58c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith_ok(int x) {
59c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
60c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
61c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  p = p + 99;
62c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  p[0] = 1; // no-warning
63c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
64c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
65c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith_bad(int x) {
66c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
67c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
68c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  p = p + 99;
69a6b0b96e5376cd9cf182a3e240e0537feed43cdeTed Kremenek  p[1] = 1; // expected-warning{{Out of bound memory access}}
70c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
71c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
72c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test1_ptr_arith_ok2(int x) {
73c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
74c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
7515a467e9e8e9bee54c9d03305b4009e530c6ba4aTed Kremenek  p = p + 99;
76a6b0b96e5376cd9cf182a3e240e0537feed43cdeTed Kremenek  p[-1] = 1; // no-warning
77c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
78c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
79c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using:
80c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index
81c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer
82c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2(int x) {
83c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
84c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  buf[-1] = 1; // expected-warning{{Out of bound memory access}}
85c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
86c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
87c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using:
88c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer
89c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index
90c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer
91c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_ptr(int x) {
92c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
93c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
94c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  p[-1] = 1; // expected-warning{{Out of bound memory access}}
95c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
96c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
97c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of an array using:
98c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - indirect pointer to buffer, manipulated using simple pointer arithmetic
99c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer index
100c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer size for buffer
101c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_ptr_arith(int x) {
102c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
103c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int *p = buf;
104c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  --p;
105882998923889a2fcce9b49696506c499e22cf38fTed Kremenek  p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}}
106c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
107c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
108c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of a multi-dimensional
109c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// array using:
110c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer indices
111c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer sizes for the array
112c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_multi(int x) {
113c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100][100];
114c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  buf[0][-1] = 1; // expected-warning{{Out of bound memory access}}
115c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
116c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
117c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// Tests doing an out-of-bounds access before the start of a multi-dimensional
118c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// array using:
119c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer indices
120c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// - constant integer sizes for the array
121c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_multi_b(int x) {
122c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100][100];
123c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  buf[-1][0] = 1; // expected-warning{{Out of bound memory access}}
124c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
125c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
126c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test2_multi_ok(int x) {
127c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100][100];
128c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  buf[0][0] = 1; // no-warning
129c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
130c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
1311d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose// *** FIXME ***
1321d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose// We don't get a warning here yet because our symbolic constraint solving
1331d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose// doesn't handle:  (symbol * constant) < constant
134c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test3(int x) {
135c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
136c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  if (x < 0)
1371d8db493f86761df9470254a2ad572fc6abf1bf6Jordy Rose    buf[x] = 1;
138c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
139c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek
140c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// *** FIXME ***
141c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// We don't get a warning here yet because our symbolic constraint solving
142c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek// doesn't handle:  (symbol * constant) < constant
143c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenekvoid test4(int x) {
144c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  int buf[100];
145c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek  if (x > 99)
146c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek    buf[x] = 1;
147c478a1425c055e517169220ea1c1efd857e65f52Ted Kremenek}
14882cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek
14982cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek// Don't warn when indexing below the start of a symbolic region's whose
15082cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek// base extent we don't know.
15182cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenekint *get_symbolic();
15282cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenekvoid test_index_below_symboloc() {
15382cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek  int *buf = get_symbolic();
15482cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek  buf[-1] = 0; // no-warning;
15582cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek}
15682cfc6849204b07e80f8ac71e33247f7df760032Ted Kremenek
157