]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use __builtin_*_overflow for isc_time_{add,subtract}()
authorOndřej Surý <ondrej@isc.org>
Wed, 20 Oct 2021 09:22:52 +0000 (11:22 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 21 Oct 2021 07:31:01 +0000 (09:31 +0200)
Use the __builtin_uadd_overflow() and __builtin_usub_overflow() for
overflow checks in isc_time_add() and isc_time_subtract().  This
generates more efficient and safe code.

configure.ac
lib/isc/time.c

index a3b54cbd71fbb1968e071dbd1963e69bbf7fcbc0..d17d8f20b2b7455f717a129f983c2da3f156a7d2 100644 (file)
@@ -1164,14 +1164,26 @@ AC_LINK_IFELSE(
      [[]],
      [[return (__builtin_clz(0xff) == 24 ? 1 : 0);]]
    )],
-  [have_builtin_clz=yes
-   AC_MSG_RESULT(yes)],
-  [have_builtin_clz=no
-   AC_MSG_RESULT(no)]
+  [AC_MSG_RESULT([yes])
+   AC_DEFINE(HAVE_BUILTIN_CLZ, 1, [Define to 1 if the compiler supports __builtin_clz.])
+  ],
+  [AC_MSG_RESULT([no])]
 )
-if test "yes" = "$have_builtin_clz"; then
-       AC_DEFINE(HAVE_BUILTIN_CLZ, 1, [Define to 1 if the compiler supports __builtin_clz.])
-fi
+
+#
+# Check for __builtin_uadd_overflow
+#
+AC_MSG_CHECKING([compiler support for __builtin_*_overflow()])
+AC_LINK_IFELSE(
+  [AC_LANG_PROGRAM(
+     [[#include <limits.h>]],
+     [[return (__builtin_uadd_overflow(UINT_MAX, UINT_MAX, &(unsigned int){ 0 }));]]
+   )],
+  [AC_MSG_RESULT([yes])
+   AC_DEFINE([HAVE_BUILTIN_OVERFLOW], [1], [define if the compiler supports __builtin_*_overflow().])
+  ],
+  [AC_MSG_RESULT([no])
+  ])
 
 #
 # Activate "rrset-order fixed" or not?
index 76b74a81ab73e3da405cce27631df4cd3ec51b25..77ac0da28faa743fdbefb731ffc329aa9dd12f1f 100644 (file)
@@ -231,10 +231,16 @@ isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) {
        REQUIRE(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
 
        /* Seconds */
+#if HAVE_BUILTIN_OVERFLOW
+       if (__builtin_uadd_overflow(t->seconds, i->seconds, &result->seconds)) {
+               return (ISC_R_RANGE);
+       }
+#else
        if (t->seconds > UINT_MAX - i->seconds) {
                return (ISC_R_RANGE);
        }
        result->seconds = t->seconds + i->seconds;
+#endif
 
        /* Nanoseconds */
        result->nanoseconds = t->nanoseconds + i->nanoseconds;
@@ -256,10 +262,16 @@ isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
        REQUIRE(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
 
        /* Seconds */
+#if HAVE_BUILTIN_OVERFLOW
+       if (__builtin_usub_overflow(t->seconds, i->seconds, &result->seconds)) {
+               return (ISC_R_RANGE);
+       }
+#else
        if (t->seconds < i->seconds) {
                return (ISC_R_RANGE);
        }
        result->seconds = t->seconds - i->seconds;
+#endif
 
        /* Nanoseconds */
        if (t->nanoseconds >= i->nanoseconds) {