/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ #ifndef LO_CLANG_SHARED_PLUGINS
TODO multiplying/otherop on a combination of a float and int, and then truncating to int. like this: float getRotation() {} int moRotation = -F_PI180 * 90 * getRotation();
*/ namespace
{ class IntVsFloat : public loplugin::FilteringPlugin<IntVsFloat>
{ public: explicit IntVsFloat(loplugin::InstantiationData const& data)
: loplugin::FilteringPlugin<IntVsFloat>(data)
{
}
bool IntVsFloat::VisitVarDecl(VarDecl const* varDecl)
{ if (ignoreLocation(varDecl->getLocation())) returntrue; auto init = varDecl->getInit(); if (!init) returntrue;
init = init->IgnoreImpCasts(); if (varDecl->getType()->isFloatingType()) returntrue; // init->dump();
compat::optional<double> d = getExprValue(init); if (!d) returntrue; if (static_cast<long>(*d) == *d) returntrue;
report(DiagnosticsEngine::Warning, "assigning constant float value to int truncates data",
init->getBeginLoc())
<< init->getSourceRange();
returntrue;
}
bool IntVsFloat::VisitBinaryOperator(BinaryOperator const* op)
{ if (op->getOpcode() != BO_EQ)
{ returntrue;
} if (ignoreLocation(op->getBeginLoc())) returntrue; auto lhs = op->getLHS()->IgnoreImpCasts(); auto rhs = op->getRHS()->IgnoreImpCasts(); if (!lhs->getType()->isFloatingType())
std::swap(lhs, rhs); if (!lhs->getType()->isFloatingType()) returntrue; if (rhs->getType()->isFloatingType()) returntrue;
compat::optional<double> d = getExprValue(lhs); if (!d) returntrue; if (static_cast<long>(*d) == *d) returntrue;
report(DiagnosticsEngine::Warning, "comparing integer to float constant, can never be true",
op->getBeginLoc())
<< op->getSourceRange(); returntrue;
}
compat::optional<double> IntVsFloat::getExprValue(Expr const* expr)
{ // Of the available clang Evaluate* APIs, this is the __only__ one that produces useful output // (as of 17 Aug 2018 checkout of clang, ie. towards clang 7)
if (expr->isValueDependent()) return compat::optional<double>();
Expr::EvalResult evalResult; if (!expr->EvaluateAsRValue(evalResult, compiler.getASTContext())) return compat::optional<double>(); if (!evalResult.Val.isFloat()) return compat::optional<double>();
llvm::APFloat floatResult = evalResult.Val.getFloat(); bool losesInfo;
floatResult.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
double d = floatResult.convertToDouble(); return d;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.