r342768 - [analyzer] Associate diagnostics created in checkEndFunction with a return statement, if possible
George Karpenkov via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 21 13:36:42 PDT 2018
Author: george.karpenkov
Date: Fri Sep 21 13:36:41 2018
New Revision: 342768
URL: http://llvm.org/viewvc/llvm-project?rev=342768&view=rev
Log:
[analyzer] Associate diagnostics created in checkEndFunction with a return statement, if possible
If not possible, use the last line of the declaration, as before.
Differential Revision: https://reviews.llvm.org/D52326
Modified:
cfe/trunk/include/clang/Analysis/ProgramPoint.h
cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
cfe/trunk/test/Analysis/inner-pointer.cpp
cfe/trunk/test/Analysis/malloc-free-after-return.cpp
Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=342768&r1=342767&r2=342768&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Fri Sep 21 13:36:41 2018
@@ -80,6 +80,7 @@ public:
CallEnterKind,
CallExitBeginKind,
CallExitEndKind,
+ FunctionExitKind,
PreImplicitCallKind,
PostImplicitCallKind,
MinImplicitCallKind = PreImplicitCallKind,
@@ -329,6 +330,29 @@ private:
}
};
+class FunctionExitPoint : public ProgramPoint {
+public:
+ explicit FunctionExitPoint(const ReturnStmt *S,
+ const LocationContext *LC,
+ const ProgramPointTag *tag = nullptr)
+ : ProgramPoint(S, FunctionExitKind, LC, tag) {}
+
+ const CFGBlock *getBlock() const {
+ return &getLocationContext()->getCFG()->getExit();
+ }
+
+ const ReturnStmt *getStmt() const {
+ return reinterpret_cast<const ReturnStmt *>(getData1());
+ }
+
+private:
+ friend class ProgramPoint;
+ FunctionExitPoint() = default;
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == FunctionExitKind;
+ }
+};
+
// PostCondition represents the post program point of a branch condition.
class PostCondition : public PostStmt {
public:
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=342768&r1=342767&r2=342768&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Fri Sep 21 13:36:41 2018
@@ -446,9 +446,8 @@ void CheckerManager::runCheckersForEndFu
// autotransition for it.
NodeBuilder Bldr(Pred, Dst, BC);
for (const auto checkFn : EndFunctionCheckers) {
- const ProgramPoint &L = BlockEntrance(BC.Block,
- Pred->getLocationContext(),
- checkFn.Checker);
+ const ProgramPoint &L =
+ FunctionExitPoint(RS, Pred->getLocationContext(), checkFn.Checker);
CheckerContext C(Bldr, Eng, Pred, L);
checkFn(RS, C);
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=342768&r1=342767&r2=342768&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Sep 21 13:36:41 2018
@@ -2984,6 +2984,17 @@ struct DOTGraphTraits<ExplodedGraph*> :
<< Loc.castAs<BlockEntrance>().getBlock()->getBlockID();
break;
+ case ProgramPoint::FunctionExitKind: {
+ auto FEP = Loc.getAs<FunctionExitPoint>();
+ Out << "Function Exit: B"
+ << FEP->getBlock()->getBlockID();
+ if (const ReturnStmt *RS = FEP->getStmt()) {
+ Out << "\\l Return: S" << RS->getID(Context) << "\\l";
+ RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),
+ /*Indentation=*/2, /*NewlineSymbol=*/"\\l");
+ }
+ break;
+ }
case ProgramPoint::BlockExitKind:
assert(false);
break;
Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=342768&r1=342767&r2=342768&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Fri Sep 21 13:36:41 2018
@@ -774,18 +774,20 @@ const Stmt *PathDiagnosticLocation::getS
}
// Otherwise, see if the node's program point directly points to a statement.
ProgramPoint P = N->getLocation();
- if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
+ if (auto SP = P.getAs<StmtPoint>())
return SP->getStmt();
- if (Optional<BlockEdge> BE = P.getAs<BlockEdge>())
+ if (auto BE = P.getAs<BlockEdge>())
return BE->getSrc()->getTerminator();
- if (Optional<CallEnter> CE = P.getAs<CallEnter>())
+ if (auto CE = P.getAs<CallEnter>())
return CE->getCallExpr();
- if (Optional<CallExitEnd> CEE = P.getAs<CallExitEnd>())
+ if (auto CEE = P.getAs<CallExitEnd>())
return CEE->getCalleeContext()->getCallSite();
- if (Optional<PostInitializer> PIPP = P.getAs<PostInitializer>())
+ if (auto PIPP = P.getAs<PostInitializer>())
return PIPP->getInitializer()->getInit();
- if (Optional<CallExitBegin> CEB = P.getAs<CallExitBegin>())
+ if (auto CEB = P.getAs<CallExitBegin>())
return CEB->getReturnStmt();
+ if (auto FEP = P.getAs<FunctionExitPoint>())
+ return FEP->getStmt();
return nullptr;
}
@@ -822,17 +824,21 @@ PathDiagnosticLocation
const SourceManager &SM) {
assert(N && "Cannot create a location with a null node.");
const Stmt *S = getStmt(N);
+ const LocationContext *LC = N->getLocationContext();
if (!S) {
// If this is an implicit call, return the implicit call point location.
if (Optional<PreImplicitCall> PIE = N->getLocationAs<PreImplicitCall>())
return PathDiagnosticLocation(PIE->getLocation(), SM);
+ if (auto FE = N->getLocationAs<FunctionExitPoint>()) {
+ if (const ReturnStmt *RS = FE->getStmt())
+ return PathDiagnosticLocation::createBegin(RS, SM, LC);
+ }
S = getNextStmt(N);
}
if (S) {
ProgramPoint P = N->getLocation();
- const LocationContext *LC = N->getLocationContext();
// For member expressions, return the location of the '.' or '->'.
if (const auto *ME = dyn_cast<MemberExpr>(S))
Modified: cfe/trunk/test/Analysis/inner-pointer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?rev=342768&r1=342767&r2=342768&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inner-pointer.cpp (original)
+++ cfe/trunk/test/Analysis/inner-pointer.cpp Fri Sep 21 13:36:41 2018
@@ -412,8 +412,9 @@ const char *escape_via_return_local() {
std::string s;
return s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
// expected-note at -1 {{Inner buffer of 'std::string' deallocated by call to destructor}}
-} // expected-warning {{Inner pointer of container used after re/deallocation}}
-// expected-note at -1 {{Inner pointer of container used after re/deallocation}}
+ // expected-warning at -2 {{Inner pointer of container used after re/deallocation}}
+ // expected-note at -3 {{Inner pointer of container used after re/deallocation}}
+}
char *c();
Modified: cfe/trunk/test/Analysis/malloc-free-after-return.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc-free-after-return.cpp?rev=342768&r1=342767&r2=342768&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc-free-after-return.cpp (original)
+++ cfe/trunk/test/Analysis/malloc-free-after-return.cpp Fri Sep 21 13:36:41 2018
@@ -17,5 +17,5 @@ int *freeAfterReturnTemp() {
int *freeAfterReturnLocal() {
S X;
- return X.getData();
-} // expected-warning {{Use of memory after it is freed}}
+ return X.getData(); // expected-warning {{Use of memory after it is freed}}
+}
More information about the cfe-commits
mailing list