Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -833,16 +833,15 @@ return; // First, find when we processed the statement. + const StackFrameContext *BeginSC = + Node->getLocationContext()->getStackFrame(); do { - if (auto CEE = Node->getLocationAs()) + if (Optional CEE = Node->getLocationAs()) if (CEE->getCalleeContext()->getCallSite() == S) break; - if (auto SP = Node->getLocationAs()) - if (SP->getStmt() == S) - break; Node = Node->getFirstPred(); - } while (Node); + } while (Node && Node->getLocationContext()->getStackFrame() == BeginSC); // Next, step over any post-statement checks. while (Node && Node->getLocation().getAs()) 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: -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core \ +// RUN: -DSUPPRESSED \ +// 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/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: -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;