From 1c64e617f57297e53abc3d48bedb5a4e3375f644 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Thu, 18 Jan 2018 00:50:19 +0000 Subject: [PATCH] [analyzer] operator new: Add a new ProgramPoint for check::NewAllocator. Add PostAllocatorCall program point to represent the moment in the analysis between the operator new() call and the constructor call. Pointer cast from "void *" to the correct object pointer type has already happened by this point. The new program point, unlike the previously used PostImplicitCall, contains a reference to the new-expression, which allows adding path diagnostics over it. Differential Revision: https://reviews.llvm.org/D41800 rdar://problem/12180598 llvm-svn: 322796 --- clang/include/clang/Analysis/ProgramPoint.h | 17 +++- .../StaticAnalyzer/Core/CheckerManager.cpp | 7 +- clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 3 +- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 2 + clang/test/Analysis/NewDelete-path-notes.cpp | 97 ++++++++++--------- 5 files changed, 70 insertions(+), 56 deletions(-) diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h index 2d59dec48a88..585dee3c9598 100644 --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -73,8 +73,9 @@ public: PostStoreKind, PostConditionKind, PostLValueKind, + PostAllocatorCallKind, MinPostStmtKind = PostStmtKind, - MaxPostStmtKind = PostLValueKind, + MaxPostStmtKind = PostAllocatorCallKind, PostInitializerKind, CallEnterKind, CallExitBeginKind, @@ -580,6 +581,20 @@ private: } }; +class PostAllocatorCall : public StmtPoint { +public: + PostAllocatorCall(const Stmt *S, const LocationContext *L, + const ProgramPointTag *Tag = nullptr) + : StmtPoint(S, nullptr, PostAllocatorCallKind, L, Tag) {} + +private: + friend class ProgramPoint; + PostAllocatorCall() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostAllocatorCallKind; + } +}; + /// Represents a point when we begin processing an inlined call. /// CallEnter uses the caller's location context. class CallEnter : public ProgramPoint { diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp index 360004bd67ec..f3de2e405000 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -488,12 +488,7 @@ namespace { void runChecker(CheckerManager::CheckNewAllocatorFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { - // TODO: Does this deserve a custom program point? For now we're re-using - // PostImplicitCall because we're guaranteed to use the non-implicit - // PostStmt for the PostCall callback, because we have some sort of - // call site (CXXNewExpr) in this scenario. - ProgramPoint L = PostImplicitCall(NE->getOperatorNew(), NE->getLocStart(), - Pred->getLocationContext()); + ProgramPoint L = PostAllocatorCall(NE, Pred->getLocationContext()); CheckerContext C(Bldr, Eng, Pred, L, WasInlined); checkFn(NE, Target, C); } diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index e2e9ddf5048e..392357450076 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -275,7 +275,8 @@ void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, Loc.getAs() || Loc.getAs() || Loc.getAs() || - Loc.getAs()); + Loc.getAs() || + Loc.getAs()); HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred); break; } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5851c98d8695..a01f362de325 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2930,6 +2930,8 @@ struct DOTGraphTraits : Out << "\\lPostStore\\l"; else if (Loc.getAs()) Out << "\\lPostLValue\\l"; + else if (Loc.getAs()) + Out << "\\lPostAllocatorCall\\l"; break; } diff --git a/clang/test/Analysis/NewDelete-path-notes.cpp b/clang/test/Analysis/NewDelete-path-notes.cpp index ac760ca60eb4..d57f67e71923 100644 --- a/clang/test/Analysis/NewDelete-path-notes.cpp +++ b/clang/test/Analysis/NewDelete-path-notes.cpp @@ -1,4 +1,5 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -analyzer-config c++-allocator-inlining=true -verify %s // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist // RUN: FileCheck --input-file=%t.plist %s @@ -40,12 +41,12 @@ void test(Odd *odd) { // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -53,12 +54,12 @@ void test(Odd *odd) { // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col14 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -70,7 +71,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -78,12 +79,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col18 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -103,12 +104,12 @@ void test(Odd *odd) { // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line6 +// CHECK-NEXT: line7 // CHECK-NEXT: col14 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -116,12 +117,12 @@ void test(Odd *odd) { // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line8 +// CHECK-NEXT: line9 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line8 +// CHECK-NEXT: line9 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -137,12 +138,12 @@ void test(Odd *odd) { // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line8 +// CHECK-NEXT: line9 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line8 +// CHECK-NEXT: line9 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -150,12 +151,12 @@ void test(Odd *odd) { // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col10 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -167,7 +168,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -175,12 +176,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -200,12 +201,12 @@ void test(Odd *odd) { // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line10 +// CHECK-NEXT: line11 // CHECK-NEXT: col10 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -213,12 +214,12 @@ void test(Odd *odd) { // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line13 +// CHECK-NEXT: line14 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line13 +// CHECK-NEXT: line14 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -230,7 +231,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line13 +// CHECK-NEXT: line14 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -238,12 +239,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line13 +// CHECK-NEXT: line14 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line13 +// CHECK-NEXT: line14 // CHECK-NEXT: col10 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -267,7 +268,7 @@ void test(Odd *odd) { // CHECK-NEXT: issue_hash_function_offset8 // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line13 +// CHECK-NEXT: line14 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -279,7 +280,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -287,12 +288,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -308,7 +309,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line18 +// CHECK-NEXT: line19 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -326,12 +327,12 @@ void test(Odd *odd) { // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line18 +// CHECK-NEXT: line19 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line18 +// CHECK-NEXT: line19 // CHECK-NEXT: col5 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -339,12 +340,12 @@ void test(Odd *odd) { // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line19 +// CHECK-NEXT: line20 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line19 +// CHECK-NEXT: line20 // CHECK-NEXT: col8 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -356,7 +357,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line19 +// CHECK-NEXT: line20 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -364,12 +365,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line19 +// CHECK-NEXT: line20 // CHECK-NEXT: col3 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line19 +// CHECK-NEXT: line20 // CHECK-NEXT: col13 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -385,7 +386,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -393,12 +394,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col12 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -418,12 +419,12 @@ void test(Odd *odd) { // CHECK-NEXT: start // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line24 +// CHECK-NEXT: line25 // CHECK-NEXT: col4 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -431,12 +432,12 @@ void test(Odd *odd) { // CHECK-NEXT: end // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line26 +// CHECK-NEXT: line27 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line26 +// CHECK-NEXT: line27 // CHECK-NEXT: col7 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -448,7 +449,7 @@ void test(Odd *odd) { // CHECK-NEXT: kindevent // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line26 +// CHECK-NEXT: line27 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -456,12 +457,12 @@ void test(Odd *odd) { // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line26 +// CHECK-NEXT: line27 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: line26 +// CHECK-NEXT: line27 // CHECK-NEXT: col11 // CHECK-NEXT: file0 // CHECK-NEXT: @@ -485,7 +486,7 @@ void test(Odd *odd) { // CHECK-NEXT: issue_hash_function_offset3 // CHECK-NEXT: location // CHECK-NEXT: -// CHECK-NEXT: line26 +// CHECK-NEXT: line27 // CHECK-NEXT: col2 // CHECK-NEXT: file0 // CHECK-NEXT: