================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits