chart2/source/tools/PolynomialRegressionCurveCalculator.cxx |    2 -
 chart2/source/view/charttypes/PieChart.cxx                  |    2 -
 include/o3tl/safeint.hxx                                    |    9 ++++++
 include/vcl/outdev.hxx                                      |    3 +-
 sc/inc/kahan.hxx                                            |    5 ++-
 sc/source/core/tool/interpr2.cxx                            |   18 ++++++------
 sc/source/core/tool/interpr3.cxx                            |    8 ++---
 sc/source/core/tool/interpr5.cxx                            |    4 +-
 sc/source/core/tool/interpr6.cxx                            |    6 ++--
 sc/source/core/tool/interpr8.cxx                            |    2 -
 sc/source/core/tool/subtotal.cxx                            |    2 -
 scaddins/source/analysis/analysishelper.cxx                 |    8 +----
 scaddins/source/analysis/financial.cxx                      |    2 -
 13 files changed, 40 insertions(+), 31 deletions(-)

New commits:
commit 2df011d176a4f851de7e30fc0084f55b33478b2f
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Sun Aug 17 11:53:34 2025 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Sun Aug 17 15:34:40 2025 +0200

    cid#1664822 silence Uncaught exception
    
    Change-Id: I417bdfaf9b5bc09a3ff3472d288bc36dc2cb11d6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189825
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index fb61ff86b123..4ec08b257bf2 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -61,6 +61,7 @@
 
 #include <unotools/fontdefs.hxx>
 #include <cppuhelper/weakref.hxx>
+#include <o3tl/deleter.hxx>
 
 #include <com/sun/star/drawing/LineCap.hpp>
 #include <com/sun/star/uno/Reference.h>
@@ -1923,7 +1924,7 @@ protected:
     struct OutputDeviceRestoreStateGuard
     {
         OutputDevice& m_rDev;
-        ~OutputDeviceRestoreStateGuard() { m_rDev.Pop(); }
+        ~OutputDeviceRestoreStateGuard() { 
suppress_fun_call_w_exception(m_rDev.Pop()); }
     };
 
     Push(nFlags);
commit 23f77eb0e294013716c172a7ea92350253c3d6f3
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Thu Aug 14 09:19:34 2025 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Sun Aug 17 15:34:28 2025 +0200

    cid#1660546 suppress Division or modulo by float zero
    
    in spreadsheet related code, similar to runtime cases of
    bin/sanitize-excludelist.txt but probably more dubious.
    
    also:
    
    cid#1660554 Division or modulo by float zero
    cid#1660545 Division or modulo by float zero
    cid#1660527 Division or modulo by float zero
    cid#1660501 Division or modulo by float zero
    cid#1660485 Division or modulo by float zero
    cid#1660442 Division or modulo by float zero
    cid#1660396 Division or modulo by float zero
    cid#1660241 Division or modulo by float zero
    cid#1660134 Division or modulo by float zero
    cid#1660066 Division or modulo by float zero
    cid#1659994 Division or modulo by float zero
    cid#1659979 Division or modulo by float zero
    cid#1659964 Division or modulo by float zero
    cid#1659940 Division or modulo by float zero
    cid#1659913 Division or modulo by float zero
    cid#1659893 Division or modulo by float zero
    cid#1659890 Division or modulo by float zero
    cid#1659868 Division or modulo by float zero
    cid#1659745 Division or modulo by float zero
    cid#1659721 Division or modulo by float zero
    cid#1659711 Division or modulo by float zero
    cid#1659611 Division or modulo by float zero
    cid#1659814 Division or modulo by float zero
    
    Change-Id: I29830cad3170e5e45348f7bd4e08f028d21a4543
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189823
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx 
b/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx
index f8921d73c266..1f2ea3e3e965 100644
--- a/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx
+++ b/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx
@@ -151,7 +151,7 @@ void SAL_CALL 
PolynomialRegressionCurveCalculator::recalculateRegression(
         double fSumXY = lcl_GetDotProduct(xVector, yVector);
         double fSumX2 = lcl_GetDotProduct(xVector, xVector);
 
-        double fSlope = fSumXY / fSumX2;
+        double fSlope = o3tl::div_allow_zero(fSumXY, fSumX2);
 
         if (!mForceIntercept)
         {
diff --git a/chart2/source/view/charttypes/PieChart.cxx 
b/chart2/source/view/charttypes/PieChart.cxx
index 3fc7968fa23f..812cfb66babe 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -1421,7 +1421,7 @@ void PieChart::createOneBar(
         rtl::Reference<SvxShapeGroupAnyD> xSeriesGroupShape_Shapes = 
getSeriesGroupShape(pSeries, xSeriesTarget);
 
         ///collect data point information (logic coordinates, style ):
-        double fY = pDataSrc->getData(pSeries, nPointIndex, eType) / barSum;
+        double fY = o3tl::div_allow_zero(pDataSrc->getData(pSeries, 
nPointIndex, eType), barSum);
         if( std::isnan(fY) )
             continue;
         if(fY==0.0)//@todo: continue also if the resolution is too small
diff --git a/include/o3tl/safeint.hxx b/include/o3tl/safeint.hxx
index a57f5f269d09..94a109fa2799 100644
--- a/include/o3tl/safeint.hxx
+++ b/include/o3tl/safeint.hxx
@@ -234,6 +234,15 @@ template<typename T> [[nodiscard]] inline T 
sanitizing_min(T a, T b)
     return std::min(a, b);
 }
 
+// For use when std::inf is an acceptable result
+[[nodiscard]] inline double div_allow_zero(double a, double b)
+{
+#if defined(__COVERITY__) && __COVERITY_MAJOR__ <= 2024
+    assert(b != 0 && "suppress floating point divide_by_zero");
+#endif
+    return a / b;
+}
+
 // To sanitize in/de-crementing value where the result is known by the caller 
to be guaranteed to fit in
 // the source type range without over/under-flow
 [[nodiscard]] inline unsigned short sanitizing_inc(unsigned short value)
diff --git a/sc/inc/kahan.hxx b/sc/inc/kahan.hxx
index c2560635fbdf..de3014b42ed9 100644
--- a/sc/inc/kahan.hxx
+++ b/sc/inc/kahan.hxx
@@ -215,7 +215,10 @@ public:
 
     inline KahanSum operator*(double fTimes) const { return get() * fTimes; }
 
-    inline KahanSum operator/(const KahanSum& fDivides) const { return get() / 
fDivides.get(); }
+    inline KahanSum operator/(const KahanSum& fDivides) const
+    {
+        return o3tl::div_allow_zero(get(), fDivides.get());
+    }
 
     inline KahanSum operator/(double fDivides) const { return get() / 
fDivides; }
 
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index c71bbc39d88d..a4e390e13fc1 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -1506,7 +1506,7 @@ void ScInterpreter::ScIRR()
             }
             SetError(nIterError);
         }
-        double xNew = x - fNom.get() / fDenom.get();  // x(i+1) = 
x(i)-f(x(i))/f'(x(i))
+        double xNew = x - o3tl::div_allow_zero(fNom.get(), fDenom.get());  // 
x(i+1) = x(i)-f(x(i))/f'(x(i))
         nItCount++;
         fEps = std::abs(xNew - x);
         x = xNew;
@@ -1636,7 +1636,7 @@ void ScInterpreter::ScMIRR()
             PushError( nGlobalError );
         else
         {
-            double fResult = -fNPV_reinvest.get() / fNPV_invest.get();
+            double fResult = -o3tl::div_allow_zero(fNPV_reinvest.get(), 
fNPV_invest.get());
             fResult *= pow( fRate1_reinvest, static_cast<double>( nCount - 1 ) 
);
             fResult = pow( fResult, div( 1.0, (nCount - 1)) );
             PushDouble( fResult - 1.0 );
@@ -1656,7 +1656,7 @@ void ScInterpreter::ScISPMT()
         if( nGlobalError != FormulaError::NONE )
             PushError( nGlobalError);
         else
-            PushDouble( fInvest * fRate * (fPeriod / fTotal - 1.0) );
+            PushDouble( fInvest * fRate * (o3tl::div_allow_zero(fPeriod, 
fTotal) - 1.0) );
     }
 }
 
@@ -1704,8 +1704,8 @@ void ScInterpreter::ScSYD()
         double fLife = GetDouble();
         double fSalvage = GetDouble();
         double fCost = GetDouble();
-        double fSyd = ((fCost - fSalvage) * (fLife - fPer + 1.0)) /
-                      ((fLife * (fLife + 1.0)) / 2.0);
+        double fSyd = o3tl::div_allow_zero((fCost - fSalvage) * (fLife - fPer 
+ 1.0),
+                      (fLife * (fLife + 1.0)) / 2.0);
         PushDouble(fSyd);
     }
 }
@@ -1714,7 +1714,7 @@ double ScInterpreter::ScGetDDB(double fCost, double 
fSalvage, double fLife,
                 double fPeriod, double fFactor)
 {
     double fDdb, fRate, fOldValue, fNewValue;
-    fRate = fFactor / fLife;
+    fRate = o3tl::div_allow_zero(fFactor, fLife);
     if (fRate >= 1.0)
     {
         fRate = 1.0;
@@ -1941,7 +1941,7 @@ double ScInterpreter::ScGetPMT(double fRate, double 
fNper, double fPv,
 {
     double fPayment;
     if (fRate == 0.0)
-        fPayment = (fPv + fFv) / fNper;
+        fPayment = o3tl::div_allow_zero(fPv + fFv, fNper);
     else
     {
         if (bPayInAdvance) // payment in advance
@@ -2029,9 +2029,9 @@ void ScInterpreter::ScNper()
     if ( fPV + fFV == 0.0 )
         PushDouble( 0.0 );
     else if (fRate == 0.0)
-        PushDouble(-(fPV + fFV)/fPmt);
+        PushDouble(-o3tl::div_allow_zero(fPV + fFV, fPmt));
     else if (bPayInAdvance)
-        
PushDouble(log(-(fRate*fFV-fPmt*(1.0+fRate))/(fRate*fPV+fPmt*(1.0+fRate)))
+        PushDouble(log(-o3tl::div_allow_zero(fRate*fFV-fPmt*(1.0+fRate), 
(fRate*fPV+fPmt*(1.0+fRate))))
                   / std::log1p(fRate));
     else
         PushDouble(log(-(fRate*fFV-fPmt)/(fRate*fPV+fPmt)) / 
std::log1p(fRate));
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index 505f551d73db..ba53101f5e16 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -257,7 +257,7 @@ double ScInterpreter::gauss(double x)
     else
     {
         static const double asympt[] = { -1.0, 1.0, -3.0, 15.0, -105.0 };
-        nVal = 0.5 + phi(xAbs) * taylor(asympt, 4, 1.0 / (xAbs * xAbs)) / xAbs;
+        nVal = 0.5 + phi(xAbs) * o3tl::div_allow_zero(taylor(asympt, 4, 
o3tl::div_allow_zero(1.0, xAbs * xAbs)), xAbs);
     }
     if (x < 0.0)
         return -nVal;
@@ -812,7 +812,7 @@ double ScInterpreter::GetBeta(double fAlpha, double fBeta)
         fA = fBeta; fB = fAlpha;
     }
     if (fA+fB < fMaxGammaArgument) // simple case
-        return GetGamma(fA)/GetGamma(fA+fB)*GetGamma(fB);
+        return o3tl::div_allow_zero(GetGamma(fA), GetGamma(fA+fB)) * 
GetGamma(fB);
     // need logarithm
     // GetLogGamma is not accurate enough, back to Lanczos for all three
     // GetGamma and arrange factors newly.
@@ -3019,7 +3019,7 @@ void ScInterpreter::ScHarMean()
         }
     }
     if (nGlobalError == FormulaError::NONE)
-        PushDouble( nValCount / nVal.get() );
+        PushDouble( o3tl::div_allow_zero(nValCount, nVal.get()) );
     else
         PushError( nGlobalError);
 }
@@ -3191,7 +3191,7 @@ void ScInterpreter::ScGeoMean()
         }
     }
     if (nGlobalError == FormulaError::NONE)
-        PushDouble(exp(nVal.get() / nValCount));
+        PushDouble(exp(o3tl::div_allow_zero(nVal.get(), nValCount)));
     else
         PushError( nGlobalError);
 }
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 15f013f33fb1..b660d53df1b5 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -2121,7 +2121,7 @@ void lcl_ApplyHouseholderTransformation(const 
ScMatrixRef& pMatA, SCSIZE nC,
     // ScMatrix matrices are zero based, index access (column,row)
     double fDenominator = lcl_GetColumnSumProduct(pMatA, nC, pMatA, nC, nC, 
nN);
     double fNumerator = lcl_GetColumnSumProduct(pMatA, nC, pMatY, 0, nC, nN);
-    double fFactor = 2.0 * (fNumerator/fDenominator);
+    double fFactor = 2.0 * o3tl::div_allow_zero(fNumerator, fDenominator);
     for (SCSIZE row = nC; row < nN; row++)
         pMatY->PutDouble(
             pMatY->GetDouble(row) - fFactor * pMatA->GetDouble(nC,row), row);
@@ -2134,7 +2134,7 @@ void lcl_TApplyHouseholderTransformation(const 
ScMatrixRef& pMatA, SCSIZE nR,
     // ScMatrix matrices are zero based, index access (column,row)
     double fDenominator = lcl_TGetColumnSumProduct(pMatA, nR, pMatA, nR, nR, 
nN);
     double fNumerator = lcl_TGetColumnSumProduct(pMatA, nR, pMatY, 0, nR, nN);
-    double fFactor = 2.0 * (fNumerator/fDenominator);
+    double fFactor = 2.0 * o3tl::div_allow_zero(fNumerator, fDenominator);
     for (SCSIZE col = nR; col < nN; col++)
         pMatY->PutDouble(
           pMatY->GetDouble(col) - fFactor * pMatA->GetDouble(col,nR), col);
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index 2d6a38a3c6b1..6d9889841a97 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -96,7 +96,7 @@ double ScInterpreter::GetGammaContFraction( double fA, double 
fX )
 double ScInterpreter::GetGammaSeries( double fA, double fX )
 {
     double fDenomfactor = fA;
-    double fSummand = 1.0/fA;
+    double fSummand = o3tl::div_allow_zero(1.0, fA);
     double fSum = fSummand;
     int nCount=1;
     do
@@ -171,7 +171,7 @@ double ScInterpreter::GetGammaDistPDF( double fX, double 
fAlpha, double fLambda
             const double fLogDblMax = log( 
::std::numeric_limits<double>::max());
             if (log(fXr) * (fAlpha-1.0) < fLogDblMax && fAlpha < 
fMaxGammaArgument)
             {
-                return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda / 
GetGamma(fAlpha);
+                return o3tl::div_allow_zero(pow( fXr, fAlpha-1.0) * exp(-fXr) 
/ fLambda, GetGamma(fAlpha));
             }
             else
             {
@@ -182,7 +182,7 @@ double ScInterpreter::GetGammaDistPDF( double fX, double 
fAlpha, double fLambda
         {
             if (fAlpha<fMaxGammaArgument)
             {
-                return pow( fXr, fAlpha-1.0) * exp(-fXr) / fLambda / 
GetGamma(fAlpha);
+                return o3tl::div_allow_zero(pow( fXr, fAlpha-1.0) * exp(-fXr) 
/ fLambda, GetGamma(fAlpha));
             }
             else
             {
diff --git a/sc/source/core/tool/interpr8.cxx b/sc/source/core/tool/interpr8.cxx
index 1c53c7ba4932..05e38e0f19c1 100644
--- a/sc/source/core/tool/interpr8.cxx
+++ b/sc/source/core/tool/interpr8.cxx
@@ -521,7 +521,7 @@ void ScETSForecastCalculation::calcAccuracyIndicators()
 
     int nCalcCount = mnCount - 1;
     mfMAE   = fSumAbsErr.get() / nCalcCount;
-    mfMASE  = fSumAbsErr.get() / ( nCalcCount * fSumDivisor.get() / ( 
nCalcCount - 1 ) );
+    mfMASE  = o3tl::div_allow_zero(fSumAbsErr.get(), nCalcCount * 
fSumDivisor.get() / ( nCalcCount - 1 ));
     mfMSE   = fSumErrSq.get() / nCalcCount;
     mfRMSE  = sqrt( mfMSE );
     mfSMAPE = fSumAbsPercErr.get() * 2.0 / nCalcCount;
diff --git a/sc/source/core/tool/subtotal.cxx b/sc/source/core/tool/subtotal.cxx
index 4c213893b14d..ed9c6c478127 100644
--- a/sc/source/core/tool/subtotal.cxx
+++ b/sc/source/core/tool/subtotal.cxx
@@ -54,7 +54,7 @@ bool SubTotal::SafeDiv(double& fVal1, double fVal2)
 {
     bool bOk = true;
     SAL_MATH_FPEXCEPTIONS_OFF();
-    fVal1 /= fVal2;
+    fVal1 = o3tl::div_allow_zero(fVal1, fVal2);
     if (!std::isfinite(fVal1))
     {
         bOk = false;
diff --git a/scaddins/source/analysis/analysishelper.cxx 
b/scaddins/source/analysis/analysishelper.cxx
index 73673bd4e593..d228667e25b9 100644
--- a/scaddins/source/analysis/analysishelper.cxx
+++ b/scaddins/source/analysis/analysishelper.cxx
@@ -1065,9 +1065,7 @@ double GetYieldmat( sal_Int32 nNullDate, sal_Int32 
nSettle, sal_Int32 nMat, sal_
     double      y = 1.0 + fIssMat * fRate;
     y /= fPrice / 100.0 + fIssSet * fRate;
     y--;
-    y /= fSetMat;
-
-    return y;
+    return o3tl::div_allow_zero(y, fSetMat);
 }
 
 
@@ -1195,9 +1193,7 @@ double GetOddlyield( sal_Int32 nNullDate, sal_Int32 
nSettle, sal_Int32 nMat, sal
     double      y = fRedemp + fDCi * 100.0 * fRate / fFreq;
     y /= fPrice + fAi * 100.0 * fRate / fFreq;
     y--;
-    y *= fFreq / fDSCi;
-
-    return y;
+    return y * o3tl::div_allow_zero(fFreq, fDSCi);
 }
 
 
diff --git a/scaddins/source/analysis/financial.cxx 
b/scaddins/source/analysis/financial.cxx
index 074d8ff4fe2d..dcc7f0554e9f 100644
--- a/scaddins/source/analysis/financial.cxx
+++ b/scaddins/source/analysis/financial.cxx
@@ -553,7 +553,7 @@ double SAL_CALL AnalysisAddIn::getXirr(
         do
         {
             fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
-            double fNewRate = fResultRate - fResultValue / 
lcl_sca_XirrResult_Deriv1( aValues, aDates, fResultRate );
+            double fNewRate = fResultRate - o3tl::div_allow_zero(fResultValue, 
lcl_sca_XirrResult_Deriv1(aValues, aDates, fResultRate));
             double fRateEps = fabs( fNewRate - fResultRate );
             fResultRate = fNewRate;
             bContLoop = (fRateEps > fMaxEps) && (fabs( fResultValue ) > 
fMaxEps);

Reply via email to