diff options
author | Alexander Kornienko <alexfh@google.com> | 2015-07-01 12:39:40 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2015-07-01 12:39:40 +0000 |
commit | 6ae400d12256de0547c1b06919d126f664c78d7e (patch) | |
tree | 2c16f7333e11b0f4c9bb2ee046f8b7a89ffd6b94 /clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h | |
parent | def554db451cafb36b71d95823eaf65538b0a3b7 (diff) | |
download | bcm5719-llvm-6ae400d12256de0547c1b06919d126f664c78d7e.tar.gz bcm5719-llvm-6ae400d12256de0547c1b06919d126f664c78d7e.zip |
[clang-tidy] Enhance clang-tidy readability-simplify-boolean-expr...
Enhance clang-tidy readability-simplify-boolean-expr to handle 'if (e) return
true; return false;' and improve replacement expressions.
This changeset extends the simplify boolean expression check in clang-tidy to
simplify if (e) return true; return false; to return e; (note the lack of an
else clause on the if statement.) By default, chained conditional assignment is
left unchanged, unless a configuration parameter is set to non-zero to override
this behavior.
It also improves the handling of replacement expressions to apply
static_cast<bool>(expr) when expr is not of type bool.
http://reviews.llvm.org/D9810
Patch by Richard Thomson!
llvm-svn: 241155
Diffstat (limited to 'clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h')
-rw-r--r-- | clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h index 365d8211347..ac38d233af9 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h +++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h @@ -34,9 +34,46 @@ namespace readability { /// `if (e) return false; else return true;` becomes `return !e;` /// `if (e) b = true; else b = false;` becomes `b = e;` /// `if (e) b = false; else b = true;` becomes `b = !e;` +/// `if (e) return true; return false;` becomes `return e;` +/// `if (e) return false; return true;` becomes `return !e;` /// -/// Parenthesis from the resulting expression `e` are removed whenever -/// possible. +/// The resulting expression `e` is modified as follows: +/// 1. Unnecessary parentheses around the expression are removed. +/// 2. Negated applications of `!` are eliminated. +/// 3. Negated applications of comparison operators are changed to use the +/// opposite condition. +/// 4. Implicit conversions of pointer to `bool` are replaced with explicit +/// comparisons to `nullptr`. +/// 5. Implicit casts to `bool` are replaced with explicit casts to `bool`. +/// 6. Object expressions with `explicit operator bool` conversion operators +/// are replaced with explicit casts to `bool`. +/// +/// Examples: +/// 1. The ternary assignment `bool b = (i < 0) ? true : false;` has redundant +/// parentheses and becomes `bool b = i < 0;`. +/// +/// 2. The conditional return `if (!b) return false; return true;` has an +/// implied double negation and becomes `return b;`. +/// +/// 3. The conditional return `if (i < 0) return false; return true;` becomes +/// `return i >= 0;`. +/// The conditional return `if (i != 0) return false; return true;` becomes +/// `return i == 0;`. +/// +/// 4. The conditional return `if (p) return true; return false;` has an +/// implicit conversion of a pointer to `bool` and becomes +/// `return p != nullptr;`. +/// The ternary assignment `bool b = (i & 1) ? true : false;` has an implicit +/// conversion of `i & 1` to `bool` and becomes +/// `bool b = static_cast<bool>(i & 1);`. +/// +/// 5. The conditional return `if (i & 1) return true; else return false;` has +/// an implicit conversion of an integer quantity `i & 1` to `bool` and becomes +/// `return static_cast<bool>(i & 1);` +/// +/// 6. Given `struct X { explicit operator bool(); };`, and an instance `x` of +/// `struct X`, the conditional return `if (x) return true; return false;` +/// becomes `return static_cast<bool>(x);` /// /// When a conditional boolean return or assignment appears at the end of a /// chain of `if`, `else if` statements, the conditional statement is left @@ -77,6 +114,9 @@ private: void matchIfAssignsBool(ast_matchers::MatchFinder *Finder, bool Value, StringRef Id); + void matchCompoundIfReturnsBool(ast_matchers::MatchFinder *Finder, bool Value, + StringRef Id); + void replaceWithExpression(const ast_matchers::MatchFinder::MatchResult &Result, const CXXBoolLiteralExpr *BoolLiteral, bool UseLHS, @@ -103,6 +143,10 @@ private: replaceWithAssignment(const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If, bool Negated = false); + void replaceCompoundReturnWithCondition( + const ast_matchers::MatchFinder::MatchResult &Result, + const CompoundStmt *Compound, bool Negated = false); + const bool ChainedConditionalReturn; const bool ChainedConditionalAssignment; }; |