diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-16 21:37:52 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-16 21:37:52 +0000 |
commit | e1962328f5ccd87d59bbc3237ac672af765ec8af (patch) | |
tree | ac4e1acd25a54188c81ac56a3f15af24b48439d6 | |
parent | 58ffdccab131475458abf409d604169653f79805 (diff) | |
download | bcm5719-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.cpp | 9 | ||||
-rw-r--r-- | clang/test/Analysis/misc-ps-region-store.cpp | 27 |
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; +} + |