Charusso updated this revision to Diff 203635.
Charusso marked 2 inline comments as done.
Charusso added a comment.
- Added `CallExpr` as being purged away
- More test
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D62926/new/
https://reviews.llvm.org/D62926
Files:
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
clang/test/Analysis/new-ctor-null-throw.cpp
clang/test/Analysis/new-ctor-null.cpp
Index: clang/test/Analysis/new-ctor-null.cpp
===================================================================
--- clang/test/Analysis/new-ctor-null.cpp
+++ clang/test/Analysis/new-ctor-null.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-allocator-inlining=true -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 \
+// RUN: -analyzer-checker=core,debug.ExprInspection \
+// RUN: -std=c++11 -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_warnIfReached();
@@ -24,7 +26,8 @@
void testArrays() {
S *s = new S[10]; // no-crash
- s[0].x = 2; // expected-warning{{Dereference of null pointer}}
+ s[0].x = 2;
+ // no-warning: 'Dereference of null pointer' suppressed by ReturnVisitor.
}
int global;
Index: clang/test/Analysis/new-ctor-null-throw.cpp
===================================================================
--- clang/test/Analysis/new-ctor-null-throw.cpp
+++ clang/test/Analysis/new-ctor-null-throw.cpp
@@ -1,4 +1,9 @@
-// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-allocator-inlining=true -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core \
+// RUN: -analyzer-config suppress-null-return-paths=false \
+// RUN: -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core \
+// RUN: -DSUPPRESSED=1 \
+// RUN: -verify %s
void clang_analyzer_eval(bool);
@@ -9,18 +14,41 @@
// operator new.
void *operator new(size_t size) {
return nullptr;
+ // expected-warning@-1 {{'operator new' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
}
void *operator new[](size_t size) {
return nullptr;
+ // expected-warning@-1 {{'operator new[]' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
}
struct S {
int x;
S() : x(1) {}
~S() {}
+ int getX() const { return x; }
};
void testArrays() {
S *s = new S[10]; // no-crash
- s[0].x = 2; // expected-warning{{Dereference of null pointer}}
+ s[0].x = 2;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Dereference of null pointer}}
+#endif
}
+
+void testCtor() {
+ S *s = new S();
+ s->x = 13;
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Access to field 'x' results in a dereference of a null pointer (loaded from variable 's')}}
+#endif
+}
+
+void testMethod() {
+ S *s = new S();
+ const int X = s->getX();
+#ifndef SUPPRESSED
+ // expected-warning@-2 {{Called C++ object pointer is null}}
+#endif
+}
+
Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -833,13 +833,20 @@
return;
// First, find when we processed the statement.
+ // If we have one of the following cases that is going to be purged away
+ // before its call take place. We would catch that purge in the second
+ // condition as a 'StmtPoint' so we have to bypass it.
+ const bool IsBypass =
+ isa<CXXNewExpr>(S) || isa<CXXConstructExpr>(S) || isa<CallExpr>(S);
do {
- if (auto CEE = Node->getLocationAs<CallExitEnd>())
+ if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>())
if (CEE->getCalleeContext()->getCallSite() == S)
break;
- if (auto SP = Node->getLocationAs<StmtPoint>())
- if (SP->getStmt() == S)
- break;
+
+ if (!IsBypass)
+ if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>())
+ if (SP->getStmt() == S)
+ break;
Node = Node->getFirstPred();
} while (Node);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits