From: Dmitry Volyntsev Date: Sun, 30 Jul 2023 09:21:51 +0000 (+0100) Subject: Ignoring UndefinedBehaviorSanitizer warnings where appropriate. X-Git-Tag: 0.8.3~23 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=e005edcf6dcaa1b99925320696db6c2b1af81dec;p=njs.git Ignoring UndefinedBehaviorSanitizer warnings where appropriate. Prodded by David Carlier and Ben Kallus. --- diff --git a/auto/clang b/auto/clang index 270d6e59..27fe03b5 100644 --- a/auto/clang +++ b/auto/clang @@ -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 diff --git a/src/njs_clang.h b/src/njs_clang.h index 614b5090..8425f467 100644 --- a/src/njs_clang.h +++ b/src/njs_clang.h @@ -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 diff --git a/src/njs_number.c b/src/njs_number.c index 9f2d6512..48ecaf08 100644 --- a/src/njs_number.c +++ b/src/njs_number.c @@ -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; } } diff --git a/src/njs_number.h b/src/njs_number.h index 06836902..98137a5d 100644 --- a/src/njs_number.h +++ b/src/njs_number.h @@ -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; diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c index 945c0e2d..7b0abc63 100644 --- a/src/njs_typed_array.c +++ b/src/njs_typed_array.c @@ -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;