aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-03-15 21:41:46 +0000
committerJordan Rose <jordan_rose@apple.com>2013-03-15 21:41:46 +0000
commit6a15f39a6bfd7a30085c5fa8f67d0b64b74b132a (patch)
tree2a9560eee7b733b1a21f27f93342321032bd330b
parent62bbe07f5aed5a2f9ae55ef480c4268cb4435d99 (diff)
[analyzer] Look through ExprWhenCleanups when trying to track a NULL.
Silences a few false positives in LLVM. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177186 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp3
-rw-r--r--test/Analysis/inlining/false-positive-suppression.cpp46
2 files changed, 43 insertions, 6 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 8cd3eecf2b..bf616b1d26 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -778,7 +778,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
if (!S || !N)
return false;
- // Peel off OpaqueValueExpr.
+ if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S))
+ S = EWC->getSubExpr();
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
S = OVE->getSourceExpr();
diff --git a/test/Analysis/inlining/false-positive-suppression.cpp b/test/Analysis/inlining/false-positive-suppression.cpp
index 613f421110..02782c3f23 100644
--- a/test/Analysis/inlining/false-positive-suppression.cpp
+++ b/test/Analysis/inlining/false-positive-suppression.cpp
@@ -40,6 +40,11 @@ inline void* operator new(__typeof__(sizeof(int)), void* __p) throw()
extern bool coin();
+class SomeClass {
+public:
+ void doSomething();
+};
+
namespace References {
class Map {
int *&getNewBox();
@@ -83,11 +88,6 @@ namespace References {
*box = 1; // expected-warning {{Dereference of null pointer}}
}
- class SomeClass {
- public:
- void doSomething();
- };
-
SomeClass *&getSomeClass() {
if (coin()) {
extern SomeClass *&opaqueClass();
@@ -174,3 +174,39 @@ void test3() {
}
+namespace Cleanups {
+ class NonTrivial {
+ public:
+ ~NonTrivial();
+
+ SomeClass *getNull() {
+ return 0;
+ }
+ };
+
+ void testImmediate() {
+ NonTrivial().getNull()->doSomething();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+ }
+
+ void testAssignment() {
+ SomeClass *ptr = NonTrivial().getNull();
+ ptr->doSomething();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+ }
+
+ void testArgumentHelper(SomeClass *arg) {
+ arg->doSomething();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+ }
+
+ void testArgument() {
+ testArgumentHelper(NonTrivial().getNull());
+ }
+}