[PATCH] libgst: Add alternative multiplication overflow check

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] libgst: Add alternative multiplication overflow check

Holger Freyther
From: Holger Hans Peter Freyther <[hidden email]>

Apple clang on OSX and the version on FreeBSD optimize the
multiplication check away. Clang introduced a family of
builtins to do the multiplication and check for the overflow
and GCC made the API usable. For clang we would need to know
if intptr_t is of type int, long int, long long int and
then use the smul, smull smulll.
Luckily clang is adopting the better interface and this is
what we are starting to use now. This means the new code
will be used on GCC5 (and later) and some future versions of
clang.

2015-11-07  Holger Hans Peter Freyther  <[hidden email]>

        * build-aux/overflow-builtins.m4: Add new macro.
        * configure.ac: Use GST_C_OVERFLOW_BUILTINS macro.

2015-11-07  Holger Hans Peter Freyther  <[hidden email]>

        * interp.inl: Add alternative mul_with_check implementation.
---
 ChangeLog                      |  5 +++++
 build-aux/overflow-builtins.m4 | 23 +++++++++++++++++++++++
 configure.ac                   |  1 +
 libgst/ChangeLog               |  4 ++++
 libgst/interp.inl              | 22 ++++++++++++++++++++++
 5 files changed, 55 insertions(+)
 create mode 100644 build-aux/overflow-builtins.m4

diff --git a/ChangeLog b/ChangeLog
index 61351a8..a40b68d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2015-11-07  Holger Hans Peter Freyther  <[hidden email]>
 
+ * build-aux/overflow-builtins.m4: Add new macro.
+ * configure.ac: Use GST_C_OVERFLOW_BUILTINS macro.
+
+2015-11-07  Holger Hans Peter Freyther  <[hidden email]>
+
  * configure.ac: Increase the version number after the
  release.
 
diff --git a/build-aux/overflow-builtins.m4 b/build-aux/overflow-builtins.m4
new file mode 100644
index 0000000..9d05019
--- /dev/null
+++ b/build-aux/overflow-builtins.m4
@@ -0,0 +1,23 @@
+dnl Check whether the host supports synchronization builtins.
+
+AC_DEFUN([GST_C_OVERFLOW_BUILTINS], [
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CACHE_CHECK([whether the host supports __builtin_mul_overflow],
+                 gst_cv_have_builtin_mul_overflow, [
+    save_CFLAGS="$CFLAGS"
+    case $host in
+      i?86-apple-darwin*) ;;
+      i?86-*-*) CFLAGS="$CFLAGS -march=i486" ;;
+    esac
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foovar = 0;]], [[
+if (__builtin_mul_overflow(44444, 55555, &foovar))
+ return 23;]])],
+   [gst_cv_have_builtin_mul_overflow=yes],
+   [gst_cv_have_builtin_mul_overflow=no])
+    CFLAGS="$save_CFLAGS"
+  ])
+  if test $gst_cv_have_builtin_mul_overflow = yes; then
+    AC_DEFINE(HAVE_OVERFLOW_BUILTINS, 1,
+              [Define to 1 if the host supports __builtin_*_overflow builtins])
+  fi
+])
diff --git a/configure.ac b/configure.ac
index e789be4..0bac23e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,6 +243,7 @@ GST_C_SYNC_BUILTINS
 if test $gst_cv_have_sync_fetch_and_add = no; then
   AC_MSG_ERROR([Synchronization primitives not found, please use a newer compiler.])
 fi
+GST_C_OVERFLOW_BUILTINS
 
 GST_LOCK
 AC_SYS_LARGEFILE
diff --git a/libgst/ChangeLog b/libgst/ChangeLog
index cbb26c6..3e513de 100644
--- a/libgst/ChangeLog
+++ b/libgst/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-07  Holger Hans Peter Freyther  <[hidden email]>
+
+ * interp.inl: Add alternative mul_with_check implementation.
+
 2015-08-02  Holger Hans Peter Freyther  <[hidden email]>
 
  * events.c: Use else instead of else if in
diff --git a/libgst/interp.inl b/libgst/interp.inl
index e18e27c..dbc631b 100644
--- a/libgst/interp.inl
+++ b/libgst/interp.inl
@@ -159,6 +159,27 @@ sub_with_check (OOP op1, OOP op2, mst_Boolean *overflow)
 OOP
 mul_with_check (OOP op1, OOP op2, mst_Boolean *overflow)
 {
+#ifdef HAVE_OVERFLOW_BUILTINS
+  intptr_t a = TO_INT (op1);
+  intptr_t b = TO_INT (op2);
+  intptr_t result;
+
+  if (__builtin_mul_overflow(a, b, &result))
+    {
+       *overflow = true;
+       return FROM_INT(0);
+    }
+
+
+  if (result < MIN_ST_INT || result > MAX_ST_INT)
+    {
+       *overflow = true;
+       return FROM_INT(0);
+    }
+
+  *overflow = false;
+  return FROM_INT(result);
+#else
   intptr_t a = TO_INT (op1);
   intptr_t b = TO_INT (op2);
   intmax_t result = (intmax_t)a * b;
@@ -188,6 +209,7 @@ mul_with_check (OOP op1, OOP op2, mst_Boolean *overflow)
     }
 
   return FROM_INT (0);
+#endif
 }
 
 /* State of the random generator.
--
2.6.0


_______________________________________________
help-smalltalk mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-smalltalk