Skip to content

Commit

Permalink
[analyzer] Extend the PathDiagnosticLocation constructor to handle Ca…
Browse files Browse the repository at this point in the history
…llExitEnd

Differential Revision: https://reviews.llvm.org/D56890

llvm-svn: 351513
  • Loading branch information
George Karpenkov committed Jan 18, 2019
1 parent 9bf9938 commit e880840
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 30 deletions.
Expand Up @@ -408,15 +408,7 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N,
if (os.str().empty())
return nullptr;

// FIXME: remove the code duplication with NoStoreFuncVisitor.
PathDiagnosticLocation L;
if (const ReturnStmt *RS = CallExitLoc.getReturnStmt()) {
L = PathDiagnosticLocation::createBegin(RS, SM, N->getLocationContext());
} else {
L = PathDiagnosticLocation(
Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(), SM);
}

PathDiagnosticLocation L = PathDiagnosticLocation::create(CallExitLoc, SM);
return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}

Expand Down
32 changes: 11 additions & 21 deletions clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
Expand Up @@ -308,18 +308,16 @@ class NoStoreFuncVisitor final : public BugReporterVisitor {
if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
potentiallyWritesIntoIvar(Call->getRuntimeDefinition().getDecl(),
IvarR->getDecl()))
return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, SelfRegion,
"self", /*FirstIsReferenceType=*/false,
1);
return notModifiedDiagnostics(N, {}, SelfRegion, "self",
/*FirstIsReferenceType=*/false, 1);
}
}

if (const auto *CCall = dyn_cast<CXXConstructorCall>(Call)) {
const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion();
if (RegionOfInterest->isSubRegionOf(ThisR)
&& !CCall->getDecl()->isImplicit())
return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, ThisR,
"this",
return notModifiedDiagnostics(N, {}, ThisR, "this",
/*FirstIsReferenceType=*/false, 1);

// Do not generate diagnostics for not modified parameters in
Expand All @@ -338,18 +336,17 @@ class NoStoreFuncVisitor final : public BugReporterVisitor {
QualType T = PVD->getType();
while (const MemRegion *R = S.getAsRegion()) {
if (RegionOfInterest->isSubRegionOf(R) && !isPointerToConst(T))
return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, R,
ParamName, ParamIsReferenceType,
IndirectionLevel);
return notModifiedDiagnostics(N, {}, R, ParamName,
ParamIsReferenceType, IndirectionLevel);

QualType PT = T->getPointeeType();
if (PT.isNull() || PT->isVoidType()) break;

if (const RecordDecl *RD = PT->getAsRecordDecl())
if (auto P = findRegionOfInterestInRecord(RD, State, R))
return notModifiedDiagnostics(
Ctx, *CallExitLoc, Call, *P, RegionOfInterest, ParamName,
ParamIsReferenceType, IndirectionLevel);
return notModifiedDiagnostics(N, *P, RegionOfInterest, ParamName,
ParamIsReferenceType,
IndirectionLevel);

S = State->getSVal(R, PT);
T = PT;
Expand Down Expand Up @@ -523,19 +520,12 @@ class NoStoreFuncVisitor final : public BugReporterVisitor {

/// \return Diagnostics piece for region not modified in the current function.
std::shared_ptr<PathDiagnosticPiece>
notModifiedDiagnostics(const LocationContext *Ctx, CallExitBegin &CallExitLoc,
CallEventRef<> Call, const RegionVector &FieldChain,
notModifiedDiagnostics(const ExplodedNode *N, const RegionVector &FieldChain,
const MemRegion *MatchedRegion, StringRef FirstElement,
bool FirstIsReferenceType, unsigned IndirectionLevel) {

PathDiagnosticLocation L;
if (const ReturnStmt *RS = CallExitLoc.getReturnStmt()) {
L = PathDiagnosticLocation::createBegin(RS, SM, Ctx);
} else {
L = PathDiagnosticLocation(
Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(),
SM);
}
PathDiagnosticLocation L =
PathDiagnosticLocation::create(N->getLocation(), SM);

SmallString<256> sbuf;
llvm::raw_svector_ostream os(sbuf);
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
Expand Up @@ -735,6 +735,12 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
return getLocationForCaller(CEE->getCalleeContext(),
CEE->getLocationContext(),
SMng);
} else if (auto CEB = P.getAs<CallExitBegin>()) {
if (const ReturnStmt *RS = CEB->getReturnStmt())
return PathDiagnosticLocation::createBegin(RS, SMng,
CEB->getLocationContext());
return PathDiagnosticLocation(
CEB->getLocationContext()->getDecl()->getSourceRange().getEnd(), SMng);
} else if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
CFGElement BlockFront = BE->getBlock()->front();
if (auto StmtElt = BlockFront.getAs<CFGStmt>()) {
Expand Down

0 comments on commit e880840

Please sign in to comment.