[bug_16512] dot division fixed when the rigth hand side is null. 65/21565/3
Cedric Delamarre [Fri, 31 Jul 2020 14:16:41 +0000 (16:16 +0200)]
Change-Id: Ia10a54264b1937a8428ae8b8661f922fdc4bb91d

scilab/CHANGES.md
scilab/modules/ast/includes/operations/types_dotdivide.hxx
scilab/modules/integer/macros/%i_d_s.sci [deleted file]
scilab/modules/integer/macros/%i_r_s.sci
scilab/modules/integer/macros/%s_d_i.sci [deleted file]
scilab/modules/integer/macros/%s_r_i.sci
scilab/modules/integer/tests/nonreg_tests/bug_16512.tst [new file with mode: 0644]

index eb04414..131077e 100644 (file)
@@ -323,6 +323,7 @@ Bug Fixes
 * [#16473](https://bugzilla.scilab.org/16473): Deleting rows in a sparse squared the matrix with padding zeros (Scilab 6 regression).
 * [#16474](https://bugzilla.scilab.org/16474): `imult(%z)` crashed Scilab.
 * [#16496](https://bugzilla.scilab.org/16496): The `getdate` page should be rewritten: a) `getdate("s")` does NOT take leap seconds into account. b) `D=getdate(X)` is vectorized, accepts fractional seconds and returns them in [0,1) in D(10) instead of milliseconds. Moreover, the time referential of the result was unclear (time zone, daylight saving offset).
+* [#16512](https://bugzilla.scilab.org/16512): 1 ./ uint8(0) crashes Scilab (idem with int8, uint16, int16, uint32, int32, uint64, int64).
 * [#16517](https://bugzilla.scilab.org/16517): `getdate("s")` truncated the actual time to integer seconds. `getdate(u)(10)` returned fractional seconds instead of milliseconds as `getdate()`.
 * [#16522](https://bugzilla.scilab.org/16522): `bitget(x,pos)` and `bitset(x,pos)` results could be wrong when `pos` is an encoded integer.
 * [#16525](https://bugzilla.scilab.org/16525): `soundsec(t,freq)` has the trivial equivalence `0 : 1/freq : t*(1-%eps)` and should be removed.
index 59d1460..ee33d41 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef __TYPES_DOTDIVIDE_HXX__
 #define __TYPES_DOTDIVIDE_HXX__
 
+#include <limits>
+
 #include "generic_operations.hxx"
 #include "configvariable.hxx"
 #include "double.hxx"
@@ -94,13 +96,35 @@ template<> types::InternalType* dotdiv_M_M<types::Polynom, types::Double, types:
 template<> types::InternalType* dotdiv_M_M<types::Double, types::Polynom, types::Polynom>(types::Double* _pL, types::Polynom* _pR);
 
 //x1 ./ x1
+template<typename T, typename U> inline static void dotdiv(T l, U r, double* o)
+{
+    if (r == 0)
+    {
+        ConfigVariable::setDivideByZero(true);
+    }
+    *o = (double)l / (double)r;
+}
+
 template<typename T, typename U, typename O> inline static void dotdiv(T l, U r, O* o)
 {
     if ((O)r == 0)
     {
         ConfigVariable::setDivideByZero(true);
+        double tmp = (double)l / (double)r;
+        if (std::isnan(tmp))
+        {
+            *o = 0;
+        }
+        else if (std::isinf(tmp))
+        {
+            tmp < 0 ? *o = std::numeric_limits<O>::min() : *o = std::numeric_limits<O>::max();
+        }
+        // no else because division by zero result to nan or inf
+    }
+    else
+    {
+        *o = (O)l / (O)r;
     }
-    *o = (O)l / (O)r;
 }
 
 //x1 ./ x1c
diff --git a/scilab/modules/integer/macros/%i_d_s.sci b/scilab/modules/integer/macros/%i_d_s.sci
deleted file mode 100644 (file)
index a9e123e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA -
-// Copyright (C) 2013 - Samuel GOUGEON : http://bugzilla.scilab.org/13000
-
-// Copyright (C) 2012 - 2016 - Scilab Enterprises
-//
-// This file is hereby licensed under the terms of the GNU GPL v2.0,
-// pursuant to article 5.3.4 of the CeCILL v.2.1.
-// This file was originally licensed under the terms of the CeCILL v2.1,
-// and continues to be available under such terms.
-// For more information, see the COPYING file which you should have received
-// along with this program.
-
-function r = %i_d_s(a,b)
-    if b==[] then
-        r = []
-    else
-        r = a./iconvert(b,inttype(a))
-    end
-endfunction
index f1d1792..56c9262 100644 (file)
@@ -12,7 +12,8 @@
 
 
 function r=%i_r_s(a,b)
-
+    // int / double
     if b==[] then r=[],end
-    r=a/iconvert(b,inttype(a))
+    r = double(a) / b
+    r = iconvert(r, inttype(a))
 endfunction
diff --git a/scilab/modules/integer/macros/%s_d_i.sci b/scilab/modules/integer/macros/%s_d_i.sci
deleted file mode 100644 (file)
index f8f460e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA -
-// Copyright (C) 2013 - Samuel GOUGEON : http://bugzilla.scilab.org/13000
-//
-// Copyright (C) 2012 - 2016 - Scilab Enterprises
-//
-// This file is hereby licensed under the terms of the GNU GPL v2.0,
-// pursuant to article 5.3.4 of the CeCILL v.2.1.
-// This file was originally licensed under the terms of the CeCILL v2.1,
-// and continues to be available under such terms.
-// For more information, see the COPYING file which you should have received
-// along with this program.
-
-
-function r = %s_d_i(a,b)
-    if a==[] then
-        r = []
-    else
-        r = iconvert(a,inttype(b))./b
-    end
-endfunction
index e869a2e..f39bc8f 100644 (file)
@@ -12,7 +12,8 @@
 
 
 function r=%s_r_i(a,b)
-
+    // double / int
     if a==[] then r=[],end
-    r=iconvert(a,inttype(b))/b
+    r = a / double(b)
+    r = iconvert(r, inttype(b))
 endfunction
diff --git a/scilab/modules/integer/tests/nonreg_tests/bug_16512.tst b/scilab/modules/integer/tests/nonreg_tests/bug_16512.tst
new file mode 100644 (file)
index 0000000..2cc9e5a
--- /dev/null
@@ -0,0 +1,28 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 16511 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/16512
+//
+// <-- Short Description -->
+// 1 ./ uint8(0) crashes Scilab
+
+for cast = list(int8, int16, int32, int64, uint8, uint16, uint32, uint64)
+    assert_checkequal(1 ./ cast(0),  1 / cast(0));
+    assert_checkequal(-1 ./ cast(0),  -1 / cast(0));
+    assert_checkequal(1 ./ -cast(0),  1 / -cast(0));
+    assert_checkequal(-1 ./ -cast(0),  -1 / -cast(0));
+    assert_checkequal(cast(1)  ./ 0, cast(1) / 0);
+    assert_checkequal(-cast(1)  ./ 0, -cast(1) / 0);
+    assert_checkequal(cast(1)  ./ -0, cast(1) / -0);
+    assert_checkequal(-cast(1)  ./ -0, -cast(1) / -0);
+end