[clang] [clang] Implement -fstrict-bool (PR #160790)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 2 10:58:37 PST 2025


=?utf-8?q?Félix?= Cloutier <fcloutier at apple.com>,
=?utf-8?q?Félix?= Cloutier <fcloutier at apple.com>,
=?utf-8?q?Félix?= Cloutier <fcloutier at apple.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/160790 at github.com>


================
@@ -2312,6 +2312,30 @@ are listed below.
    additional function arity information (for supported targets). See
    :doc:`ControlFlowIntegrity` for more details.
 
+.. option:: -fstrict-bool
+
+    ``bool`` values are stored to memory as 8-bit values on most targets. C and
+    C++ specify that it is undefined behavior to put a value other than 0 or 1
+    in the storage of a ``bool`` value, and with ``-fstrict-bool``, Clang
+    leverages this knowledge for optimization opportunities. When this
+    assumption is violated, for instance if invalid data is ``memcpy``ed over a
+    ``bool``, the optimized code can lead to memory corruption.
+    ``-fstrict-bool`` is enabled by default.
+
+.. option:: -fno-strict-bool[={truncate|nonzero}]
+
+    Disable optimizations based on the assumption that all ``bool`` values,
+    which are typically represented as 8-bit integers in memory, only ever
+    contain bit patterns 0 or 1. When ``=truncate`` is specified, a ``bool`` is
+    true if its least significant bit is set, and false otherwise. When
+    ``=nonzero`` is specified, a ``bool`` is true when any bit is set, and
+    false otherwise. The default is ``=truncate``, but this could change in
+    future releases.
----------------
AaronBallman wrote:

> With that said, I don't think we can say this is an ABI break without implying that code built with -fstrict-bool, -fno-strict-bool=truncate and -fno-strict-bool=nonzero are each mutually ABI-incompatible

I think they are by definition. `-fno-strict-bool=truncated` has a different value representation from `-fno-strict-bool=nonzero`.

> we need to conclude that sharing broken bools across an ABI boundary is still undefined, and therefore it's not an ABI break if the observed bool value for a given bit pattern (other than 0 or 1) changes.

I don't think that follows, but I also don't think it matters because we seem to be in agreement that changing the behavior from `truncate` to `nonzero` or vice versa can silently change the behavior of code and therefore is a bad thing for us to tell users we're possibly going to do to them in the future. I think this is a bog standard "different options in different TUs is a bad idea when linking things together" situation otherwise.

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


More information about the cfe-commits mailing list