================ @@ -0,0 +1,138 @@ +//===--- MinMaxUseInitializerListCheck.cpp - clang-tidy -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "MinMaxUseInitializerListCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + Inserter(Options.getLocalOrGlobal("IncludeStyle", + utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::max"))), + hasAnyArgument(callExpr(callee(functionDecl(hasName("::std::max"))))), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::max"))))))) + .bind("maxCall"), + this); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName("::std::min"))), + hasAnyArgument(callExpr(callee(functionDecl(hasName("::std::min"))))), + unless( + hasParent(callExpr(callee(functionDecl(hasName("::std::min"))))))) + .bind("minCall"), + this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MaxCall = Result.Nodes.getNodeAs<CallExpr>("maxCall"); + const auto *MinCall = Result.Nodes.getNodeAs<CallExpr>("minCall"); + + const CallExpr *TopCall = MaxCall ? MaxCall : MinCall; + if (!TopCall) { + return; + } + const QualType ResultType = + TopCall->getDirectCallee()->getReturnType().getNonReferenceType(); + + const Expr *FirstArg = nullptr; + const Expr *LastArg = nullptr; + std::vector<const Expr *> Args; + findArgs(TopCall, &FirstArg, &LastArg, Args); + + if (!FirstArg || !LastArg || Args.size() <= 2) { + return; + } + + std::string ReplacementText = "{"; + for (const Expr *Arg : Args) { + QualType ArgType = Arg->getType(); + bool CastNeeded = + ArgType.getCanonicalType() != ResultType.getCanonicalType(); + + if (CastNeeded) + ReplacementText += "static_cast<" + ResultType.getAsString() + ">("; ---------------- sopyb wrote:
I am unsure if a type cast may even be needed over here since the method declaration for std::{max, min} would require the first 2 parameters being compared would be type casted to the correct type already or it wouldn't compile. ```cpp template< class T > const T& max( const T& a, const T& b ); template< class T, class Compare > const T& max( const T& a, const T& b, Compare comp ); template< class T > const T& min( const T& a, const T& b ); template< class T, class Compare > const T& min( const T& a, const T& b, Compare comp ); ``` Source: - https://en.cppreference.com/w/cpp/algorithm/min - https://en.cppreference.com/w/cpp/algorithm/max Let me know if I am misunderstanding the intended purpose of the typecast in this case. https://github.com/llvm/llvm-project/pull/85572 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits