summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp3
-rw-r--r--clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp5
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone-if-constexpr-template.cpp58
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements-constexpr-if-templates.cpp48
4 files changed, 112 insertions, 2 deletions
diff --git a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp
index eb54aaa9944..e40b27585d3 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp
@@ -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);
diff --git a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
index 117ef36d78f..da0bef32c09 100644
--- a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
@@ -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);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone-if-constexpr-template.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone-if-constexpr-template.cpp
new file mode 100644
index 00000000000..382330139c8
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone-if-constexpr-template.cpp
@@ -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>();
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements-constexpr-if-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements-constexpr-if-templates.cpp
new file mode 100644
index 00000000000..988125f9ce2
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability-braces-around-statements-constexpr-if-templates.cpp
@@ -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>();
+}
OpenPOWER on IntegriCloud