]> git.kaiwu.me - njs.git/commitdiff
Ignoring UndefinedBehaviorSanitizer warnings where appropriate.
authorDmitry Volyntsev <xeioex@nginx.com>
Sun, 30 Jul 2023 09:21:51 +0000 (10:21 +0100)
committerDmitry Volyntsev <xeioex@nginx.com>
Sun, 30 Jul 2023 09:21:51 +0000 (10:21 +0100)
Prodded by David Carlier and Ben Kallus.

auto/clang
src/njs_clang.h
src/njs_number.c
src/njs_number.h
src/njs_typed_array.c

index 270d6e5925baa87ba861d9d7a8e9730300ee583a..27fe03b5a60c11d0a7d0817f4475c1e09a3f8de1 100644 (file)
@@ -161,6 +161,17 @@ njs_feature_test="int main(int argc, char *argv[]) {
 . auto/feature
 
 
+njs_feature="GCC __attribute__ no_sanitize"
+njs_feature_name=NJS_HAVE_GCC_ATTRIBUTE_NO_SANITIZE
+njs_feature_run=no
+njs_feature_path=
+njs_feature_libs=
+njs_feature_test="__attribute__((no_sanitize(\"undefined\"))) int main(void) {
+                    return 0;
+                  }"
+. auto/feature
+
+
 njs_feature="Address sanitizer"
 njs_feature_name=NJS_HAVE_ADDRESS_SANITIZER
 njs_feature_run=no
index 614b509075db0f9d7fcc90263b99095268791ecf..8425f467808e8a8265bd477f1821476884b6fe98 100644 (file)
@@ -183,6 +183,31 @@ njs_leading_zeros64(uint64_t x)
 #define njs_msan_unpoison(ptr, size)
 #endif
 
+#if (NJS_HAVE_GCC_ATTRIBUTE_NO_SANITIZE)
+#define NJS_NOSANITIZE(options) __attribute__((no_sanitize(options)))
+#else
+#define NJS_NOSANITIZE(options)
+#endif
+
+
+njs_inline NJS_NOSANITIZE("float-cast-overflow") int64_t
+njs_unsafe_cast_double_to_int64(double num)
+{
+       /*
+        * Casting NaN to integer is undefined behavior,
+        * but it is fine in some cases where we do additional checks later.
+        * For example:
+        *  int64_t i64 = njs_unsafe_cast_double_to_int64(num);
+        *  if (i64 == num) {
+        *    // num is integer
+        *  }
+        *
+        * We do this as inline function to avoid UndefinedBehaviorSanitizer
+        * warnings.
+        */
+       return (int64_t) num;
+}
+
 
 #if (NJS_HAVE_DENORMALS_CONTROL)
 #include <xmmintrin.h>
index 9f2d651226d87cee349aa710b7cffdea7f9d5ea5..48ecaf08446b73885943aeea035ed423df7a2cbd 100644 (file)
@@ -382,7 +382,9 @@ njs_number_is_safe_integer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     if (nargs > 1 && njs_is_number(&args[1])) {
         num = njs_number(&args[1]);
 
-        if (num == (int64_t) num && fabs(num) <= NJS_MAX_SAFE_INTEGER) {
+        if (num == njs_unsafe_cast_double_to_int64(num)
+            && fabs(num) <= NJS_MAX_SAFE_INTEGER)
+        {
             integer = 1;
         }
     }
index 0683690216593f40291f992f9c8708af51c7799c..98137a5dd9030ee12b9211e044b081ee04563a75 100644 (file)
@@ -36,7 +36,7 @@ njs_int_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
 
-njs_inline njs_bool_t
+njs_inline NJS_NOSANITIZE("float-cast-overflow") njs_bool_t
 njs_number_is_integer_index(double num)
 {
     uint32_t  u32;
index 945c0e2deee255906446f6387c9e86fc45c081fc..7b0abc633bfb9ef04d795bf2d309b83926e18610 100644 (file)
@@ -1388,7 +1388,7 @@ njs_typed_array_prototype_index_of(njs_vm_t *vm, njs_value_t *args,
 
     v = njs_number(njs_argument(args, 1));
 
-    i64 = v;
+    i64 = njs_unsafe_cast_double_to_int64(v);
     integer = (v == i64);
 
     buffer = array->buffer;