diff options
author | Csaba Dabis <dabis.csaba98@gmail.com> | 2019-06-15 10:05:49 +0000 |
---|---|---|
committer | Csaba Dabis <dabis.csaba98@gmail.com> | 2019-06-15 10:05:49 +0000 |
commit | 077f13c612c2e319878f2ce359dad7e9f4fb017e (patch) | |
tree | 19a533fa20573a7b9c6467c2fa2de9e137fd7c86 /clang/lib | |
parent | 8550fb386a367f15987019f7fa00c843dfde6a97 (diff) | |
download | bcm5719-llvm-077f13c612c2e319878f2ce359dad7e9f4fb017e.tar.gz bcm5719-llvm-077f13c612c2e319878f2ce359dad7e9f4fb017e.zip |
[analyzer] ReturnVisitor: Bypass everything to see inlined calls
Summary:
When we traversed backwards on ExplodedNodes to see where processed the
given statement we `break` too early. With the current approach we do not
miss the CallExitEnd ProgramPoint which stands for an inlined call.
Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus
Reviewed By: NoQ
Subscribers: szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy,
dkrupp, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62926
llvm-svn: 363491
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 9aaf050d477..469dd1d3c06 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -841,16 +841,38 @@ public: return; // First, find when we processed the statement. + // If we work with a 'CXXNewExpr' that is going to be purged away before + // its call take place. We would catch that purge in the last condition + // as a 'StmtPoint' so we have to bypass it. + const bool BypassCXXNewExprEval = isa<CXXNewExpr>(S); + + // This is moving forward when we enter into another context. + const StackFrameContext *CurrentSFC = Node->getStackFrame(); + do { - if (auto CEE = Node->getLocationAs<CallExitEnd>()) + // If that is satisfied we found our statement as an inlined call. + if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>()) if (CEE->getCalleeContext()->getCallSite() == S) break; - if (auto SP = Node->getLocationAs<StmtPoint>()) - if (SP->getStmt() == S) - break; + // Try to move forward to the end of the call-chain. Node = Node->getFirstPred(); - } while (Node); + if (!Node) + break; + + const StackFrameContext *PredSFC = Node->getStackFrame(); + + // If that is satisfied we found our statement. + // FIXME: This code currently bypasses the call site for the + // conservatively evaluated allocator. + if (!BypassCXXNewExprEval) + if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>()) + // See if we do not enter into another context. + if (SP->getStmt() == S && CurrentSFC == PredSFC) + break; + + CurrentSFC = PredSFC; + } while (Node->getStackFrame() == CurrentSFC); // Next, step over any post-statement checks. while (Node && Node->getLocation().getAs<PostStmt>()) |