46 constexpr BuiltinType::Kind IntTy = BuiltinType::Int;
47 constexpr BuiltinType::Kind LongTy = BuiltinType::Long;
48 constexpr BuiltinType::Kind FloatTy = BuiltinType::Float;
49 constexpr BuiltinType::Kind DoubleTy = BuiltinType::Double;
50 constexpr BuiltinType::Kind LongDoubleTy = BuiltinType::LongDouble;
52 auto HasBuiltinTyParam = [](
int Pos, BuiltinType::Kind Kind) {
53 return hasParameter(Pos, hasType(isBuiltinType(Kind)));
55 auto HasBuiltinTyArg = [](
int Pos, BuiltinType::Kind Kind) {
56 return hasArgument(Pos, hasType(isBuiltinType(Kind)));
60 auto OneDoubleArgFns = hasAnyName(
61 "::acos",
"::acosh",
"::asin",
"::asinh",
"::atan",
"::atanh",
"::cbrt",
62 "::ceil",
"::cos",
"::cosh",
"::erf",
"::erfc",
"::exp",
"::exp2",
63 "::expm1",
"::fabs",
"::floor",
"::ilogb",
"::lgamma",
"::llrint",
64 "::log",
"::log10",
"::log1p",
"::log2",
"::logb",
"::lrint",
"::modf",
65 "::nearbyint",
"::rint",
"::round",
"::sin",
"::sinh",
"::sqrt",
"::tan",
66 "::tanh",
"::tgamma",
"::trunc",
"::llround",
"::lround");
68 callExpr(callee(functionDecl(OneDoubleArgFns, parameterCountIs(1),
69 HasBuiltinTyParam(0, DoubleTy))),
70 HasBuiltinTyArg(0, FloatTy))
75 auto TwoDoubleArgFns = hasAnyName(
"::atan2",
"::copysign",
"::fdim",
"::fmax",
76 "::fmin",
"::fmod",
"::hypot",
"::ldexp",
77 "::nextafter",
"::pow",
"::remainder");
79 callExpr(callee(functionDecl(TwoDoubleArgFns, parameterCountIs(2),
80 HasBuiltinTyParam(0, DoubleTy),
81 HasBuiltinTyParam(1, DoubleTy))),
82 HasBuiltinTyArg(0, FloatTy), HasBuiltinTyArg(1, FloatTy))
88 callExpr(callee(functionDecl(hasName(
"::fma"), parameterCountIs(3),
89 HasBuiltinTyParam(0, DoubleTy),
90 HasBuiltinTyParam(1, DoubleTy),
91 HasBuiltinTyParam(2, DoubleTy))),
92 HasBuiltinTyArg(0, FloatTy), HasBuiltinTyArg(1, FloatTy),
93 HasBuiltinTyArg(2, FloatTy))
99 callExpr(callee(functionDecl(
100 hasName(
"::frexp"), parameterCountIs(2),
101 HasBuiltinTyParam(0, DoubleTy),
102 hasParameter(1, parmVarDecl(hasType(pointerType(
103 pointee(isBuiltinType(IntTy)))))))),
104 HasBuiltinTyArg(0, FloatTy))
111 callExpr(callee(functionDecl(hasName(
"::nexttoward"), parameterCountIs(2),
112 HasBuiltinTyParam(0, DoubleTy),
113 HasBuiltinTyParam(1, LongDoubleTy))),
114 HasBuiltinTyArg(0, FloatTy))
123 hasName(
"::remquo"), parameterCountIs(3),
124 HasBuiltinTyParam(0, DoubleTy), HasBuiltinTyParam(1, DoubleTy),
125 hasParameter(2, parmVarDecl(hasType(pointerType(
126 pointee(isBuiltinType(IntTy)))))))),
127 HasBuiltinTyArg(0, FloatTy), HasBuiltinTyArg(1, FloatTy))
133 callExpr(callee(functionDecl(hasName(
"::scalbln"), parameterCountIs(2),
134 HasBuiltinTyParam(0, DoubleTy),
135 HasBuiltinTyParam(1, LongTy))),
136 HasBuiltinTyArg(0, FloatTy))
142 callExpr(callee(functionDecl(hasName(
"::scalbn"), parameterCountIs(2),
143 HasBuiltinTyParam(0, DoubleTy),
144 HasBuiltinTyParam(1, IntTy))),
145 HasBuiltinTyArg(0, FloatTy))
154 const auto *Call = Result.Nodes.getNodeAs<CallExpr>(
"call");
155 assert(Call !=
nullptr);
157 const StringRef OldFnName = Call->getDirectCallee()->getName();
161 static const llvm::StringSet<> Cpp11OnlyFns = {
162 "acosh",
"asinh",
"atanh",
"cbrt",
"copysign",
"erf",
163 "erfc",
"exp2",
"expm1",
"fdim",
"fma",
"fmax",
164 "fmin",
"hypot",
"ilogb",
"lgamma",
"llrint",
"llround",
165 "log1p",
"log2",
"logb",
"lrint",
"lround",
"nearbyint",
166 "nextafter",
"nexttoward",
"remainder",
"remquo",
"rint",
"round",
167 "scalbln",
"scalbn",
"tgamma",
"trunc"};
168 const bool StdFnRequiresCpp11 = Cpp11OnlyFns.contains(OldFnName);
170 std::string NewFnName;
171 bool FnInCmath =
false;
172 if (getLangOpts().CPlusPlus &&
173 (!StdFnRequiresCpp11 || getLangOpts().CPlusPlus11)) {
174 NewFnName = (
"std::" + OldFnName).str();
177 NewFnName = (OldFnName +
"f").str();
180 auto Diag = diag(Call->getExprLoc(),
"call to '%0' promotes float to double")
182 << FixItHint::CreateReplacement(
183 Call->getCallee()->getSourceRange(), NewFnName);
190 Diag << IncludeInserter.createIncludeInsertion(
191 Result.Context->getSourceManager().getFileID(Call->getBeginLoc()),
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.