[clang-tools-extra] f3c1d28 - [clang-tidy] Extend SimplifyBooleanExpr demorgan support.
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Wed May 25 05:09:12 PDT 2022
Author: Nathan James
Date: 2022-05-25T13:09:00+01:00
New Revision: f3c1d281767a5849b9f3e712e3c3406bd9410c81
URL: https://github.com/llvm/llvm-project/commit/f3c1d281767a5849b9f3e712e3c3406bd9410c81
DIFF: https://github.com/llvm/llvm-project/commit/f3c1d281767a5849b9f3e712e3c3406bd9410c81.diff
LOG: [clang-tidy] Extend SimplifyBooleanExpr demorgan support.
Adds an option SimplifyDemorganRelaxed which, when enabled, will transform negated conjunctions or disjunctions when neither operand is a negation.
Default value is `false`.
Reviewed By: LegalizeAdulthood
Differential Revision: https://reviews.llvm.org/D126162
Added:
Modified:
clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h
clang-tools-extra/docs/clang-tidy/checks/readability-simplify-boolean-expr.rst
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-demorgan.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
index f35f7839dc257..8ae990a929dfd 100644
--- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -558,7 +558,8 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
if (!BinaryOp || !BinaryOp->isLogicalOp() ||
!BinaryOp->getType()->isBooleanType())
return Base::TraverseUnaryOperator(Op);
- if (checkEitherSide(BinaryOp, isUnaryLNot) ||
+ if (Check->SimplifyDeMorganRelaxed ||
+ checkEitherSide(BinaryOp, isUnaryLNot) ||
checkEitherSide(BinaryOp,
[](const Expr *E) { return nestedDemorgan(E, 1); })) {
if (Check->reportDeMorgan(Context, Op, BinaryOp, !IsProcessing, parent(),
@@ -584,7 +585,13 @@ SimplifyBooleanExprCheck::SimplifyBooleanExprCheck(StringRef Name,
ChainedConditionalReturn(Options.get("ChainedConditionalReturn", false)),
ChainedConditionalAssignment(
Options.get("ChainedConditionalAssignment", false)),
- SimplifyDeMorgan(Options.get("SimplifyDeMorgan", true)) {}
+ SimplifyDeMorgan(Options.get("SimplifyDeMorgan", true)),
+ SimplifyDeMorganRelaxed(Options.get("SimplifyDeMorganRelaxed", false)) {
+ if (SimplifyDeMorganRelaxed && !SimplifyDeMorgan)
+ configurationDiag("%0: 'SimplifyDeMorganRelaxed' cannot be enabled "
+ "without 'SimplifyDeMorgan' enabled")
+ << Name;
+}
static bool containsBoolLiteral(const Expr *E) {
if (!E)
@@ -667,6 +674,7 @@ void SimplifyBooleanExprCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "ChainedConditionalAssignment",
ChainedConditionalAssignment);
Options.store(Opts, "SimplifyDeMorgan", SimplifyDeMorgan);
+ Options.store(Opts, "SimplifyDeMorganRelaxed", SimplifyDeMorganRelaxed);
}
void SimplifyBooleanExprCheck::registerMatchers(MatchFinder *Finder) {
diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h
index 72d8f3354b890..8da20f37b975e 100644
--- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h
@@ -69,6 +69,7 @@ class SimplifyBooleanExprCheck : public ClangTidyCheck {
const bool ChainedConditionalReturn;
const bool ChainedConditionalAssignment;
const bool SimplifyDeMorgan;
+ const bool SimplifyDeMorganRelaxed;
};
} // namespace readability
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-simplify-boolean-expr.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-simplify-boolean-expr.rst
index 240e7be64ad45..f25d4c418695f 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability-simplify-boolean-expr.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability-simplify-boolean-expr.rst
@@ -96,3 +96,23 @@ Options
If `true`, DeMorgan's Theorem will be applied to simplify negated
conjunctions and disjunctions. Default is `true`.
+
+.. option:: SimplifyDeMorganRelaxed
+
+ If `true`, :option:`SimplifyDeMorgan` will also transform negated
+ conjunctions and disjunctions where there is no negation on either operand.
+ Default is `false`.
+
+ When Enabled:
+
+ .. code-block::
+
+ bool X = !(A && B)
+ bool Y = !(A || B)
+
+ Would be transformed to:
+
+ .. code-block::
+
+ bool X = !A || !B
+ bool Y = !A && !B
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-demorgan.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-demorgan.cpp
index 12a9eb65352d8..6787273daa8c5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-demorgan.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-demorgan.cpp
@@ -1,9 +1,30 @@
// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t
+// Check when we can convert !(A Op B) -> !A InvOp !B.
+// RUN: %check_clang_tidy -check-suffixes=",RELAXED" %s \
+// RUN: readability-simplify-boolean-expr %t -- -config="{CheckOptions: [{ \
+// RUN: key: "readability-simplify-boolean-expr.SimplifyDeMorganRelaxed", value: true}]}" --
+
+// Verify warning issued when invalid options are specified.
+// RUN: clang-tidy %s -checks=-*,readability-simplify-boolean-expr -config="{CheckOptions: [ \
+// RUN: {key: readability-simplify-boolean-expr.SimplifyDeMorgan, value: false}, \
+// RUN: {key: readability-simplify-boolean-expr.SimplifyDeMorganRelaxed, value: true}]}" \
+// RUN: -- 2>&1 | FileCheck %s -check-prefix=CHECK-BAD-CONFIG \
+// RUN: -implicit-check-not="{{warning|error}}:"
+
+// CHECK-BAD-CONFIG: warning: readability-simplify-boolean-expr: 'SimplifyDeMorganRelaxed' cannot be enabled without 'SimplifyDeMorgan' enabled
void eat(bool);
void foo(bool A1, bool A2, bool A3, bool A4) {
bool X;
+
+ X = !(A1 && A2);
+ X = !(A1 || A2);
+ // CHECK-MESSAGES-RELAXED: :[[@LINE-2]]:7: warning: boolean expression can be simplified by DeMorgan's theorem
+ // CHECK-MESSAGES-RELAXED: :[[@LINE-2]]:7: warning: boolean expression can be simplified by DeMorgan's theorem
+ // CHECK-FIXES-RELAXED: X = !A1 || !A2;
+ // CHECK-FIXES-NEXT-RELAXED: X = !A1 && !A2;
+
X = !(!A1 || A2);
X = !(A1 || !A2);
X = !(!A1 || !A2);
More information about the cfe-commits
mailing list