[Libreoffice-commits] core.git: sc/qa
Stephan Bergmann
sbergman at redhat.com
Thu Aug 13 02:36:11 PDT 2015
On 08/12/2015 05:53 PM, Eike Rathke wrote:
> On Wednesday, 2015-08-12 17:48:57 +0200, Eike Rathke wrote:
>>>> The new test code triggers a division by zero now (as seen with
>>>> -fsanitize=undefined):
>>>
>>> First, that shouldn't matter as it produces a double INF value.
>>
>> I wonder though why that didn't propagate into the += operation and
>> whether that behavior is really undefined.. the test should had failed
>> already.
>
> Seeing that it already tested for an error things should be correct.
>
> So, should fsanitize maybe be taught about double infinity? ;)
...or, developers be taught about the C++ Standard? ;) It is quite
clear on this: "If the second operand of / or % is zero the behavior is
undefined." ([expr.mul]/4)
Now, ISO/IEC 60559 may mandate the result of division by zero to be
infinity under certain circumstances (if the dividend is finite and
non-zero) an NaN otherwise, when operating in its default exception
handling mode, and C++ implementations may follow that, and we may even
require that at least certain parts of the LO code base must be executed
in conformance to ISO/IEC 60559 in its default exception handling mode.
However, in other parts of the LO code base it might be unexpected that
floating-point division by zero happens, and its occurrence might
indicate a bug (cf. "git log --grep -fsanitize=float-divide-by-zero"),
so I'm reluctant to disable -fsanitize=float-divide-by-zero wholesale.
For those places where we apparently require floating-point division to
adhere to ISO/IEC 60559 in its default exception handling mode, would it
be possible to "dress those up" (like in the below ad-hoc patch), or
would that be unreasonable?
> diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
> index ce3dc91..a0e02b1 100644
> --- a/sc/source/core/tool/interpr3.cxx
> +++ b/sc/source/core/tool/interpr3.cxx
> @@ -30,11 +30,12 @@
> #include "scmatrix.hxx"
> #include "globstr.hrc"
>
> -#include <math.h>
> +#include <cmath>
> #include <vector>
> #include <algorithm>
> #include <boost/math/special_functions/log1p.hpp>
> #include <comphelper/random.hxx>
> +#include <config_options.h>
>
> using ::std::vector;
> using namespace formula;
> @@ -2821,6 +2822,23 @@ void ScInterpreter::ScFTest()
> PushDouble(2.0*GetFDist(fF, fF1, fF2));
> }
>
> +namespace {
> +
> +double divide(double a, double b) {
> +#if !ENABLE_RUNTIME_OPTIMIZATIONS
> + if (b == 0) {
> + if (std::isfinite(a) && a != 0) {
> + return std::copysign(INFINITY, a);
> + } else {
> + return NAN;
> + }
> + }
> +#endif
> + return a / b;
> +}
> +
> +}
> +
> void ScInterpreter::ScChiTest()
> {
> if ( !MustHaveParamCount( GetByte(), 2 ) )
> @@ -2850,7 +2868,7 @@ void ScInterpreter::ScChiTest()
> {
> double fValX = pMat1->GetDouble(i,j);
> double fValE = pMat2->GetDouble(i,j);
> - fChi += (fValX - fValE) * (fValX - fValE) / fValE;
> + fChi += divide((fValX - fValE) * (fValX - fValE), fValE);
> }
> else
> {
More information about the LibreOffice
mailing list