[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