From d55bf9d5bf7a19dcfb6689f368a19c1b7ab942dc Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Fri, 29 Mar 2024 19:49:16 -0500 Subject: [PATCH] distributed/tria.cc: avoid FPE due to undefined behavior The following construct ``` static_cast(this_sc_point[dim]) ``` triggers a floating point exception when the stored double is -1.0 (at least with gcc-11 and avx512 instructions enabled). Judging from cppreference [1] this is undefined behavior: """ A prvalue of floating-point type can be converted to a prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded. If the truncated value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply). """ Thus, work around the issue by explicitly setting negative values to `numbers::invalid_subdomain_id` if we encounter -1. [1] https://en.cppreference.com/w/cpp/language/implicit_conversion --- source/distributed/tria.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/distributed/tria.cc b/source/distributed/tria.cc index 611248d2fc..e645050a93 100644 --- a/source/distributed/tria.cc +++ b/source/distributed/tria.cc @@ -3262,7 +3262,13 @@ namespace parallel // get a non-const view of the array double *this_sc_point = static_cast(sc_array_index_ssize_t(point_sc_array, i)); - owner_rank[i] = static_cast(this_sc_point[dim]); + Assert(this_sc_point[dim] >= 0. || this_sc_point[dim] == -1., + ExcInternalError()); + if (this_sc_point[dim] < 0.) + owner_rank[i] = numbers::invalid_subdomain_id; + else + owner_rank[i] = + static_cast(this_sc_point[dim]); } // reset the internal pointer to this triangulation -- 2.39.5