Author: rkovacs Date: Thu Aug 2 15:31:03 2018 New Revision: 338777 URL: http://llvm.org/viewvc/llvm-project?rev=338777&view=rev Log: [analyzer] Obtain a ReturnStmt from a CFGAutomaticObjDtor.
The CoreEngine only gives us a ReturnStmt if the last element in the CFGBlock is a CFGStmt, otherwise the ReturnStmt is nullptr. This patch adds support for the case when the last element is a CFGAutomaticObjDtor, by returning its TriggerStmt as a ReturnStmt. Differential Revision: https://reviews.llvm.org/D49811 Added: cfe/trunk/test/Analysis/end-function-return-stmt.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp?rev=338777&r1=338776&r2=338777&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp Thu Aug 2 15:31:03 2018 @@ -16,6 +16,7 @@ #include "ClangSACheckers.h" #include "clang/AST/ExprCXX.h" +#include "clang/Analysis/CFGStmtMap.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -37,6 +38,7 @@ class AnalysisOrderChecker check::PostStmt<OffsetOfExpr>, check::PreCall, check::PostCall, + check::EndFunction, check::NewAllocator, check::Bind, check::RegionChanges, @@ -121,6 +123,23 @@ public: } } + void checkEndFunction(const ReturnStmt *S, CheckerContext &C) const { + if (isCallbackEnabled(C, "EndFunction")) { + llvm::errs() << "EndFunction\nReturnStmt: " << (S ? "yes" : "no") << "\n"; + if (!S) + return; + + llvm::errs() << "CFGElement: "; + CFGStmtMap *Map = C.getCurrentAnalysisDeclContext()->getCFGStmtMap(); + CFGElement LastElement = Map->getBlock(S)->back(); + + if (LastElement.getAs<CFGStmt>()) + llvm::errs() << "CFGStmt\n"; + else if (LastElement.getAs<CFGAutomaticObjDtor>()) + llvm::errs() << "CFGAutomaticObjDtor\n"; + } + } + void checkNewAllocator(const CXXNewExpr *CNE, SVal Target, CheckerContext &C) const { if (isCallbackEnabled(C, "NewAllocator")) Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=338777&r1=338776&r2=338777&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Thu Aug 2 15:31:03 2018 @@ -223,8 +223,12 @@ void CoreEngine::HandleBlockEdge(const B // Get return statement.. const ReturnStmt *RS = nullptr; if (!L.getSrc()->empty()) { - if (Optional<CFGStmt> LastStmt = L.getSrc()->back().getAs<CFGStmt>()) { + CFGElement LastElement = L.getSrc()->back(); + if (Optional<CFGStmt> LastStmt = LastElement.getAs<CFGStmt>()) { RS = dyn_cast<ReturnStmt>(LastStmt->getStmt()); + } else if (Optional<CFGAutomaticObjDtor> AutoDtor = + LastElement.getAs<CFGAutomaticObjDtor>()) { + RS = dyn_cast<ReturnStmt>(AutoDtor->getTriggerStmt()); } } Added: cfe/trunk/test/Analysis/end-function-return-stmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/end-function-return-stmt.cpp?rev=338777&view=auto ============================================================================== --- cfe/trunk/test/Analysis/end-function-return-stmt.cpp (added) +++ cfe/trunk/test/Analysis/end-function-return-stmt.cpp Thu Aug 2 15:31:03 2018 @@ -0,0 +1,34 @@ +//RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:EndFunction=true %s 2>&1 | FileCheck %s + +// At the end of a function, we can only obtain a ReturnStmt if the last +// CFGElement in the CFGBlock is either a CFGStmt or a CFGAutomaticObjDtor. + +void noReturnStmt() {} + +struct S { + S(); + ~S(); +}; + +int dtorAfterReturnStmt() { + S s; + return 0; +} + +S endsWithReturnStmt() { + return S(); +} + +// endsWithReturnStmt() +// CHECK: EndFunction +// CHECK-NEXT: ReturnStmt: yes +// CHECK-NEXT: CFGElement: CFGStmt + +// dtorAfterReturnStmt() +// CHECK: EndFunction +// CHECK-NEXT: ReturnStmt: yes +// CHECK-NEXT: CFGElement: CFGAutomaticObjDtor + +// noReturnStmt() +// CHECK: EndFunction +// CHECK-NEXT: ReturnStmt: no _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits