[clang] [Clang] Optimize -Wunsafe-buffer-usage. (PR #125492)
Ivana Ivanovska via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 7 04:54:27 PST 2025
================
@@ -1561,56 +1821,70 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget {
} WarnedFunKind = OTHERS;
public:
- UnsafeLibcFunctionCallGadget(const MatchFinder::MatchResult &Result)
+ UnsafeLibcFunctionCallGadget(const MatchResult &Result)
: WarningGadget(Kind::UnsafeLibcFunctionCall),
- Call(Result.Nodes.getNodeAs<CallExpr>(Tag)) {
- if (Result.Nodes.getNodeAs<Decl>(UnsafeSprintfTag))
+ Call(Result.getNodeAs<CallExpr>(Tag)) {
+ if (Result.getNodeAs<Decl>(UnsafeSprintfTag))
WarnedFunKind = SPRINTF;
- else if (auto *E = Result.Nodes.getNodeAs<Expr>(UnsafeStringTag)) {
+ else if (auto *E = Result.getNodeAs<Expr>(UnsafeStringTag)) {
WarnedFunKind = STRING;
UnsafeArg = E;
- } else if (Result.Nodes.getNodeAs<CallExpr>(UnsafeSizedByTag)) {
+ } else if (Result.getNodeAs<CallExpr>(UnsafeSizedByTag)) {
WarnedFunKind = SIZED_BY;
UnsafeArg = Call->getArg(0);
- } else if (Result.Nodes.getNodeAs<Decl>(UnsafeVaListTag))
+ } else if (Result.getNodeAs<Decl>(UnsafeVaListTag))
WarnedFunKind = VA_LIST;
}
- static Matcher matcher(const UnsafeBufferUsageHandler *Handler) {
- return stmt(unless(ignoreUnsafeLibcCall(Handler)),
- anyOf(
- callExpr(
- callee(functionDecl(anyOf(
- // Match a predefined unsafe libc
- // function:
- functionDecl(libc_func_matchers::isPredefinedUnsafeLibcFunc()),
- // Match a call to one of the `v*printf` functions
- // taking va-list, which cannot be checked at
- // compile-time:
- functionDecl(libc_func_matchers::isUnsafeVaListPrintfFunc())
- .bind(UnsafeVaListTag),
- // Match a call to a `sprintf` function, which is never
- // safe:
- functionDecl(libc_func_matchers::isUnsafeSprintfFunc())
- .bind(UnsafeSprintfTag)))),
- // (unless the call has a sole string literal argument):
- unless(
- allOf(hasArgument(0, expr(stringLiteral())), hasNumArgs(1)))),
-
- // The following two cases require checking against actual
- // arguments of the call:
-
- // Match a call to an `snprintf` function. And first two
- // arguments of the call (that describe a buffer) are not in
- // safe patterns:
- callExpr(callee(functionDecl(libc_func_matchers::isNormalPrintfFunc())),
- libc_func_matchers::hasUnsafeSnprintfBuffer())
- .bind(UnsafeSizedByTag),
- // Match a call to a `printf` function, which can be safe if
- // all arguments are null-terminated:
- callExpr(callee(functionDecl(libc_func_matchers::isNormalPrintfFunc())),
- libc_func_matchers::hasUnsafePrintfStringArg(
- expr().bind(UnsafeStringTag)))));
+ static bool matches(const Stmt *S, ASTContext &Ctx,
+ const UnsafeBufferUsageHandler *Handler,
+ MatchResult &Result) {
+ if (ignoreUnsafeLibcCall(Ctx, *S, Handler))
+ return false;
+ auto *CE = dyn_cast<CallExpr>(S);
+ if (!CE || !CE->getDirectCallee())
+ return false;
+ const auto *FD = dyn_cast<FunctionDecl>(CE->getDirectCallee());
+ if (!FD)
+ return false;
+ auto isSingleStringLiteralArg = false;
+ if (CE->getNumArgs() == 1) {
+ const auto *const Arg = CE->getArg(0);
+ if (isa<Expr>(Arg) && !Arg->children().empty()) {
+ isSingleStringLiteralArg =
+ isa<clang::StringLiteral>(*Arg->children().begin());
+ }
+ }
+ if (!isSingleStringLiteralArg) { // (unless the call has a sole string
----------------
ivanaivanovska wrote:
Done.
https://github.com/llvm/llvm-project/pull/125492
More information about the cfe-commits
mailing list