brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · a91645f Raw
112 lines · plain
1.. title:: clang-tidy - bugprone-branch-clone2 3bugprone-branch-clone4=====================5 6Checks for repeated branches in ``if/else if/else`` chains, consecutive7repeated branches in ``switch`` statements and identical true and false8branches in conditional operators.9 10.. code-block:: c++11 12    if (test_value(x)) {13      y++;14      do_something(x, y);15    } else {16      y++;17      do_something(x, y);18    }19 20In this simple example (which could arise e.g. as a copy-paste error) the21``then`` and ``else`` branches are identical and the code is equivalent the22following shorter and cleaner code:23 24.. code-block:: c++25 26    test_value(x); // can be omitted unless it has side effects27    y++;28    do_something(x, y);29 30 31If this is the intended behavior, then there is no reason to use a conditional32statement; otherwise the issue can be solved by fixing the branch that is33handled incorrectly.34 35The check detects repeated branches in longer ``if/else if/else`` chains36where it would be even harder to notice the problem.37 38The check also detects repeated inner and outer ``if`` statements that may39be a result of a copy-paste error. This check cannot currently detect40identical inner and outer ``if`` statements if code is between the ``if``41conditions. An example is as follows.42 43.. code-block:: c++44 45    void test_warn_inner_if_1(int x) {46      if (x == 1) {    // warns, if with identical inner if47        if (x == 1)    // inner if is here48          ;49      if (x == 1) {    // does not warn, cannot detect50        int y = x;51        if (x == 1)52          ;53      }54    }55 56 57In ``switch`` statements the check only reports repeated branches when they are58consecutive, because it is relatively common that the ``case:`` labels have59some natural ordering and rearranging them would decrease the readability of60the code. For example:61 62.. code-block:: c++63 64    switch (ch) {65    case 'a':66      return 10;67    case 'A':68      return 10;69    case 'b':70      return 11;71    case 'B':72      return 11;73    default:74      return 10;75    }76 77Here the check reports that the ``'a'`` and ``'A'`` branches are identical78(and that the ``'b'`` and ``'B'`` branches are also identical), but does not79report that the ``default:`` branch is also identical to the first two branches.80If this is indeed the correct behavior, then it could be implemented as:81 82.. code-block:: c++83 84    switch (ch) {85    case 'a':86    case 'A':87      return 10;88    case 'b':89    case 'B':90      return 11;91    default:92      return 10;93    }94 95Here the check does not warn for the repeated ``return 10;``, which is good if96we want to preserve that ``'a'`` is before ``'b'`` and ``default:`` is the last97branch.98 99Switch cases marked with the ``[[fallthrough]]`` attribute are ignored.100 101Finally, the check also examines conditional operators and reports code like:102 103.. code-block:: c++104 105    return test_value(x) ? x : x;106 107Unlike if statements, the check does not detect chains of conditional108operators.109 110Note: This check also reports situations where branches become identical only111after preprocessing.112