[clang-tools-extra] [clang-tidy] Create bugprone-bit-cast-pointers check (PR #108083)

Julian Schmidt via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 11 11:55:49 PDT 2024


================
@@ -0,0 +1,40 @@
+.. title:: clang-tidy - bugprone-bit-cast-pointers
+
+bugprone-bit-cast-pointers
+==========================
+
+Warns about usage of ``std::bit_cast`` when the input and output types are
+pointers.
+
+The motivation is that ``std::bit_cast`` is advertised as the safe alternative
+to type punning via ``reinterpret_cast`` in modern C++. However, one should not
+blindly replace ``reinterpret_cast`` with ``std::bit_cast``, as follows:
+
+.. code-block:: c++
+
+    int x{};
+    -float y = *reinterpret_cast<float*>(&x);
+    +float y = *std::bit_cast<float*>(&x);
+
+The drop-in replacement behaves exactly the same as ``reinterpret_cast``, and
+Undefined Behavior is still invoked. ``std::bit_cast`` is copying the bytes of
+the input pointer, not the pointee, into an output pointer of a different type,
+which may violate the strict aliasing rules. However, simply looking at the
+code, it looks "safe", because it uses ``std::bit_cast`` which is advertised as
+safe.
+
+The solution to safe type punning is to apply ``std::bit_cast`` on value types,
+not on pointer types:
+
+.. code-block:: c++
+
+    int x{};
+    float y = std::bit_cast<float>(x);
+
+This way, the bytes of the input object are copied into the output object, which
+is safe from Undefined Behavior. Compilers are able to optimize this copy and
----------------
5chmidti wrote:

> safe from undefined Behavior

Seems to be not technically the case, according to https://en.cppreference.com/w/cpp/numeric/bit_cast

> If there is no value of type To corresponding to the value representation produced, the behavior is undefined.

> <c++26 For each bit in the value representation of the result that is indeterminate, the smallest object containing that bit has an indeterminate value; the behavior is undefined unless that object is of an [uninitialized-friendly type](https://en.cppreference.com/w/cpp/language/default_initialization#Special_cases).

> \>=c++26 if [bit] b is indeterminate, the behavior is undefined.

I think `[much] safer` would be correctly qualified.

https://github.com/llvm/llvm-project/pull/108083


More information about the cfe-commits mailing list