aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-09-28 17:15:12 +0000
committerJordan Rose <jordan_rose@apple.com>2012-09-28 17:15:12 +0000
commit6f61df3e7256413dcb99afb9673f4206e3c4992c (patch)
treed297501092690e7a5b0e044191966f655dc30960 /test
parentda3d76b4cfbb5ebeb79e03a0abeabd403fe9260a (diff)
[analyzer] Create a temporary region for rvalue structs when accessing fields
Struct rvalues are represented in the analyzer by CompoundVals, LazyCompoundVals, or plain ConjuredSymbols -- none of which have associated regions. If the entire structure is going to persist, this is not a problem -- either the rvalue will be assigned to an existing region, or a MaterializeTemporaryExpr will be present to create a temporary region. However, if we just need a field from the struct, we need to create the temporary region ourselves. This is inspired by the way CodeGen handles calls to temporaries; support for that in the analyzer is coming next. Part of <rdar://problem/12137950> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164828 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Analysis/fields.c11
-rw-r--r--test/Analysis/reference.cpp4
2 files changed, 11 insertions, 4 deletions
diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c
index a10d5a8060..a2b3dcf738 100644
--- a/test/Analysis/fields.c
+++ b/test/Analysis/fields.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core %s -analyzer-store=region -verify
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify
+
+void clang_analyzer_eval(int);
unsigned foo();
typedef struct bf { unsigned x:2; } bf;
@@ -33,3 +35,10 @@ void testNullAddress() {
int *px = &p->x; // expected-warning{{Access to field 'x' results in a dereference of a null pointer (loaded from variable 'p')}}
*px = 1; // No warning because analysis stops at the previous line.
}
+
+void testLazyCompoundVal() {
+ Point p = {42, 0};
+ Point q;
+ clang_analyzer_eval((q = p).x == 42); // expected-warning{{TRUE}}
+ clang_analyzer_eval(q.x == 42); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index 374f3f7261..ce0ee8ed57 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -116,10 +116,8 @@ void testReferenceAddress(int &x) {
struct S { int &x; };
- // FIXME: Should be TRUE. Fields of return-by-value structs are not yet
- // symbolicated. Tracked by <rdar://problem/12137950>.
extern S getS();
- clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}
extern S *getSP();
clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}}