From: Matthias Maier Date: Sat, 30 Mar 2024 00:49:16 +0000 (-0500) Subject: distributed/tria.cc: avoid FPE due to undefined behavior X-Git-Tag: v9.6.0-rc1~424^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d55bf9d5bf7a19dcfb6689f368a19c1b7ab942dc;p=dealii.git 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 --- 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