[clang-tools-extra] r348344 - Revert "[clang-tidy] new check: bugprone-branch-clone"

Jonas Toth via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 5 01:34:19 PST 2018


Author: jonastoth
Date: Wed Dec  5 01:34:18 2018
New Revision: 348344

URL: http://llvm.org/viewvc/llvm-project?rev=348344&view=rev
Log:
Revert "[clang-tidy] new check: bugprone-branch-clone"

The patch broke on buildbot with assertion-failure. Revert until this
is figured out.

Removed:
    clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.cpp
    clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-branch-clone.rst
    clang-tools-extra/trunk/test/clang-tidy/bugprone-branch-clone.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Removed: clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.cpp?rev=348343&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.cpp (removed)
@@ -1,215 +0,0 @@
-//===--- BranchCloneCheck.cpp - clang-tidy --------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "BranchCloneCheck.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Analysis/CloneDetection.h"
-#include "llvm/Support/Casting.h"
-
-using namespace clang;
-using namespace clang::ast_matchers;
-
-/// Returns true when the statements are Type I clones of each other.
-static bool areStatementsIdentical(const Stmt *LHS, const Stmt *RHS,
-                                   const ASTContext &Context) {
-  llvm::FoldingSetNodeID DataLHS, DataRHS;
-  LHS->Profile(DataLHS, Context, false);
-  RHS->Profile(DataRHS, Context, false);
-  return (DataLHS == DataRHS);
-}
-
-namespace {
-/// A branch in a switch may consist of several statements; while a branch in
-/// an if/else if/else chain is one statement (which may be a CompoundStmt).
-using SwitchBranch = llvm::SmallVector<const Stmt *, 2>;
-} // anonymous namespace
-
-/// Determines if the bodies of two branches in a switch statements are Type I
-/// clones of each other. This function only examines the body of the branch
-/// and ignores the `case X:` or `default:` at the start of the branch.
-static bool areSwitchBranchesIdentical(const SwitchBranch LHS,
-                                       const SwitchBranch RHS,
-                                       const ASTContext &Context) {
-  if (LHS.size() != RHS.size())
-    return false;
-
-  for (size_t i = 0, Size = LHS.size(); i < Size; i++) {
-    // NOTE: We strip goto labels and annotations in addition to stripping
-    // the `case X:` or `default:` labels, but it is very unlikely that this
-    // would casue false positives in real-world code.
-    if (!areStatementsIdentical(LHS[i]->stripLabelLikeStatements(),
-                                RHS[i]->stripLabelLikeStatements(), Context)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-namespace clang {
-namespace tidy {
-namespace bugprone {
-
-void BranchCloneCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(
-      ifStmt(stmt().bind("if"),
-             hasParent(stmt(unless(ifStmt(hasElse(equalsBoundNode("if")))))),
-             hasElse(stmt().bind("else"))),
-      this);
-  Finder->addMatcher(switchStmt().bind("switch"), this);
-  Finder->addMatcher(conditionalOperator().bind("condOp"), this);
-}
-
-void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) {
-  const ASTContext &Context = *Result.Context;
-
-  if (const auto *IS = Result.Nodes.getNodeAs<IfStmt>("if")) {
-    const Stmt *Then = IS->getThen();
-    assert(Then && "An IfStmt must have a `then` branch!");
-
-    const Stmt *Else = Result.Nodes.getNodeAs<Stmt>("else");
-    assert(Else && "We only look for `if` statements with an `else` branch!");
-
-    if (!isa<IfStmt>(Else)) {
-      // Just a simple if with no `else if` branch.
-      if (areStatementsIdentical(Then->IgnoreContainers(),
-                                 Else->IgnoreContainers(), Context)) {
-        diag(IS->getBeginLoc(), "if with identical then and else branches");
-        diag(IS->getElseLoc(), "else branch starts here", DiagnosticIDs::Note);
-      }
-      return;
-    }
-
-    // This is the complicated case when we start an if/else if/else chain.
-    // To find all the duplicates, we collect all the branches into a vector.
-    llvm::SmallVector<const Stmt *, 4> Branches;
-    const IfStmt *Cur = IS;
-    while (true) {
-      // Store the `then` branch.
-      Branches.push_back(Cur->getThen());
-
-      Else = Cur->getElse();
-      // The chain ends if there is no `else` branch.
-      if (!Else)
-        break;
-
-      // Check if there is another `else if`...
-      Cur = dyn_cast<IfStmt>(Else);
-      if (!Cur) {
-        // ...this is just a plain `else` branch at the end of the chain.
-        Branches.push_back(Else);
-        break;
-      }
-    }
-
-    size_t N = Branches.size();
-    llvm::BitVector KnownAsClone(N);
-
-    for (size_t i = 0; i + 1 < N; i++) {
-      // We have already seen Branches[i] as a clone of an earlier branch.
-      if (KnownAsClone[i])
-        continue;
-
-      int NumCopies = 1;
-
-      for (size_t j = i + 1; j < N; j++) {
-        if (KnownAsClone[j] ||
-            !areStatementsIdentical(Branches[i]->IgnoreContainers(),
-                                    Branches[j]->IgnoreContainers(), Context))
-          continue;
-
-        NumCopies++;
-        KnownAsClone[j] = true;
-
-        if (NumCopies == 2) {
-          // We report the first occurence only when we find the second one.
-          diag(Branches[i]->getBeginLoc(),
-               "repeated branch in conditional chain");
-          diag(Lexer::getLocForEndOfToken(Branches[i]->getEndLoc(), 0,
-                                          *Result.SourceManager, getLangOpts()),
-               "end of the original", DiagnosticIDs::Note);
-        }
-
-        diag(Branches[j]->getBeginLoc(), "clone %0 starts here",
-             DiagnosticIDs::Note)
-            << (NumCopies - 1);
-      }
-    }
-    return;
-  }
-
-  if (const auto *CO = Result.Nodes.getNodeAs<ConditionalOperator>("condOp")) {
-    // We do not try to detect chains of ?: operators.
-    if (areStatementsIdentical(CO->getTrueExpr(), CO->getFalseExpr(), Context))
-      diag(CO->getQuestionLoc(),
-           "conditional operator with identical true and false expressions");
-
-    return;
-  }
-
-  if (const auto *SS = Result.Nodes.getNodeAs<SwitchStmt>("switch")) {
-    const CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(SS->getBody());
-
-    // Code like
-    //   switch (x) case 0: case 1: foobar();
-    // is legal and calls foobar() if and only if x is either 0 or 1;
-    // but we do not try to distinguish branches in such code.
-    if (!Body)
-      return;
-
-    // We will first collect the branches of the switch statements. For the
-    // sake of simplicity we say that branches are delimited by the SwitchCase
-    // (`case:` or `default:`) children of Body; that is, we ignore `case:` or
-    // `default:` labels embedded inside other statements and we do not follow
-    // the effects of `break` and other manipulation of the control-flow.
-    llvm::SmallVector<SwitchBranch, 4> Branches;
-    for (const Stmt *S : Body->body()) {
-      // If this is a `case` or `default`, we start a new, empty branch.
-      if (isa<SwitchCase>(S))
-        Branches.emplace_back();
-
-      // There may be code before the first branch (which can be dead code
-      // and can be code reached either through goto or through case labels
-      // that are embedded inside e.g. inner compound statements); we do not
-      // store those statements in branches.
-      if (!Branches.empty())
-        Branches.back().push_back(S);
-    }
-
-    auto End = Branches.end();
-    auto BeginCurrent = Branches.begin();
-    while (BeginCurrent < End) {
-      auto EndCurrent = BeginCurrent + 1;
-      while (EndCurrent < End &&
-             areSwitchBranchesIdentical(*BeginCurrent, *EndCurrent, Context)) {
-        ++EndCurrent;
-      }
-      // At this point the iterator range {BeginCurrent, EndCurrent} contains a
-      // complete family of consecutive identical branches.
-      if (EndCurrent > BeginCurrent + 1) {
-        diag(BeginCurrent->front()->getBeginLoc(),
-             "switch has %0 consecutive identical branches")
-            << static_cast<int>(std::distance(BeginCurrent, EndCurrent));
-        diag(Lexer::getLocForEndOfToken((EndCurrent - 1)->back()->getEndLoc(),
-                                        0, *Result.SourceManager,
-                                        getLangOpts()),
-             "last of these clones ends here", DiagnosticIDs::Note);
-      }
-      BeginCurrent = EndCurrent;
-    }
-    return;
-  }
-
-  llvm_unreachable("No if statement and no switch statement.");
-}
-
-} // namespace bugprone
-} // namespace tidy
-} // namespace clang

Removed: clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.h?rev=348343&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/BranchCloneCheck.h (removed)
@@ -1,39 +0,0 @@
-//===--- BranchCloneCheck.h - clang-tidy ------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BRANCHCLONECHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BRANCHCLONECHECK_H
-
-#include "../ClangTidy.h"
-
-namespace clang {
-namespace tidy {
-namespace bugprone {
-
-/// A check for detecting if/else if/else chains where two or more branches are
-/// Type I clones of each other (that is, they contain identical code), for
-/// detecting switch statements where two or more consecutive branches are
-/// Type I clones of each other, and for detecting conditional operators where
-/// the true and false expressions are Type I clones of each other.
-///
-/// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-branch-clone.html
-class BranchCloneCheck : public ClangTidyCheck {
-public:
-  BranchCloneCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
-  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
-  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-};
-
-} // namespace bugprone
-} // namespace tidy
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BRANCHCLONECHECK_H

Modified: clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp?rev=348344&r1=348343&r2=348344&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp Wed Dec  5 01:34:18 2018
@@ -14,7 +14,6 @@
 #include "ArgumentCommentCheck.h"
 #include "AssertSideEffectCheck.h"
 #include "BoolPointerImplicitConversionCheck.h"
-#include "BranchCloneCheck.h"
 #include "CopyConstructorInitCheck.h"
 #include "DanglingHandleCheck.h"
 #include "ExceptionEscapeCheck.h"
@@ -66,8 +65,6 @@ public:
         "bugprone-assert-side-effect");
     CheckFactories.registerCheck<BoolPointerImplicitConversionCheck>(
         "bugprone-bool-pointer-implicit-conversion");
-    CheckFactories.registerCheck<BranchCloneCheck>(
-        "bugprone-branch-clone");
     CheckFactories.registerCheck<CopyConstructorInitCheck>(
         "bugprone-copy-constructor-init");
     CheckFactories.registerCheck<DanglingHandleCheck>(

Modified: clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt?rev=348344&r1=348343&r2=348344&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt Wed Dec  5 01:34:18 2018
@@ -4,7 +4,6 @@ add_clang_library(clangTidyBugproneModul
   ArgumentCommentCheck.cpp
   AssertSideEffectCheck.cpp
   BoolPointerImplicitConversionCheck.cpp
-  BranchCloneCheck.cpp
   BugproneTidyModule.cpp
   CopyConstructorInitCheck.cpp
   DanglingHandleCheck.cpp

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=348344&r1=348343&r2=348344&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed Dec  5 01:34:18 2018
@@ -122,13 +122,6 @@ Improvements to clang-tidy
   Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
   ``absl::StrAppend()`` should be used instead.
 
-- New :doc:`bugprone-branch-clone
-  <clang-tidy/checks/bugprone-branch-clone>` check.
-
-  Checks for repeated branches in ``if/else if/else`` chains, consecutive
-  repeated branches in ``switch`` statements and indentical true and false
-  branches in conditional operators.
-
 - New :doc:`bugprone-too-small-loop-variable
   <clang-tidy/checks/bugprone-too-small-loop-variable>` check.
 

Removed: clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-branch-clone.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-branch-clone.rst?rev=348343&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-branch-clone.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-branch-clone.rst (removed)
@@ -1,90 +0,0 @@
-.. title:: clang-tidy - bugprone-branch-clone
-
-bugprone-branch-clone
-=====================
-
-Checks for repeated branches in ``if/else if/else`` chains, consecutive
-repeated branches in ``switch`` statements and indentical true and false
-branches in conditional operators.
-
-.. code-block:: c++
-
-    if (test_value(x)) {
-      y++;
-      do_something(x, y);
-    } else {
-      y++;
-      do_something(x, y);
-    }
-
-In this simple example (which could arise e.g. as a copy-paste error) the
-``then`` and ``else`` branches are identical and the code is equivalent the
-following shorter and cleaner code:
-
-.. code-block:: c++
-
-    test_value(x); // can be omitted unless it has side effects
-    y++;
-    do_something(x, y);
-
-
-If this is the inteded behavior, then there is no reason to use a conditional
-statement; otherwise the issue can be solved by fixing the branch that is
-handled incorrectly.
-
-The check also detects repeated branches in longer ``if/else if/else`` chains
-where it would be even harder to notice the problem.
-
-In ``switch`` statements the check only reports repeated branches when they are
-consecutive, because it is relatively common that the ``case:`` labels have
-some natural ordering and rearranging them would decrease the readability of
-the code. For example:
-
-.. code-block:: c++
-
-    switch (ch) {
-    case 'a':
-      return 10;
-    case 'A':
-      return 10;
-    case 'b':
-      return 11;
-    case 'B':
-      return 11;
-    default:
-      return 10;
-    }
-
-Here the check reports that the ``'a'`` and ``'A'`` branches are identical
-(and that the ``'b'`` and ``'B'`` branches are also identical), but does not
-report that the ``default:`` branch is also idenical to the first two branches.
-If this is indeed the correct behavior, then it could be implemented as:
-
-.. code-block:: c++
-
-    switch (ch) {
-    case 'a':
-    case 'A':
-      return 10;
-    case 'b':
-    case 'B':
-      return 11;
-    default:
-      return 10;
-    }
-
-Here the check does not warn for the repeated ``return 10;``, which is good if
-we want to preserve that ``'a'`` is before ``'b'`` and ``default:`` is the last
-branch.
-
-Finally, the check also examines conditional operators and reports code like:
-
-.. code-block:: c++
-
-    return test_value(x) ? x : x;
-
-Unlike if statements, the check does not detect chains of conditional
-operators.
-
-Note: This check also reports situations where branches become identical only
-after preprocession.

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=348344&r1=348343&r2=348344&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed Dec  5 01:34:18 2018
@@ -31,7 +31,6 @@ Clang-Tidy Checks
    bugprone-argument-comment
    bugprone-assert-side-effect
    bugprone-bool-pointer-implicit-conversion
-   bugprone-branch-clone
    bugprone-copy-constructor-init
    bugprone-dangling-handle
    bugprone-exception-escape

Removed: clang-tools-extra/trunk/test/clang-tidy/bugprone-branch-clone.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-branch-clone.cpp?rev=348343&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/bugprone-branch-clone.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/bugprone-branch-clone.cpp (removed)
@@ -1,1017 +0,0 @@
-// RUN: %check_clang_tidy %s bugprone-branch-clone %t
-
-void test_basic1(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    out++;
-
-  out++;
-}
-
-void test_basic2(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  }
-  else {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    out++;
-  }
-
-  out++;
-}
-
-void test_basic3(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  }
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    out++;
-
-  out++;
-}
-
-void test_basic4(int in, int &out) {
-  if (in > 77) {
-    out--;
-  }
-  else {
-    out++;
-  }
-}
-
-void test_basic5(int in, int &out) {
-  if (in > 77) {
-    out++;
-  }
-  else {
-    out++;
-    out++;
-  }
-}
-
-void test_basic6(int in, int &out) {
-  if (in > 77) {
-    out++;
-  }
-  else {
-    out++, out++;
-  }
-}
-
-void test_basic7(int in, int &out) {
-  if (in > 77) {
-    out++;
-    out++;
-  }
-  else
-    out++;
-
-  out++;
-}
-
-void test_basic8(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-    out++;
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-    out++;
-    out++;
-  }
-
-  if (in % 2)
-    out++;
-}
-
-void test_basic9(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    if (in % 2)
-      out++;
-    else
-      out--;
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-    if (in % 2)
-      out++;
-    else
-      out--;
-  }
-}
-
-// If we remove the braces from the previous example, the check recognizes it
-// as an `else if`.
-void test_basic10(int in, int &out) {
-  if (in > 77)
-    if (in % 2)
-      out++;
-    else
-      out--;
-  else
-    if (in % 2)
-      out++;
-    else
-      out--;
-
-}
-
-void test_basic11(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    if (in % 2)
-      out++;
-    else
-      out--;
-    if (in % 3)
-      out++;
-    else
-      out--;
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-    if (in % 2)
-      out++;
-    else
-      out--;
-    if (in % 3)
-      out++;
-    else
-      out--;
-  }
-}
-
-void test_basic12(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-  }
-}
-
-void test_basic13(int in, int &out) {
-  if (in > 77) {
-    // Empty compound statement is not identical to null statement.
-  } else;
-}
-
-// We use a comparison that ignores redundant parentheses:
-void test_basic14(int in, int &out) {
-  if (in > 77)
-    out += 2;
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    (out) += (2);
-}
-
-void test_basic15(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    ((out += 2));
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    out += 2;
-}
-
-// ..but does not apply additional simplifications: 
-void test_basic16(int in, int &out) {
-  if (in > 77)
-    out += 2;
-  else
-    out += 1 + 1;
-}
-
-// ..and does not forget important parentheses:
-int test_basic17(int a, int b, int c, int mode) {
-  if (mode>8)
-    return (a + b) * c;
-  else
-    return a + b * c;
-}
-
-//=========--------------------==========//
-
-#define PASTE_CODE(x) x
-
-void test_macro1(int in, int &out) {
-  PASTE_CODE(
-    if (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]
-      out++;
-    else
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-      out++;
-  )
-
-  out--;
-}
-
-void test_macro2(int in, int &out) {
-  PASTE_CODE(
-    if (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]
-      out++;
-  )
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    out++;
-}
-
-void test_macro3(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  PASTE_CODE(
-    else
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-      out++;
-  )
-}
-
-void test_macro4(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    PASTE_CODE(
-      out++;
-    )
-}
-
-void test_macro5(int in, int &out) {
-  PASTE_CODE(if) (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  PASTE_CODE(else)
-// CHECK-MESSAGES: :[[@LINE-1]]:14: note: else branch starts here
-    out++;
-}
-
-#define OTHERWISE_INCREASE else out++
-
-void test_macro6(int in, int &out) {
-  if (in > 77)
-      out++;
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-  OTHERWISE_INCREASE;
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-// CHECK-MESSAGES: :[[@LINE-8]]:28: note: expanded from macro 'OTHERWISE_INCREASE'
-}
-
-#define COND_INCR(a, b, c) \
-  do {                     \
-    if ((a))               \
-      (b)++;               \
-    else                   \ 
-      (c)++;               \
-  } while (0)
-
-void test_macro7(int in, int &out1, int &out2) {
-  COND_INCR(in, out1, out1);
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-9]]:5: note: expanded from macro 'COND_INCR'
-// CHECK-MESSAGES: :[[@LINE-3]]:3: note: else branch starts here
-// CHECK-MESSAGES: :[[@LINE-8]]:5: note: expanded from macro 'COND_INCR'
-}
-
-void test_macro8(int in, int &out1, int &out2) {
-  COND_INCR(in, out1, out2);
-}
-
-void test_macro9(int in, int &out1, int &out2) {
-  COND_INCR(in, out2, out2);
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-21]]:5: note: expanded from macro 'COND_INCR'
-// CHECK-MESSAGES: :[[@LINE-3]]:3: note: else branch starts here
-// CHECK-MESSAGES: :[[@LINE-20]]:5: note: expanded from macro 'COND_INCR'
-}
-
-#define CONCAT(a, b) a##b
-
-void test_macro10(int in, int &out) {
-  CONCAT(i, f) (in > 77)
-// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: if with identical then and else branches [bugprone-branch-clone]
-    out++;
-  CONCAT(el, se)
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: else branch starts here
-    out++;
-}
-
-#define PROBLEM (-1)
-
-int test_macro11(int count) {
-  if (!count)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    return PROBLEM;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original
-  else if (count == 13)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here
-    return -1;
-  else
-    return count * 2;
-}
-
-#define IF if (
-#define THEN ) {
-#define ELSE } else {
-#define END }
-
-void test_macro12(int in, int &out) {
-  IF in > 77 THEN
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-8]]:12: note: expanded from macro 'IF'
-    out++;
-    out++;
-  ELSE
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-// CHECK-MESSAGES: :[[@LINE-12]]:14: note: expanded from macro 'IF'
-    out++;
-    out++;
-  END
-}
-
-// A hack for implementing a switch with no fallthrough:
-#define SWITCH(x) switch (x) {
-#define CASE(x) break; case (x):
-#define DEFAULT break; default:
-
-void test_macro13(int in, int &out) {
-  SWITCH(in)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-6]]:24: note: expanded from macro 'CASE'
-    CASE(1)
-      out++;
-      out++;
-    CASE(2)
-      out++;
-      out++;
-    CASE(3)
-      out++;
-      out++;
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: last of these clones ends here
-// CHECK-MESSAGES: :[[@LINE-17]]:22: note: expanded from macro 'CASE'
-    CASE(4)
-      out++;
-    CASE(5)
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-22]]:24: note: expanded from macro 'CASE'
-    CASE(6)
-      out--;
-    CASE(7)
-      out--;
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: last of these clones ends here
-// CHECK-MESSAGES: :[[@LINE-28]]:22: note: expanded from macro 'CASE'
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-30]]:24: note: expanded from macro 'CASE'
-    CASE(8)
-      out++;
-      out++;
-    CASE(9)
-      out++;
-      out++;
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: last of these clones ends here
-// CHECK-MESSAGES: :[[@LINE-37]]:22: note: expanded from macro 'DEFAULT'
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE-39]]:24: note: expanded from macro 'DEFAULT'
-    DEFAULT
-      out--;
-      out--;
-    CASE(10)
-      out--;
-      out--;
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: last of these clones ends here
-// CHECK-MESSAGES: :[[@LINE-48]]:22: note: expanded from macro 'CASE'
-    CASE(12)
-      out++;
-    CASE(13)
-      out++;
-  END
-}
-
-//=========--------------------==========//
-
-void test_chain1(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original
-  else if (in > 55)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here
-    out++;
-
-  out++;
-}
-
-void test_chain2(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original
-  else if (in > 55)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here
-    out++;
-  else if (in > 42)
-    out--;
-  else if (in > 28)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here
-    out++;
-  else if (in > 12) {
-    out++;
-    out *= 7;
-  } else if (in > 7) {
-// CHECK-MESSAGES: :[[@LINE-1]]:22: note: clone 3 starts here
-    out++;
-  }
-}
-
-void test_chain3(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-    out++;
-// CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original
-  } else if (in > 55) {
-// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here
-    out++;
-    out++;
-  } else if (in > 42)
-    out--;
-  else if (in > 28) {
-// CHECK-MESSAGES: :[[@LINE-1]]:21: note: clone 2 starts here
-    out++;
-    out++;
-  } else if (in > 12) {
-    out++;
-    out++;
-    out++;
-    out *= 7;
-  } else if (in > 7) {
-// CHECK-MESSAGES: :[[@LINE-1]]:22: note: clone 3 starts here
-    out++;
-    out++;
-  }
-}
-
-// In this chain there are two clone families; notice that the checker
-// describes all branches of the first one before mentioning the second one.
-void test_chain4(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-    out++;
-// CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original
-  } else if (in > 55) {
-// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here
-// CHECK-MESSAGES: :[[@LINE+8]]:21: note: clone 2 starts here
-// CHECK-MESSAGES: :[[@LINE+15]]:22: note: clone 3 starts here
-    out++;
-    out++;
-  } else if (in > 42)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out--;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original
-  else if (in > 28) {
-    out++;
-    out++;
-  } else if (in > 12) {
-    out++;
-    out++;
-    out++;
-    out *= 7;
-  } else if (in > 7) {
-    out++;
-    out++;
-  } else if (in > -3) {
-// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here
-    out--;
-  }
-}
-
-void test_chain5(int in, int &out) {
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original
-  else if (in > 55)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here
-    out++;
-  else if (in > 42)
-    out--;
-  else if (in > 28)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here
-    out++;
-  else if (in > 12) {
-    out++;
-    out *= 7;
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: clone 3 starts here
-    out++;
-  }
-}
-
-void test_chain6(int in, int &out) {
-  if (in > 77) {
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-    out++;
-// CHECK-MESSAGES: :[[@LINE+1]]:4: note: end of the original
-  } else if (in > 55) {
-// CHECK-MESSAGES: :[[@LINE-1]]:23: note: clone 1 starts here
-    out++;
-    out++;
-  } else if (in > 42)
-    out--;
-  else if (in > 28) {
-// CHECK-MESSAGES: :[[@LINE-1]]:21: note: clone 2 starts here
-    out++;
-    out++;
-  } else if (in > 12) {
-    out++;
-    out++;
-    out++;
-    out *= 7;
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: clone 3 starts here
-    out++;
-    out++;
-  }
-}
-
-void test_nested(int a, int b, int c, int &out) {
-  if (a > 5) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+27]]:5: note: else branch starts here
-    if (b > 5) {
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+9]]:6: note: end of the original
-// CHECK-MESSAGES: :[[@LINE+8]]:24: note: clone 1 starts here
-// CHECK-MESSAGES: :[[@LINE+14]]:12: note: clone 2 starts here
-      if (c > 5)
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]
-        out++;
-      else
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here
-        out++;
-    } else if (b > 15) {
-      if (c > 5)
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]
-        out++;
-      else
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here
-        out++;
-    } else {
-      if (c > 5)
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]
-        out++;
-      else
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here
-        out++;
-    }
-  } else {
-    if (b > 5) {
-// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: repeated branch in conditional chain [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+9]]:6: note: end of the original
-// CHECK-MESSAGES: :[[@LINE+8]]:24: note: clone 1 starts here
-// CHECK-MESSAGES: :[[@LINE+14]]:12: note: clone 2 starts here
-      if (c > 5)
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]
-        out++;
-      else
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here
-        out++;
-    } else if (b > 15) {
-      if (c > 5)
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]
-        out++;
-      else
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here
-        out++;
-    } else {
-      if (c > 5)
-// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: if with identical then and else branches [bugprone-branch-clone]
-        out++;
-      else
-// CHECK-MESSAGES: :[[@LINE-1]]:7: note: else branch starts here
-        out++;
-    }
-  }
-}
-
-//=========--------------------==========//
-
-template <class T>
-void test_template_not_instantiated(const T &t) {
-  int a;
-  if (t)
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    a++;
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    a++;
-}
-
-template <class T>
-void test_template_instantiated(const T &t) {
-  int a;
-  if (t)
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    a++;
-  else
-// CHECK-MESSAGES: :[[@LINE-1]]:3: note: else branch starts here
-    a++;
-}
-
-template void test_template_instantiated<int>(const int &t);
-
-template <class T>
-void test_template2(T t, int a) {
-  if (a) {
-    T b(0);
-    a += b;
-  } else {
-    int b(0);
-    a += b;
-  }
-}
-
-template void test_template2<int>(int t, int a);
-
-template <class T>
-void test_template3(T t, int a) {
-  if (a) {
-    T b(0);
-    a += b;
-  } else {
-    int b(0);
-    a += b;
-  }
-}
-
-template void test_template3<short>(short t, int a);
-
-template <class T>
-void test_template_two_instances(T t, int &a) {
-  if (a) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    a += int(t);
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-    a += int(t);
-  }
-}
-
-template void test_template_two_instances<short>(short t, int &a);
-template void test_template_two_instances<long>(long t, int &a);
-
-class C {
-  int member;
-  void inline_method(int arg) {
-    if (arg)
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: if with identical then and else branches [bugprone-branch-clone]
-      member = 3;
-    else
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-      member = 3;
-  }
-  int other_method();
-};
-
-int C::other_method() {
-  if (member) {
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: if with identical then and else branches [bugprone-branch-clone]
-    return 8;
-  } else {
-// CHECK-MESSAGES: :[[@LINE-1]]:5: note: else branch starts here
-    return 8;
-  }
-}
-
-//=========--------------------==========//
-
-int simple_switch(char ch) {
-  switch (ch) {
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-  case 'a':
-    return 10;
-  case 'A':
-    return 10;
-// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-  case 'b':
-    return 11;
-  case 'B':
-    return 11;
-// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-  case 'c':
-    return 10;
-  case 'C':
-    return 10;
-// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here
-  default:
-    return 0;
-  }
-}
-
-int long_sequence_switch(char ch) {
-  switch (ch) {
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 7 consecutive identical branches [bugprone-branch-clone]
-  case 'a':
-    return 10;
-  case 'A':
-    return 10;
-  case 'b':
-    return 10;
-  case 'B':
-    return 10;
-  case 'c':
-    return 10;
-  case 'C':
-    return 10;
-  default:
-    return 10;
-// CHECK-MESSAGES: :[[@LINE-1]]:14: note: last of these clones ends here
-  }
-}
-
-int nested_switch(int a, int b, int c) {
-  switch (a) {
-// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+114]]:6: note: last of these clones ends here
-  case 1:
-    switch (b) {
-// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here
-    case 1:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    case 2:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    default:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    }
-  case 2:
-    switch (b) {
-// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here
-    case 1:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    case 2:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    default:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    }
-  default:
-    switch (b) {
-// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-// CHECK-MESSAGES: :[[@LINE+33]]:8: note: last of these clones ends here
-    case 1:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    case 2:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    default:
-      switch (c) {
-// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: switch has 3 consecutive identical branches [bugprone-branch-clone]
-      case 1:
-        return 42;
-      case 2:
-        return 42;
-      default:
-        return 42;
-// CHECK-MESSAGES: :[[@LINE-1]]:18: note: last of these clones ends here
-      }
-    }
-  }
-}
-
-//=========--------------------==========//
-
-// This should not produce warnings, as in switch statements we only report
-// identical branches when they are consecutive. Also note that a branch
-// terminated by a break is different from a branch terminated by the end of
-// the switch statement.
-int interleaved_cases(int a, int b) {
-  switch (a) {
-  case 3:
-  case 4:
-    b = 2;
-    break;
-  case 5:
-    b = 3;
-    break;
-  case 6:
-    b = 2;
-    break;
-  case 7:
-    if (b % 2) {
-      b++;
-    } else {
-      b++;
-      break;
-    }
-    b = 2;
-    break;
-  case 8:
-    b = 2;
-  case 9:
-    b = 3;
-    break;
-  default:
-    b = 3;
-  }
-  return b;
-}
-
-
-// A case: or default: is only considered to be the start of a branch if it is a direct child of the CompoundStmt forming the body of the switch
-int buried_cases(int foo) {
-  switch (foo) {
-    {
-    case 36:
-      return 8;
-    default:
-      return 8;
-    }
-  }
-}
-
-// Here the `case 7:` is a child statement of the GotoLabelStmt, so the checker
-// thinks that it is part of the `case 9:` branch. While this result is
-// counterintuitve, mixing goto labels and switch statements in this fashion is
-// pretty rare, so it does not deserve a special case in the checker code.
-int decorated_cases(int z) {
-  if (!(z % 777)) {
-    goto lucky;
-  }
-  switch (z) {
-// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: switch has 2 consecutive identical branches [bugprone-branch-clone]
-  case 1:
-  case 2:
-  case 3:
-    z++;
-    break;
-  case 4:
-  case 5:
-    z++;
-    break;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: last of these clones ends here
-  case 9:
-    z++;
-    break;
-  lucky:
-  case 7:
-    z += 3;
-    z *= 2;
-    break;
-  case 92:
-    z += 3;
-    z *= 2;
-    break;
-  default:
-    z++;
-  }
-  return z + 92;
-}
-
-// The child of the switch statement is not neccessarily a compound statement,
-// do not crash in this unusual case.
-char no_real_body(int in, int &out) {
-  switch (in)
-  case 42:
-    return 'A';
-
-  if (in > 77)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: repeated branch in conditional chain [bugprone-branch-clone]
-    out++;
-// CHECK-MESSAGES: :[[@LINE-1]]:10: note: end of the original
-  else if (in > 55)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 1 starts here
-    out++;
-  else if (in > 34)
-// CHECK-MESSAGES: :[[@LINE+1]]:5: note: clone 2 starts here
-    out++;
-
-  return '|';
-}
-
-// Duff's device [https://en.wikipedia.org/wiki/Duff's_device]
-// The check does not try to distinguish branches in this sort of convoluted
-// code, but it should avoid crashing.
-void send(short *to, short *from, int count)
-{
-    int n = (count + 7) / 8;
-    switch (count % 8) {
-    case 0: do { *to = *from++;
-    case 7:      *to = *from++;
-    case 6:      *to = *from++;
-    case 5:      *to = *from++;
-    case 4:      *to = *from++;
-    case 3:      *to = *from++;
-    case 2:      *to = *from++;
-    case 1:      *to = *from++;
-            } while (--n > 0);
-    }
-}
-
-//=========--------------------==========//
-
-void ternary1(bool b, int &x) {
-// CHECK-MESSAGES: :[[@LINE+1]]:6: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]
-  (b ? x : x) = 42;
-}
-
-int ternary2(bool b, int x) {
-// CHECK-MESSAGES: :[[@LINE+1]]:12: warning: conditional operator with identical true and false expressions [bugprone-branch-clone]
-  return b ? 42 : 42;
-}
-
-int ternary3(bool b, int x) {
-  return b ? 42 : 43;
-}
-
-int ternary4(bool b, int x) {
-  return b ? true ? 45 : 44 : false ? 45 : 44;
-}
-
-// We do not detect chains of conditional operators.
-int ternary5(bool b1, bool b2 int x) {
-  return b1 ? 42 : b2 ? 43 : 42;
-}




More information about the cfe-commits mailing list