Skip to content

Commit 8afa030

Browse files
committed
added call-places of functions
1 parent e421016 commit 8afa030

File tree

7 files changed

+190
-282
lines changed

7 files changed

+190
-282
lines changed

clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -96,25 +96,26 @@ void ExceptionEscapeCheck::check(const MatchFinder::MatchResult &Result) {
9696
return;
9797
}
9898

99-
// FIXME: We should provide exact position of functions calls, not only call
100-
// stack of thrown exception.
10199
const utils::ExceptionAnalyzer::CallStack &Stack = ThrowInfo.Stack;
102-
diag(Stack.front()->getLocation(),
103-
"throw stack of unhandled exception, starting from function %0",
100+
diag(ThrowInfo.Loc,
101+
"frame #0: unhandled exception may be thrown in function %0 here",
104102
DiagnosticIDs::Note)
105-
<< Stack.front();
106-
107-
size_t FrameNo = 0;
108-
for (const FunctionDecl *CallNode : Stack) {
109-
if (FrameNo != Stack.size() - 1) {
110-
diag(CallNode->getLocation(), "frame #%0: function %1",
103+
<< Stack.back().first;
104+
105+
size_t FrameNo = 1;
106+
for (auto CurrIt = ++Stack.rbegin(), PrevIt = Stack.rbegin();
107+
CurrIt != Stack.rend(); ++CurrIt, ++PrevIt) {
108+
const FunctionDecl *CurrFunction = CurrIt->first;
109+
const FunctionDecl *PrevFunction = PrevIt->first;
110+
const SourceLocation PrevLocation = PrevIt->second;
111+
if (PrevLocation.isValid()) {
112+
diag(PrevLocation, "frame #%0: function %1 calls function %2 here",
111113
DiagnosticIDs::Note)
112-
<< FrameNo << CallNode;
114+
<< FrameNo << CurrFunction << PrevFunction;
113115
} else {
114-
diag(ThrowInfo.Loc,
115-
"frame #%0: function %1 throws unhandled exception here",
116-
DiagnosticIDs::Note)
117-
<< FrameNo << CallNode;
116+
diag(CurrFunction->getLocation(),
117+
"frame #%0: function %1 calls function %2", DiagnosticIDs::Note)
118+
<< FrameNo << CurrFunction << PrevFunction;
118119
}
119120
++FrameNo;
120121
}

clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -464,16 +464,15 @@ void ExceptionAnalyzer::ExceptionInfo::reevaluateBehaviour() {
464464
else
465465
Behaviour = State::Throwing;
466466
}
467-
ExceptionAnalyzer::ExceptionInfo
468-
ExceptionAnalyzer::throwsException(const FunctionDecl *Func,
469-
const ExceptionInfo::Throwables &Caught,
470-
CallStack &CallStack) {
467+
ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException(
468+
const FunctionDecl *Func, const ExceptionInfo::Throwables &Caught,
469+
CallStack &CallStack, SourceLocation CallLoc) {
471470
if (!Func || CallStack.contains(Func) ||
472471
(!CallStack.empty() && !canThrow(Func)))
473472
return ExceptionInfo::createNonThrowing();
474473

475474
if (const Stmt *Body = Func->getBody()) {
476-
CallStack.insert(Func);
475+
CallStack.insert({Func, CallLoc});
477476
ExceptionInfo Result = throwsException(Body, Caught, CallStack);
478477

479478
// For a constructor, we also have to check the initializers.
@@ -485,18 +484,18 @@ ExceptionAnalyzer::throwsException(const FunctionDecl *Func,
485484
}
486485
}
487486

488-
CallStack.remove(Func);
487+
CallStack.erase(Func);
489488
return Result;
490489
}
491490

492491
auto Result = ExceptionInfo::createUnknown();
493492
if (const auto *FPT = Func->getType()->getAs<FunctionProtoType>()) {
494493
for (const QualType &Ex : FPT->exceptions()) {
495-
CallStack.insert(Func);
494+
CallStack.insert({Func, CallLoc});
496495
Result.registerException(
497496
Ex.getTypePtr(),
498497
{Func->getExceptionSpecSourceRange().getBegin(), CallStack});
499-
CallStack.remove(Func);
498+
CallStack.erase(Func);
500499
}
501500
}
502501
return Result;
@@ -566,12 +565,13 @@ ExceptionAnalyzer::throwsException(const Stmt *St,
566565
Results.merge(Uncaught);
567566
} else if (const auto *Call = dyn_cast<CallExpr>(St)) {
568567
if (const FunctionDecl *Func = Call->getDirectCallee()) {
569-
ExceptionInfo Excs = throwsException(Func, Caught, CallStack);
568+
ExceptionInfo Excs =
569+
throwsException(Func, Caught, CallStack, Call->getBeginLoc());
570570
Results.merge(Excs);
571571
}
572572
} else if (const auto *Construct = dyn_cast<CXXConstructExpr>(St)) {
573-
ExceptionInfo Excs =
574-
throwsException(Construct->getConstructor(), Caught, CallStack);
573+
ExceptionInfo Excs = throwsException(Construct->getConstructor(), Caught,
574+
CallStack, Construct->getBeginLoc());
575575
Results.merge(Excs);
576576
} else if (const auto *DefaultInit = dyn_cast<CXXDefaultInitExpr>(St)) {
577577
ExceptionInfo Excs =
@@ -590,8 +590,8 @@ ExceptionAnalyzer::throwsException(const Stmt *St,
590590
for (const auto &Exception : Excs.getExceptions()) {
591591
const Type *ExcType = Exception.getFirst();
592592
if (const CXXRecordDecl *ThrowableRec = ExcType->getAsCXXRecordDecl()) {
593-
ExceptionInfo DestructorExcs =
594-
throwsException(ThrowableRec->getDestructor(), Caught, CallStack);
593+
ExceptionInfo DestructorExcs = throwsException(
594+
ThrowableRec->getDestructor(), Caught, CallStack, SourceLocation{});
595595
Results.merge(DestructorExcs);
596596
}
597597
}
@@ -612,8 +612,8 @@ ExceptionAnalyzer::analyzeImpl(const FunctionDecl *Func) {
612612
const auto CacheEntry = FunctionCache.find(Func);
613613
if (CacheEntry == FunctionCache.end()) {
614614
CallStack CallStack;
615-
ExceptionList =
616-
throwsException(Func, ExceptionInfo::Throwables(), CallStack);
615+
ExceptionList = throwsException(Func, ExceptionInfo::Throwables(),
616+
CallStack, Func->getLocation());
617617

618618
// Cache the result of the analysis. This is done prior to filtering
619619
// because it is best to keep as much information as possible.

clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ class ExceptionAnalyzer {
2929
///< definition.
3030
};
3131

32-
/// We use a SetVector to preserve the order of the functions in the call
32+
/// We use a MapVector to preserve the order of the functions in the call
3333
/// stack as well as have fast lookup.
34-
using CallStack = llvm::SetVector<const FunctionDecl *,
35-
llvm::SmallVector<const FunctionDecl *, 32>,
36-
llvm::DenseSet<const FunctionDecl *>, 32>;
34+
using CallStack = llvm::MapVector<const FunctionDecl *, SourceLocation>;
3735

3836
/// Bundle the gathered information about an entity like a function regarding
3937
/// it's exception behaviour. The 'NonThrowing'-state can be considered as the
@@ -144,7 +142,7 @@ class ExceptionAnalyzer {
144142
private:
145143
ExceptionInfo throwsException(const FunctionDecl *Func,
146144
const ExceptionInfo::Throwables &Caught,
147-
CallStack &CallStack);
145+
CallStack &CallStack, SourceLocation CallLoc);
148146
ExceptionInfo throwsException(const Stmt *St,
149147
const ExceptionInfo::Throwables &Caught,
150148
CallStack &CallStack);

0 commit comments

Comments
 (0)