]> https://gitweb.dealii.org/ - dealii.git/commitdiff
distributed/tria.cc: avoid FPE due to undefined behavior 16820/head
authorMatthias Maier <tamiko@43-1.org>
Sat, 30 Mar 2024 00:49:16 +0000 (19:49 -0500)
committerMatthias Maier <tamiko@43-1.org>
Sat, 30 Mar 2024 00:49:16 +0000 (19:49 -0500)
The following construct
```
static_cast<types::subdomain_id>(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

index 611248d2fc1cc654ba0d616dc9389c6d709353ff..e645050a93a94f833fa6e9c9329ee3064fa6e643 100644 (file)
@@ -3262,7 +3262,13 @@ namespace parallel
           // get a non-const view of the array
           double *this_sc_point =
             static_cast<double *>(sc_array_index_ssize_t(point_sc_array, i));
-          owner_rank[i] = static_cast<types::subdomain_id>(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<types::subdomain_id>(this_sc_point[dim]);
         }
 
       // reset the internal pointer to this triangulation

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.