forked from OSchip/llvm-project
[clang-tidy] Disable Checks on If constexpr statements in template Instantiations for BugproneBranchClone and ReadabilityBracesAroundStatements
Summary: fixes [[ https://bugs.llvm.org/show_bug.cgi?id=32203 | readability-braces-around-statements broken for if constexpr]] and [[ https://bugs.llvm.org/show_bug.cgi?id=44229 | bugprone-branch-clone false positive with template functions and constexpr ]] by disabling the relevant checks on if constexpr statements while inside an instantiated template. This is due to how the else branch of an if constexpr statement is folded away to a null statement if the condition evaluates to false Reviewers: alexfh, hokein, aaron.ballman, xazax.hun Reviewed By: aaron.ballman, xazax.hun Subscribers: rnkovacs, JonasToth, Jim, lebedev.ri, xazax.hun, cfe-commits Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D71980
This commit is contained in:
parent
8eb4d25a09
commit
f9c46229e4
|
@ -59,7 +59,8 @@ namespace bugprone {
|
|||
|
||||
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);
|
||||
|
|
|
@ -123,7 +123,10 @@ void BracesAroundStatementsCheck::storeOptions(
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// RUN: %check_clang_tidy %s bugprone-branch-clone %t -- -- -std=c++17
|
||||
|
||||
void handle(int);
|
||||
|
||||
template <unsigned Index>
|
||||
void shouldFail() {
|
||||
if constexpr (Index == 0) {
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: repeated branch in conditional chain [bugprone-branch-clone]
|
||||
handle(0);
|
||||
} else if constexpr (Index == 1) {
|
||||
handle(1);
|
||||
} else {
|
||||
handle(0);
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned Index>
|
||||
void shouldPass() {
|
||||
if constexpr (Index == 0) {
|
||||
handle(0);
|
||||
} else if constexpr (Index == 1) {
|
||||
handle(1);
|
||||
} else {
|
||||
handle(2);
|
||||
}
|
||||
}
|
||||
|
||||
void shouldFailNonTemplate() {
|
||||
constexpr unsigned Index = 1;
|
||||
if constexpr (Index == 0) {
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: repeated branch in conditional chain [bugprone-branch-clone]
|
||||
handle(0);
|
||||
} else if constexpr (Index == 1) {
|
||||
handle(1);
|
||||
} else {
|
||||
handle(0);
|
||||
}
|
||||
}
|
||||
|
||||
void shouldPassNonTemplate() {
|
||||
constexpr unsigned Index = 1;
|
||||
if constexpr (Index == 0) {
|
||||
handle(0);
|
||||
} else if constexpr (Index == 1) {
|
||||
handle(1);
|
||||
} else {
|
||||
handle(2);
|
||||
}
|
||||
}
|
||||
|
||||
void run() {
|
||||
shouldFail<0>();
|
||||
shouldFail<1>();
|
||||
shouldFail<2>();
|
||||
shouldPass<0>();
|
||||
shouldPass<1>();
|
||||
shouldPass<2>();
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// RUN: %check_clang_tidy %s readability-braces-around-statements %t -- -- -std=c++17
|
||||
|
||||
void handle(bool);
|
||||
|
||||
template <bool branch>
|
||||
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 <bool branch>
|
||||
void shouldPass() {
|
||||
if constexpr (branch) {
|
||||
handle(true);
|
||||
} else {
|
||||
handle(false);
|
||||
}
|
||||
}
|
||||
|
||||
void shouldFailNonTemplate() {
|
||||
constexpr bool branch = false;
|
||||
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);
|
||||
}
|
||||
|
||||
void shouldPass() {
|
||||
constexpr bool branch = false;
|
||||
if constexpr (branch) {
|
||||
handle(true);
|
||||
} else {
|
||||
handle(false);
|
||||
}
|
||||
}
|
||||
|
||||
void run() {
|
||||
shouldFail<true>();
|
||||
shouldFail<false>();
|
||||
shouldPass<true>();
|
||||
shouldPass<false>();
|
||||
}
|
Loading…
Reference in New Issue