You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.md
+24Lines changed: 24 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -984,6 +984,30 @@ Alternatives to `-no-strict-overflow` are the `-fwrapv` and `-ftrapv` options. W
984
984
985
985
Since GCC 8.5 `-no-strict-overflow` is equivalent to `-fwrapv -fwrapv-pointer` while GCC documentation recommends `-fsanitize=signed-integer-overflow` for diagnosing signed integer overflow issues during testing and debugging. In prior GCC versions `-no-strict-overflow` does not fully enforce two's complement on signed integers, allowing for additional optimizations[^Wang2012]. In Clang, `-no-strict-overflow` option is considered a synonym for `-fwrapv`.
986
986
987
+
#### When not to use?
988
+
989
+
The C and C++ standards since C23[^C2023] and C++20[^CPP2020] only support two’s complement representation for signed integer types[^Bastien2024]. Previous editions of these standards additionally allowed other sign representations. Code targeting one these previous language editions and requires a specific signed integer representation becomes less portable in a very subtle way. However, in practice, neither GCC nor Clang support other representations [^Bastien2018]. This means that even prior to C23 and C++20 the GCC and Clang implementations of these langauges are effectively two’s complement. Consequently we believe most code will benefit from `-fno-strict-overflow` or its alternatives.
990
+
991
+
#### Performance implications
992
+
993
+
Each of these options gives the compiler less freedom for optimizing the resulting machine code compared to the default `-fstrict-overflow` behavior. For example, under `-fstrict-overflow` semantics, expressions such as `i + 10 > i` will always be true for signed `i`, allowing the expression to be replaced at compile time with a constant value. As discussed above, if such expressions occur in condition checks the compiler may optimize away entire code paths when the expression can be evaluated at compile time. In contrast, under `-fno-strict-overflow` those expression must be evaluated at run-time in case of overflows that wrap around the value, thus preventing some optimizations. On the other hand, treating overflows as undefined behavior will only yield optimal behavior if the programmer can be certain the program will never accept inputs that cause overflows.
994
+
995
+
The `-ftrapv` option requires the compiler to emit checks to detect and trap overflows on signed integers unless it has compile time information of the value range to prove the operation doesn't overflow. As a result, `-ftrapv` is expected to have the largest performance impact out the options covered in this section.
996
+
997
+
### Other considerations
998
+
999
+
During link-time optimization (LTO), different compilation units may have been built with different arithmetic overflow behavior. The `-fno-strict-overflow`, `-fwrapv`, `-fno-trapv` and `-fno-strict-aliasing` are passed through to the link stage and take precedece over `-fstrict-overflow` semantics for compilation units with conflicting behavior[^gcc-flto]. In practice this means that software where certain modules benefit from `-fstrict-overflow` for perormance, but others use `-fno-strict-overflow` to improve security, may loose out on the performance benefits with `-fno-strict-overflow` taking precedence during LTO.
1000
+
1001
+
[^gcc-flto]: GCC team, [Options That Control Optimization: -flto](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-flto), GCC Manual, 2024-05-07.
1002
+
1003
+
[^C2023]: ISO/IEC, [Programming languages — C ("C23")](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf), ISO/IEC ISO/IEC 9899:2024, 2024. Note: The official ISO/IEC specification is paywalled and therefore not publicly available. The final specification draft is publicly available.
1004
+
1005
+
[^CPP2020]: ISO/IEC, [Programming languages — C++ ("C++20")](https://isocpp.org/files/papers/N4860.pdf), ISO/IEC ISO/IEC 14882:2020, 2022. Note: The official ISO/IEC specification is paywalled and therefore not publicly available. The final specification draft is publicly available.
1006
+
1007
+
[^Bastien2024]: Bastien, JF, [P3477R0: There are exactly 8 bits in a byte](https://open-std.org/JTC1/SC22/WG21/docs/papers/2024/p3477r0.html), Published ISO/IEC JTC1/SC22/WG21 Proposal, 2024-10-15.
1008
+
1009
+
[^Bastien2018]: Bastien, JF, [P0907R4: Signed Integers are Two’s Complement](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r4.html), Published ISO/IEC JTC1/SC22/WG21 Proposal, 2018-10-06
0 commit comments