summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-08-16 21:37:52 +0000
committerTed Kremenek <kremenek@apple.com>2011-08-16 21:37:52 +0000
commite1962328f5ccd87d59bbc3237ac672af765ec8af (patch)
treeac4e1acd25a54188c81ac56a3f15af24b48439d6
parent58ffdccab131475458abf409d604169653f79805 (diff)
downloadbcm5719-llvm-e1962328f5ccd87d59bbc3237ac672af765ec8af.tar.gz
bcm5719-llvm-e1962328f5ccd87d59bbc3237ac672af765ec8af.zip
[analyzer] teach ExprEngine about loads from static C++ class fields. Fixes <rdar://problem/9948787>.
llvm-svn: 137760
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp9
-rw-r--r--clang/test/Analysis/misc-ps-region-store.cpp27
2 files changed, 35 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 1ea90047fac..916734b4e71 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1380,7 +1380,14 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
- FieldDecl *field = dyn_cast<FieldDecl>(M->getMemberDecl());
+ Decl *member = M->getMemberDecl();
+ if (VarDecl *VD = dyn_cast<VarDecl>(member)) {
+ assert(M->isLValue());
+ VisitCommonDeclRefExpr(M, VD, Pred, Dst);
+ return;
+ }
+
+ FieldDecl *field = dyn_cast<FieldDecl>(member);
if (!field) // FIXME: skipping member expressions for non-fields
return;
diff --git a/clang/test/Analysis/misc-ps-region-store.cpp b/clang/test/Analysis/misc-ps-region-store.cpp
index f27b910e1ad..1d055d59686 100644
--- a/clang/test/Analysis/misc-ps-region-store.cpp
+++ b/clang/test/Analysis/misc-ps-region-store.cpp
@@ -414,3 +414,30 @@ void TestAssignIntoSymbolicOffset::test(int x, int y) {
}
}
+// Test loads from static fields. This previously triggered an uninitialized
+// value warning.
+class ClassWithStatic {
+public:
+ static const unsigned value = 1;
+};
+
+int rdar9948787_negative() {
+ ClassWithStatic classWithStatic;
+ unsigned value = classWithStatic.value;
+ if (value == 1)
+ return 1;
+ int *p = 0;
+ *p = 0xDEADBEEF; // no-warning
+ return 0;
+}
+
+int rdar9948787_positive() {
+ ClassWithStatic classWithStatic;
+ unsigned value = classWithStatic.value;
+ if (value == 0)
+ return 1;
+ int *p = 0;
+ *p = 0xDEADBEEF; // expected-warning {{null}}
+ return 0;
+}
+
OpenPOWER on IntegriCloud