loplugin:redundantcast improvements for floating-integer conversions

Change-Id: I63dbf18f144a792ae775fe6706da81657f790016
Reviewed-on: https://gerrit.libreoffice.org/54416
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Tested-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann 2018-05-16 10:16:01 +02:00
parent f8e3ad0273
commit 7ab34b51f2
17 changed files with 80 additions and 29 deletions

View File

@ -155,7 +155,6 @@ void SbiExprNode::ConvertToIntConstIfPossible()
double n; double n;
if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 ) if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 )
{ {
nVal = static_cast<double>(static_cast<short>(nVal));
eType = SbxINTEGER; eType = SbxINTEGER;
} }
} }

View File

@ -248,6 +248,23 @@ bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) {
} }
} }
break; break;
case CK_FloatingToIntegral:
case CK_IntegralToFloating:
if (auto e = dyn_cast<ExplicitCastExpr>(expr->getSubExpr()->IgnoreParenImpCasts())) {
if ((isa<CXXStaticCastExpr>(e) || isa<CXXFunctionalCastExpr>(e))
&& (e->getSubExprAsWritten()->getType().getCanonicalType().getTypePtr()
== expr->getType().getCanonicalType().getTypePtr()))
{
report(
DiagnosticsEngine::Warning,
("suspicious %select{static_cast|functional cast}0 from %1 to %2, result is"
" implicitly cast to %3"),
e->getExprLoc())
<< isa<CXXFunctionalCastExpr>(e) << e->getSubExprAsWritten()->getType()
<< e->getTypeAsWritten() << expr->getType() << expr->getSourceRange();
}
}
break;
default: default:
break; break;
} }

View File

@ -374,6 +374,15 @@ void testOverloadResolution() {
(void) NonOverloadMemFn(&Overload::nonOverload); // expected-error {{redundant functional cast from 'void (Overload::*)()' to 'NonOverloadMemFn' (aka 'void (Overload::*)()') [loplugin:redundantcast]}} (void) NonOverloadMemFn(&Overload::nonOverload); // expected-error {{redundant functional cast from 'void (Overload::*)()' to 'NonOverloadMemFn' (aka 'void (Overload::*)()') [loplugin:redundantcast]}}
}; };
void testIntermediaryStaticCast() {
int n = 0;
n = static_cast<double>(n); // expected-error {{suspicious static_cast from 'int' to 'double', result is implicitly cast to 'int' [loplugin:redundantcast]}}
n = double(n); // expected-error {{suspicious functional cast from 'int' to 'double', result is implicitly cast to 'int' [loplugin:redundantcast]}}
double d = 0.0;
d = static_cast<int>(d) + 1.0; // expected-error {{suspicious static_cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}}
d = int(d) + 1.0; // expected-error {{suspicious functional cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}}
};
int main() { int main() {
testConstCast(); testConstCast();
testStaticCast(); testStaticCast();
@ -382,6 +391,7 @@ int main() {
testCStyleCastOfTemplateMethodResult(nullptr); testCStyleCastOfTemplateMethodResult(nullptr);
testReinterpretConstCast(); testReinterpretConstCast();
testDynamicCast(); testDynamicCast();
testIntermediaryStaticCast();
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -134,9 +134,9 @@ void lcl_CalcJulDate(sal_Int32& _nJulianDate,sal_Int32& _nJulianTime, const css:
} // if ( rDateTime.Year <= 0 ) } // if ( rDateTime.Year <= 0 )
else else
{ {
_nJulianDate = static_cast<sal_Int32>( ((365.25 * iy0) _nJulianDate = static_cast<sal_Int32>(365.25 * iy0)
+ static_cast<sal_Int32>(30.6001 * (im0 + 1)) + static_cast<sal_Int32>(30.6001 * (im0 + 1))
+ aDateTime.Day + 1720994)); + aDateTime.Day + 1720994;
} }
double JD = _nJulianDate + 0.5; double JD = _nJulianDate + 0.5;
_nJulianDate = static_cast<sal_Int32>( JD + 0.5); _nJulianDate = static_cast<sal_Int32>( JD + 0.5);

View File

@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <sal/config.h>
#include <cmath>
#include <drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx> #include <drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx> #include <basegfx/polygon/b2dpolygontools.hxx>
@ -62,7 +66,7 @@ namespace drawinglayer
const double fFrontArea(basegfx::utils::getArea(aFirstPolygon)); const double fFrontArea(basegfx::utils::getArea(aFirstPolygon));
const double fSqrtFrontArea(sqrt(fFrontArea)); const double fSqrtFrontArea(sqrt(fFrontArea));
double fRelativeTextureWidth = basegfx::fTools::equalZero(fSqrtFrontArea) ? 1.0 : fFrontLength / fSqrtFrontArea; double fRelativeTextureWidth = basegfx::fTools::equalZero(fSqrtFrontArea) ? 1.0 : fFrontLength / fSqrtFrontArea;
fRelativeTextureWidth = static_cast<double>(static_cast<sal_uInt32>(fRelativeTextureWidth - 0.5)); fRelativeTextureWidth = std::trunc(fRelativeTextureWidth - 0.5);
if(fRelativeTextureWidth < 1.0) if(fRelativeTextureWidth < 1.0)
{ {

View File

@ -4399,21 +4399,21 @@ void HwpReader::makePictureDRAW(HWPDrawingObject *drawobj, Picture * hbox)
NaturalSpline(n, tarr, yarr, yb, carr, darr); NaturalSpline(n, tarr, yarr, yb, carr, darr);
} }
sprintf(buf, "M%d %dC%d %d", WTSM(static_cast<int>(xarr[0])), WTSM(static_cast<int>(yarr[0])), sprintf(buf, "M%d %dC%d %d", WTSM(xarr[0]), WTSM(yarr[0]),
WTSM(static_cast<int>(xarr[0] + xb[0]/3)), WTSM(static_cast<int>(yarr[0] + yb[0]/3)) ); WTSM(xarr[0] + xb[0]/3), WTSM(yarr[0] + yb[0]/3) );
oustr += ascii(buf); oustr += ascii(buf);
for( i = 1 ; i < n ; i++ ){ for( i = 1 ; i < n ; i++ ){
if( i == n -1 ){ if( i == n -1 ){
sprintf(buf, " %d %d %d %dz", sprintf(buf, " %d %d %d %dz",
WTSM(static_cast<int>(xarr[i] - xb[i]/3)), WTSM(static_cast<int>(yarr[i] - yb[i]/3)), WTSM(xarr[i] - xb[i]/3), WTSM(yarr[i] - yb[i]/3),
WTSM(static_cast<int>(xarr[i])), WTSM(static_cast<int>(yarr[i])) ); WTSM(xarr[i]), WTSM(yarr[i]) );
} }
else{ else{
sprintf(buf, " %d %d %d %d %d %d", sprintf(buf, " %d %d %d %d %d %d",
WTSM(static_cast<int>(xarr[i] - xb[i]/3)), WTSM(static_cast<int>(yarr[i] - yb[i]/3)), WTSM(xarr[i] - xb[i]/3), WTSM(yarr[i] - yb[i]/3),
WTSM(static_cast<int>(xarr[i])), WTSM(static_cast<int>(yarr[i])), WTSM(xarr[i]), WTSM(yarr[i]),
WTSM(static_cast<int>(xarr[i]) + xb[i]/3), WTSM(static_cast<int>(yarr[i] + yb[i]/3)) ); WTSM(xarr[i] + xb[i]/3), WTSM(yarr[i] + yb[i]/3) );
} }
oustr += ascii(buf); oustr += ascii(buf);

View File

@ -155,7 +155,7 @@ int main( int argc, char* argv[] )
// Estimate the maximum tiles based on the number of parts requested, if Writer. // Estimate the maximum tiles based on the number of parts requested, if Writer.
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT) if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
max_tiles = static_cast<int>(ceil(max_parts * 16128. / nTilePixelHeight)) * ceil(static_cast<double>(nWidth) / nTilePixelWidth); max_tiles = static_cast<int>(ceil(max_parts * 16128. / nTilePixelHeight) * ceil(static_cast<double>(nWidth) / nTilePixelWidth));
fprintf(stderr, "Parts to render: %d, Total Parts: %d, Max parts: %d, Max tiles: %d\n", nParts, nTotalParts, max_parts, max_tiles); fprintf(stderr, "Parts to render: %d, Total Parts: %d, Max parts: %d, Max tiles: %d\n", nParts, nTotalParts, max_parts, max_tiles);
std::vector<unsigned char> vBuffer(nTilePixelWidth * nTilePixelHeight * 4); std::vector<unsigned char> vBuffer(nTilePixelWidth * nTilePixelHeight * 4);
@ -210,7 +210,7 @@ int main( int argc, char* argv[] )
aTimes.emplace_back("render sub-regions at scale"); aTimes.emplace_back("render sub-regions at scale");
int nMaxTiles = max_tiles; int nMaxTiles = max_tiles;
if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT) if (pDocument->getDocumentType() == LOK_DOCTYPE_TEXT)
nMaxTiles = static_cast<int>(ceil(max_parts * 16128. / nTileTwipHeight)) * ceil(static_cast<double>(nWidth) / nTileTwipWidth); nMaxTiles = static_cast<int>(ceil(max_parts * 16128. / nTileTwipHeight) * ceil(static_cast<double>(nWidth) / nTileTwipWidth));
int nTiles = 0; int nTiles = 0;
for (int nY = 0; nY < nHeight - 1; nY += nTileTwipHeight) for (int nY = 0; nY < nHeight - 1; nY += nTileTwipHeight)
{ {

View File

@ -19,6 +19,7 @@
#include <sal/config.h> #include <sal/config.h>
#include <cmath>
#include <map> #include <map>
#include "xmlControlProperty.hxx" #include "xmlControlProperty.hxx"
@ -271,7 +272,8 @@ Any OXMLControlProperty::convertString(const css::uno::Type& _rExpectedType, con
{ {
case TYPE_DATE: case TYPE_DATE:
{ {
OSL_ENSURE((static_cast<sal_uInt32>(nValue)) - nValue == 0, double dummy;
OSL_ENSURE(std::modf(nValue, &dummy) == 0,
"OPropertyImport::convertString: a Date value with a fractional part?"); "OPropertyImport::convertString: a Date value with a fractional part?");
aReturn <<= implGetDate(nValue); aReturn <<= implGetDate(nValue);
} }

View File

@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <sal/config.h>
#include <cmath>
#include <sal/types.h> #include <sal/types.h>
#include <osl/thread.h> #include <osl/thread.h>
#include <osl/thread.hxx> #include <osl/thread.hxx>
@ -81,8 +85,7 @@ static double data(RandomData_Impl *pImpl)
(static_cast<double>(pImpl->m_nY) / 30269.0) + (static_cast<double>(pImpl->m_nY) / 30269.0) +
(static_cast<double>(pImpl->m_nZ) / 30307.0) ); (static_cast<double>(pImpl->m_nZ) / 30307.0) );
random -= static_cast<double>(static_cast<sal_uInt32>(random)); return std::modf(random, &random);
return random;
} }
static bool initPool(RandomPool_Impl *pImpl) static bool initPool(RandomPool_Impl *pImpl)

View File

@ -30,6 +30,7 @@
#include <comphelper/propertycontainer.hxx> #include <comphelper/propertycontainer.hxx>
#include <comphelper/proparrhlp.hxx> #include <comphelper/proparrhlp.hxx>
#include <cmath>
#include <vector> #include <vector>
#include <limits> #include <limits>
#include <chrono> #include <chrono>
@ -370,7 +371,7 @@ double SwarmSolver::clampVariable(size_t nVarIndex, double fValue)
double fResult = std::max(std::min(fValue, rBound.upper), rBound.lower); double fResult = std::max(std::min(fValue, rBound.upper), rBound.lower);
if (mbInteger) if (mbInteger)
return sal_Int64(fResult); return std::trunc(fResult);
return fResult; return fResult;
} }
@ -389,7 +390,7 @@ double SwarmSolver::boundVariable(size_t nVarIndex, double fValue)
} }
if (mbInteger) if (mbInteger)
return sal_Int64(fResult); return std::trunc(fResult);
return fResult; return fResult;
} }

View File

@ -1898,8 +1898,8 @@ bool PowerPointExport::WriteComments(sal_uInt32 nPageNum)
FSEND); FSEND);
pFS->singleElementNS(XML_p, XML_pos, pFS->singleElementNS(XML_p, XML_pos,
XML_x, I64S((static_cast<sal_Int64>(57600*aRealPoint2D.X + 1270)/2540.0)), XML_x, I64S(static_cast<sal_Int64>((57600*aRealPoint2D.X + 1270)/2540.0)),
XML_y, I64S((static_cast<sal_Int64>(57600*aRealPoint2D.Y + 1270)/2540.0)), XML_y, I64S(static_cast<sal_Int64>((57600*aRealPoint2D.Y + 1270)/2540.0)),
FSEND); FSEND);
pFS->startElementNS(XML_p, XML_text, pFS->startElementNS(XML_p, XML_text,

View File

@ -17,6 +17,9 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <sal/config.h>
#include <cmath>
#include <osl/diagnose.h> #include <osl/diagnose.h>
#include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/matrix/b2dhommatrix.hxx>
@ -87,7 +90,7 @@ SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis )
if (in) { if (in) {
const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements ); const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements );
const double edge = ::basegfx::pruneScaleValue( const double edge = ::basegfx::pruneScaleValue(
static_cast<double>( static_cast<sal_Int32>(sqrtArea2) ) / std::trunc(sqrtArea2) /
m_sqrtElements ); m_sqrtElements );
::basegfx::B2DPolygon poly; ::basegfx::B2DPolygon poly;
@ -99,7 +102,8 @@ SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis )
res.append(poly); res.append(poly);
} }
const double a = (M_SQRT1_2 / m_sqrtElements); const double a = (M_SQRT1_2 / m_sqrtElements);
const double d = (sqrtArea2 - static_cast<sal_Int32>(sqrtArea2)); double dummy;
const double d = std::modf(sqrtArea2, &dummy);
const double len = (t * M_SQRT2 * d); const double len = (t * M_SQRT2 * d);
const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements ); const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements );
poly.clear(); poly.clear();
@ -130,7 +134,7 @@ SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis )
{ {
const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements ); const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements );
const double edge = ::basegfx::pruneScaleValue( const double edge = ::basegfx::pruneScaleValue(
static_cast<double>( static_cast<sal_Int32>(sqrtArea2) ) / std::trunc(sqrtArea2) /
m_sqrtElements ); m_sqrtElements );
::basegfx::B2DPolygon poly; ::basegfx::B2DPolygon poly;
@ -143,7 +147,8 @@ SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis )
res.append(poly); res.append(poly);
} }
const double a = (M_SQRT1_2 / m_sqrtElements); const double a = (M_SQRT1_2 / m_sqrtElements);
const double d = (sqrtArea2 - static_cast<sal_Int32>(sqrtArea2)); double dummy;
const double d = std::modf(sqrtArea2, &dummy);
const double len = ((1.0 - t) * M_SQRT2 * d); const double len = ((1.0 - t) * M_SQRT2 * d);
const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements ); const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements );
poly.clear(); poly.clear();

View File

@ -1329,7 +1329,7 @@ void Polygon::ImplReduceEdges( tools::Polygon& rPoly, const double& rArea, sal_u
else if( fRelLen > 1.0 ) else if( fRelLen > 1.0 )
fRelLen = 1.0; fRelLen = 1.0;
if( ( static_cast<sal_uInt32>( ( ( fLenFact - 1.0 ) * 1000000.0 ) + 0.5 ) < fBound ) && if( ( std::round( ( fLenFact - 1.0 ) * 1000000.0 ) < fBound ) &&
( fabs( fGradB ) <= ( fRelLen * fBound * 0.01 ) ) ) ( fabs( fGradB ) <= ( fRelLen * fBound * 0.01 ) ) )
{ {
bDeletePoint = true; bDeletePoint = true;

View File

@ -39,6 +39,7 @@
#include <opengl/VertexUtils.hxx> #include <opengl/VertexUtils.hxx>
#include <opengl/BufferObject.hxx> #include <opengl/BufferObject.hxx>
#include <cmath>
#include <vector> #include <vector>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
@ -1071,7 +1072,7 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
if( ixscale >= 2 && iyscale >= 2 ) // scale ratio less than 50% if( ixscale >= 2 && iyscale >= 2 ) // scale ratio less than 50%
{ {
areaScaling = true; areaScaling = true;
fastAreaScaling = ( ixscale == int( ixscale ) && iyscale == int( iyscale )); fastAreaScaling = ( ixscale == std::trunc( ixscale ) && iyscale == std::trunc( iyscale ));
// The generic case has arrays only up to 16 ratio downscaling and is performed in 2 passes, // The generic case has arrays only up to 16 ratio downscaling and is performed in 2 passes,
// when the ratio is in the 16-100 range, which is hopefully enough in practice, but protect // when the ratio is in the 16-100 range, which is hopefully enough in practice, but protect
// against buffer overflows in case such an extreme case happens (and in such case the precision // against buffer overflows in case such an extreme case happens (and in such case the precision

View File

@ -19,6 +19,8 @@
#include <sal/config.h> #include <sal/config.h>
#include <cmath>
#include <vcl/opengl/OpenGLHelper.hxx> #include <vcl/opengl/OpenGLHelper.hxx>
#include <vcl/bitmap.hxx> #include <vcl/bitmap.hxx>
@ -203,7 +205,7 @@ bool OpenGLSalBitmap::ImplScaleArea( const rtl::Reference< OpenGLContext > &xCon
double ixscale = 1 / rScaleX; double ixscale = 1 / rScaleX;
double iyscale = 1 / rScaleY; double iyscale = 1 / rScaleY;
bool fast = ( ixscale == int( ixscale ) && iyscale == int( iyscale ) bool fast = ( ixscale == std::trunc( ixscale ) && iyscale == std::trunc( iyscale )
&& int( nNewWidth * ixscale ) == mnWidth && int( nNewHeight * iyscale ) == mnHeight ); && int( nNewWidth * ixscale ) == mnWidth && int( nNewHeight * iyscale ) == mnHeight );
bool bTwoPasses = false; bool bTwoPasses = false;

View File

@ -78,6 +78,7 @@
#include <oox/token/tokens.hxx> #include <oox/token/tokens.hxx>
#include <cmath>
#include <map> #include <map>
#include <tuple> #include <tuple>
#include <unordered_map> #include <unordered_map>
@ -4586,7 +4587,8 @@ static util::DateTime lcl_dateTimeFromSerial(const double& dSerial)
DateTime d(Date(30, 12, 1899)); DateTime d(Date(30, 12, 1899));
d.AddDays( static_cast<sal_Int32>(dSerial) ); d.AddDays( static_cast<sal_Int32>(dSerial) );
double frac = dSerial - static_cast<sal_Int32>(dSerial); double dummy;
double frac = std::modf(dSerial, &dummy);
sal_uInt32 seconds = frac * secondsPerDay; sal_uInt32 seconds = frac * secondsPerDay;
util::DateTime date; util::DateTime date;

View File

@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <sal/config.h>
#include <cmath>
#include "propertyimport.hxx" #include "propertyimport.hxx"
#include <sax/tools/converter.hxx> #include <sax/tools/converter.hxx>
@ -182,7 +186,8 @@ Any PropertyConversion::convertString( const css::uno::Type& _rExpectedType,
{ {
case TYPE_DATE: case TYPE_DATE:
{ {
OSL_ENSURE((static_cast<sal_uInt32>(nValue)) - nValue == 0, double dummy;
OSL_ENSURE(std::modf(nValue, &dummy) == 0,
"PropertyConversion::convertString: a Date value with a fractional part?"); "PropertyConversion::convertString: a Date value with a fractional part?");
aReturn <<= lcl_getDate(nValue); aReturn <<= lcl_getDate(nValue);
} }