diff --git a/src/coding-guidelines/expressions.rst b/src/coding-guidelines/expressions.rst index 247e573..6851d74 100644 --- a/src/coding-guidelines/expressions.rst +++ b/src/coding-guidelines/expressions.rst @@ -83,6 +83,75 @@ Expressions fn with_base(_: &Base) { ... } +.. guideline:: Do not divide by 0 + :id: gui_kMbiWbn8Z6g5 + :category: required + :status: draft + :release: latest + :fls: fls_Q9dhNiICGIfr + :decidability: undecidable + :scope: system + :tags: numerics, defect + + This guideline applies when unsigned integer or two’s complement division is performed during the + evaluation of an `ArithmeticExpression + `_. + + This includes the evaluation of a `RemainderExpression + `_, which uses unsigned integer or two's + complement division. + + This rule does not apply to evaluation of a :std:`core::ops::Div` trait on types other than `integer + types `_. + + .. rationale:: + :id: rat_h84NjY2tLSBW + :status: draft + + Integer division by zero results in a panic, which is an abnormal program state and may terminate the + process. The use of :std:`std::num::NonZero` as the divisor is a recommended way to avoid the + undecidability of this guideline. + + .. non_compliant_example:: + :id: non_compl_ex_LLs3vY8aGz0F + :status: draft + + When the division is performed, the right operand is evaluated to zero and the program panics. + + .. code-block:: rust + + let x = 0; + let y = 5 / x; // This line will panic. + + .. compliant_example:: + :id: compl_ex_Ri9pP5Ch3kbb + :status: draft + + There is no compliant way to perform integer division by zero. A checked division will prevent any + division by zero from happening. The programmer can then handle the returned :std:`std::option::Option`. + + The check for zero can also be performed manually. However, as the complexity of the control + flow leading to the invariant increases, it becomes increasingly harder to reason about it. For both programmers and static analysis tools. + + .. code-block:: rust + + // Example 1: using the checked division API + let result = match 5u8.checked_div(0) { + None => 0 + Some(r) => r + }; + + // Example 2: performing zero-checks by hand + let x = 0; + let y = if x != 0 { + 5 / x + } else { + 0 + }; + + + + .. guideline:: The 'as' operator should not be used with numeric operands :id: gui_ADHABsmK9FXz :category: advisory