aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/array-struct-region.c
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-08 18:23:27 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-08 18:23:27 +0000
commite0d24eb1060a213ec9820dc02c45f26b2d5b348b (patch)
tree063bded676a959bc997b45741ec74f541aed7b59 /test/Analysis/array-struct-region.c
parent2aa800a955132d83a666bcd52d3d59d09cffc079 (diff)
[analyzer] Revamp RegionStore to distinguish regions with symbolic offsets.
RegionStore currently uses a (Region, Offset) pair to describe the locations of memory bindings. However, this representation breaks down when we have regions like 'array[index]', where 'index' is unknown. We used to store this as (SubRegion, 0); now we mark them specially as (SubRegion, SYMBOLIC). Furthermore, ProgramState::scanReachableSymbols depended on the existence of a sub-region map, but RegionStore's implementation doesn't provide for such a thing. Moving the store-traversing logic of scanReachableSymbols into the StoreManager allows us to eliminate the notion of SubRegionMap altogether. This fixes some particularly awkward broken test cases, now in array-struct-region.c. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161510 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/array-struct-region.c')
-rw-r--r--test/Analysis/array-struct-region.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
index c452709832..244bc977b5 100644
--- a/test/Analysis/array-struct-region.c
+++ b/test/Analysis/array-struct-region.c
@@ -92,3 +92,95 @@ float struct_in_struct_f() {
return c.r; // no-warning
}
+
+int randomInt();
+
+int testSymbolicInvalidation(int index) {
+ int vals[10];
+
+ vals[0] = 42;
+ clang_analyzer_eval(vals[0] == 42); // expected-warning{{TRUE}}
+
+ vals[index] = randomInt();
+ clang_analyzer_eval(vals[0] == 42); // expected-warning{{UNKNOWN}}
+
+ return vals[index]; // no-warning
+}
+
+int testConcreteInvalidation(int index) {
+ int vals[10];
+
+ vals[index] = 42;
+ clang_analyzer_eval(vals[index] == 42); // expected-warning{{TRUE}}
+ vals[0] = randomInt();
+ clang_analyzer_eval(vals[index] == 42); // expected-warning{{UNKNOWN}}
+
+ return vals[0]; // no-warning
+}
+
+
+typedef struct {
+ int x, y, z;
+} S;
+
+S makeS();
+
+int testSymbolicInvalidationStruct(int index) {
+ S vals[10];
+
+ vals[0].x = 42;
+ clang_analyzer_eval(vals[0].x == 42); // expected-warning{{TRUE}}
+
+ vals[index] = makeS();
+ clang_analyzer_eval(vals[0].x == 42); // expected-warning{{UNKNOWN}}
+
+ return vals[index].x; // no-warning
+}
+
+int testConcreteInvalidationStruct(int index) {
+ S vals[10];
+
+ vals[index].x = 42;
+ clang_analyzer_eval(vals[index].x == 42); // expected-warning{{TRUE}}
+ vals[0] = makeS();
+ clang_analyzer_eval(vals[index].x == 42); // expected-warning{{UNKNOWN}}
+
+ return vals[0].x; // no-warning
+}
+
+typedef struct {
+ S a[5];
+ S b[5];
+} SS;
+
+int testSymbolicInvalidationDoubleStruct(int index) {
+ SS vals;
+
+ vals.a[0].x = 42;
+ vals.b[0].x = 42;
+ clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}}
+
+ vals.a[index] = makeS();
+ clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}}
+
+ return vals.b[index].x; // no-warning
+}
+
+int testConcreteInvalidationDoubleStruct(int index) {
+ SS vals;
+
+ vals.a[index].x = 42;
+ vals.b[index].x = 42;
+ clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}}
+
+ vals.a[0] = makeS();
+ clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}}
+
+ return vals.b[0].x; // no-warning
+}
+
+