llvm/clang-tools-extra/docs/clang-tidy/checks/bugprone/redundant-branch-condition.rst

.. title:: clang-tidy - bugprone-redundant-branch-condition

bugprone-redundant-branch-condition
===================================

Finds condition variables in nested ``if`` statements that were also checked in
the outer ``if`` statement and were not changed.

Simple example:

.. code-block:: c

  bool onFire = isBurning();
  if (onFire) {
    if (onFire)
      scream();
  }

Here `onFire` is checked both in the outer ``if`` and the inner ``if`` statement
without a possible change between the two checks. The check warns for this code
and suggests removal of the second checking of variable `onFire`.

The checker also detects redundant condition checks if the condition variable
is an operand of a logical "and" (``&&``) or a logical "or" (``||``) operator:

.. code-block:: c

  bool onFire = isBurning();
  if (onFire) {
    if (onFire && peopleInTheBuilding > 0)
      scream();
  }

.. code-block:: c

  bool onFire = isBurning();
  if (onFire) {
    if (onFire || isCollapsing())
      scream();
  }

In the first case (logical "and") the suggested fix is to remove the redundant
condition variable and keep the other side of the ``&&``. In the second case
(logical "or") the whole ``if`` is removed similarly to the simple case on the
top.

The condition of the outer ``if`` statement may also be a logical "and" (``&&``)
expression:

.. code-block:: c

  bool onFire = isBurning();
  if (onFire && fireFighters < 10) {
    if (someOtherCondition()) {
      if (onFire)
        scream();
    }
  }

The error is also detected if both the outer statement is a logical "and"
(``&&``) and the inner statement is a logical "and" (``&&``) or "or" (``||``).
The inner ``if`` statement does not have to be a direct descendant of the outer
one.

No error is detected if the condition variable may have been changed between the
two checks:

.. code-block:: c

  bool onFire = isBurning();
  if (onFire) {
    tryToExtinguish(onFire);
    if (onFire && peopleInTheBuilding > 0)
      scream();
  }

Every possible change is considered, thus if the condition variable is not
a local variable of the function, it is a volatile or it has an alias (pointer
or reference) then no warning is issued.

Known limitations
^^^^^^^^^^^^^^^^^

The ``else`` branch is not checked currently for negated condition variable:

.. code-block:: c

  bool onFire = isBurning();
  if (onFire) {
    scream();
  } else {
    if (!onFire) {
      continueWork();
    }
  }

The checker currently only detects redundant checking of single condition
variables. More complex expressions are not checked:

.. code-block:: c

  if (peopleInTheBuilding == 1) {
    if (peopleInTheBuilding == 1) {
      doSomething();
    }
  }