[PATCH] D118370: [clang-tidy] bugprone-signal-handler: Code refactor (NFC)
Balázs Kéri via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 27 07:49:23 PST 2022
balazske created this revision.
Herald added subscribers: carlosgalvezp, steakhal, martong, gamesh411, Szelethus, dkrupp, xazax.hun.
balazske requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.
Another change of the code design.
Code simplified again, now there is a single place to check
a handler function and less functions for bug report emitting.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D118370
Files:
clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
Index: clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
+++ clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h
@@ -33,14 +33,12 @@
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
+ bool checkFunction(const FunctionDecl *FD, const Expr *CallOrRef);
bool isFunctionAsyncSafe(const FunctionDecl *FD) const;
bool isSystemCallAsyncSafe(const FunctionDecl *FD) const;
- void reportBug(const FunctionDecl *CalledFunction, const Expr *CallOrRef,
- bool DirectHandler);
- void reportHandlerCommon(llvm::df_iterator<clang::CallGraphNode *> Itr,
- const CallExpr *SignalCall,
- const FunctionDecl *HandlerDecl,
- const Expr *HandlerRef);
+ void reportHandlerChain(const llvm::df_iterator<clang::CallGraphNode *> &Itr,
+ const FunctionDecl *HandlerDecl,
+ const Expr *HandlerRef);
clang::CallGraph CG;
Index: clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp
@@ -142,30 +142,41 @@
"There should be at least one function added to call graph.");
}
- // Check for special case when the signal handler itself is an unsafe external
- // function.
- if (!isFunctionAsyncSafe(HandlerDecl)) {
- reportBug(HandlerDecl, HandlerExpr, /*DirectHandler=*/true);
+ if (!HandlerDecl->hasBody()) {
+ checkFunction(HandlerDecl, HandlerExpr);
return;
}
CallGraphNode *HandlerNode = CG.getNode(HandlerDecl);
- // Signal handler can be external but not unsafe, no call graph in this case.
- if (!HandlerNode)
- return;
+ assert(HandlerNode &&
+ "Handler has body, should be present in the call graph.");
// Start from signal handler and visit every function call.
for (auto Itr = llvm::df_begin(HandlerNode), ItrE = llvm::df_end(HandlerNode);
Itr != ItrE; ++Itr) {
const auto *CallF = dyn_cast<FunctionDecl>((*Itr)->getDecl());
- if (CallF && !isFunctionAsyncSafe(CallF)) {
- assert(Itr.getPathLength() >= 2);
- reportBug(CallF, findCallExpr(Itr.getPath(Itr.getPathLength() - 2), *Itr),
- /*DirectHandler=*/false);
- reportHandlerCommon(Itr, SignalCall, HandlerDecl, HandlerExpr);
+ if (CallF && CallF != HandlerDecl) {
+ if (checkFunction(
+ CallF, findCallExpr(Itr.getPath(Itr.getPathLength() - 2), *Itr)))
+ reportHandlerChain(Itr, HandlerDecl, HandlerExpr);
}
}
}
+bool SignalHandlerCheck::checkFunction(const FunctionDecl *FD,
+ const Expr *CallOrRef) {
+ const bool FunctionIsCalled = isa<CallExpr>(CallOrRef);
+
+ if (!isFunctionAsyncSafe(FD)) {
+ diag(CallOrRef->getBeginLoc(), "%0 may not be asynchronous-safe; "
+ "%select{using it as|calling it from}1 "
+ "a signal handler may be dangerous")
+ << FD << FunctionIsCalled;
+ return true;
+ }
+
+ return false;
+}
+
bool SignalHandlerCheck::isFunctionAsyncSafe(const FunctionDecl *FD) const {
if (isSystemCall(FD))
return isSystemCallAsyncSafe(FD);
@@ -186,16 +197,8 @@
return false;
}
-void SignalHandlerCheck::reportBug(const FunctionDecl *CalledFunction,
- const Expr *CallOrRef, bool DirectHandler) {
- diag(CallOrRef->getBeginLoc(),
- "%0 may not be asynchronous-safe; %select{calling it from|using it as}1 "
- "a signal handler may be dangerous")
- << CalledFunction << DirectHandler;
-}
-
-void SignalHandlerCheck::reportHandlerCommon(
- llvm::df_iterator<clang::CallGraphNode *> Itr, const CallExpr *SignalCall,
+void SignalHandlerCheck::reportHandlerChain(
+ const llvm::df_iterator<clang::CallGraphNode *> &Itr,
const FunctionDecl *HandlerDecl, const Expr *HandlerRef) {
int CallLevel = Itr.getPathLength() - 2;
assert(CallLevel >= -1 && "Empty iterator?");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118370.403652.patch
Type: text/x-patch
Size: 4307 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220127/a238c26f/attachment.bin>
More information about the cfe-commits
mailing list