Index: clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp +++ clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp @@ -59,7 +59,8 @@ void BranchCloneCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - ifStmt(stmt().bind("if"), + ifStmt(unless(allOf(isConstexpr(), isInTemplateInstantiation())), + stmt().bind("if"), hasParent(stmt(unless(ifStmt(hasElse(equalsBoundNode("if")))))), hasElse(stmt().bind("else"))), this); Index: clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp +++ clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp @@ -123,7 +123,10 @@ } void BracesAroundStatementsCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(ifStmt().bind("if"), this); + Finder->addMatcher( + ifStmt(unless(allOf(isConstexpr(), isInTemplateInstantiation()))) + .bind("if"), + this); Finder->addMatcher(whileStmt().bind("while"), this); Finder->addMatcher(doStmt().bind("do"), this); Finder->addMatcher(forStmt().bind("for"), this); Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone-if-constexpr-template.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone-if-constexpr-template.cpp @@ -0,0 +1,35 @@ +// RUN: %check_clang_tidy %s bugprone-branch-clone %t -- -- -std=c++17 + +void handle(int); + +template +void shouldFail() { + if constexpr (T == 0) { + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: repeated branch in conditional chain [bugprone-branch-clone] + handle(0); + } else if constexpr (T == 1) { + handle(1); + } else { + handle(0); + } +} + +template +void shouldPass() { + if constexpr (T == 0) { + handle(0); + } else if constexpr (T == 1) { + handle(1); + } else { + handle(2); + } +} + +void run() { + shouldFail<0>(); + shouldFail<1>(); + shouldFail<2>(); + shouldPass<0>(); + shouldPass<1>(); + shouldPass<2>(); +} \ No newline at end of file Index: clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements-constexpr-if-templates.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements-constexpr-if-templates.cpp @@ -0,0 +1,29 @@ +// RUN: %check_clang_tidy %s readability-braces-around-statements %t -- -- -std=c++17 + +void handle(bool); + +template +void shouldFail() { + if constexpr (branch) + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: statement should be inside braces [readability-braces-around-statements] + handle(true); + else + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: statement should be inside braces [readability-braces-around-statements] + handle(false); +} + +template +void shouldPass() { + if constexpr (branch) { + handle(true); + } else { + handle(false); + } +} + +void run() { + shouldFail(); + shouldFail(); + shouldPass(); + shouldPass(); +} \ No newline at end of file