@@ -18,7 +18,6 @@ Expressions
1818 :tags: security, performance, numerics
1919
2020 Eliminate `arithmetic overflow <https://rust-lang.github.io/fls/expressions.html#arithmetic-overflow >`_ of both signed and unsigned integer types.
21- Arithmetic overflow will panic in debug mode, but wraparound in release mode.
2221 Any wraparound behavior must be explicitly specified to ensure the same behavior in both debug and release modes.
2322
2423 This rule applies to the following primitive types:
@@ -41,7 +40,9 @@ Expressions
4140 :status: draft
4241
4342 Eliminate arithmetic overflow to avoid runtime panics and unexpected wraparound behavior.
44- Use explicit wrapping or saturation semantics in cases where these behaviors are intentional.
43+ Arithmetic overflow will panic in debug mode, but wraparound in release mode, resulting in inconsistent behavior.
44+ Use explicit `wrapping <https://doc.rust-lang.org/std/num/struct.Wrapping.html >`_ or
45+ `saturating <https://doc.rust-lang.org/std/num/struct.Saturating.html >`_ semantics where these behaviors are intentional.
4546 Range checking can be used to eliminate the possibility of arithmetic overflow.
4647
4748 .. non_compliant_example ::
@@ -61,20 +62,26 @@ Expressions
6162 :id: compl_ex_BgUHiRB4kc4b_1
6263 :status: draft
6364
64- This compliant solution ensures that the addition operation cannot result
65- in arithmetic overflow, based on the maximum range of a signed 32-bit integer.
66- A more restrictive range may also be used.
65+ This compliant solution ensures that the addition operation cannot result in arithmetic overflow,
66+ based on the maximum range of a signed 32-bit integer.
67+ Functions such as
68+ `overflowing_add <https://doc.rust-lang.org/stable/core/primitive.u32.html#method.overflowing_add >`_,
69+ `overflowing_sub <https://doc.rust-lang.org/stable/core/primitive.u32.html#method.overflowing_sub >`_, and
70+ `overflowing_mul <https://doc.rust-lang.org/stable/core/primitive.u32.html#method.overflowing_mul >`_
71+ can also be used to detect overflow.
72+ Code that invoked these functions would typically further restrict the range of possible values,
73+ based on the anticipated range of the inputs.
6774
6875 .. code-block :: rust
6976
7077 enum ArithmeticError {
7178 Overflow,
72- DivisionByZero,
79+ DivisionByZero,
7380 }
7481
7582 use std::i32::{MAX as INT_MAX, MIN as INT_MIN};
7683
77- fn add(si_a: i32, si_b: i32) -> Result<i32, ArithmeticError> {
84+ fn add(si_a: i32, si_b: i32) -> Result<i32, ArithmeticError> {
7885 if (si_b > 0 && si_a > INT_MAX - si_b)
7986 || (si_b < 0 && si_a < INT_MIN - si_b)
8087 {
@@ -88,13 +95,13 @@ Expressions
8895 if (si_b < 0 && si_a > INT_MAX + si_b)
8996 || (si_b > 0 && si_a < INT_MIN + si_b)
9097 {
91- Err(ArithmeticError::Overflow)
98+ Err(ArithmeticError::Overflow)
9299 } else {
93- Ok(si_a - si_b)
100+ Ok(si_a - si_b)
94101 }
95102 }
96103
97- fn mul(si_a: i32, si_b: i32) -> Result<i32, ArithmeticError> {
104+ fn mul(si_a: i32, si_b: i32) -> Result<i32, ArithmeticError> {
98105 if si_a == 0 || si_b == 0 {
99106 return Ok(0);
100107 }
@@ -180,7 +187,7 @@ Expressions
180187 fn main() {
181188 let si_a = Wrapping(i32::MAX);
182189 let si_b = Wrapping(i32::MAX);
183- println!("Adding {} by {} has a sum of {}", si_a, si_b, add(si_a, si_b))
190+ println!("{} + {} = {}", si_a, si_b, add(si_a, si_b))
184191 }
185192
186193 .. compliant_example ::
0 commit comments