7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " SimplifyBooleanExprCheck.h"
10
+ #include " clang/AST/Expr.h"
10
11
#include " clang/AST/RecursiveASTVisitor.h"
11
12
#include " clang/Lex/Lexer.h"
12
13
#include " llvm/Support/SaveAndRestore.h"
@@ -280,9 +281,8 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
280
281
if (!S) {
281
282
return true ;
282
283
}
283
- if (Check->IgnoreMacros && S-> getBeginLoc (). isMacroID ()) {
284
+ if (Check->canBeBypassed (S))
284
285
return false ;
285
- }
286
286
if (!shouldIgnore (S))
287
287
StmtStack.push_back (S);
288
288
return true ;
@@ -513,17 +513,23 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
513
513
return true ;
514
514
}
515
515
516
- static bool isUnaryLNot (const Expr *E) {
517
- return isa<UnaryOperator>(E) &&
516
+ bool isExpectedUnaryLNot (const Expr *E) {
517
+ return !Check-> canBeBypassed (E) && isa<UnaryOperator>(E) &&
518
518
cast<UnaryOperator>(E)->getOpcode () == UO_LNot;
519
519
}
520
520
521
+ bool isExpectedBinaryOp (const Expr *E) {
522
+ const auto *BinaryOp = dyn_cast<BinaryOperator>(E);
523
+ return !Check->canBeBypassed (E) && BinaryOp && BinaryOp->isLogicalOp () &&
524
+ BinaryOp->getType ()->isBooleanType ();
525
+ }
526
+
521
527
template <typename Functor>
522
528
static bool checkEitherSide (const BinaryOperator *BO, Functor Func) {
523
529
return Func (BO->getLHS ()) || Func (BO->getRHS ());
524
530
}
525
531
526
- static bool nestedDemorgan (const Expr *E, unsigned NestingLevel) {
532
+ bool nestedDemorgan (const Expr *E, unsigned NestingLevel) {
527
533
const auto *BO = dyn_cast<BinaryOperator>(E->IgnoreUnlessSpelledInSource ());
528
534
if (!BO)
529
535
return false ;
@@ -539,15 +545,13 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
539
545
return true ;
540
546
case BO_LAnd:
541
547
case BO_LOr:
542
- if (checkEitherSide (BO, isUnaryLNot))
543
- return true ;
544
- if (NestingLevel) {
545
- if (checkEitherSide (BO, [NestingLevel](const Expr *E) {
546
- return nestedDemorgan (E, NestingLevel - 1 );
547
- }))
548
- return true ;
549
- }
550
- return false ;
548
+ return checkEitherSide (
549
+ BO,
550
+ [this ](const Expr *E) { return isExpectedUnaryLNot (E); }) ||
551
+ (NestingLevel &&
552
+ checkEitherSide (BO, [this , NestingLevel](const Expr *E) {
553
+ return nestedDemorgan (E, NestingLevel - 1 );
554
+ }));
551
555
default :
552
556
return false ;
553
557
}
@@ -556,19 +560,19 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
556
560
bool TraverseUnaryOperator (UnaryOperator *Op) {
557
561
if (!Check->SimplifyDeMorgan || Op->getOpcode () != UO_LNot)
558
562
return Base::TraverseUnaryOperator (Op);
559
- Expr *SubImp = Op->getSubExpr ()->IgnoreImplicit ();
560
- auto *Parens = dyn_cast<ParenExpr>(SubImp);
561
- auto *BinaryOp =
562
- Parens
563
- ? dyn_cast<BinaryOperator>(Parens->getSubExpr ()->IgnoreImplicit ())
564
- : dyn_cast<BinaryOperator>(SubImp);
565
- if (!BinaryOp || !BinaryOp->isLogicalOp () ||
566
- !BinaryOp->getType ()->isBooleanType ())
563
+ const Expr *SubImp = Op->getSubExpr ()->IgnoreImplicit ();
564
+ const auto *Parens = dyn_cast<ParenExpr>(SubImp);
565
+ const Expr *SubExpr =
566
+ Parens ? Parens->getSubExpr ()->IgnoreImplicit () : SubImp;
567
+ if (!isExpectedBinaryOp (SubExpr))
567
568
return Base::TraverseUnaryOperator (Op);
569
+ const auto *BinaryOp = cast<BinaryOperator>(SubExpr);
568
570
if (Check->SimplifyDeMorganRelaxed ||
569
- checkEitherSide (BinaryOp, isUnaryLNot) ||
570
- checkEitherSide (BinaryOp,
571
- [](const Expr *E) { return nestedDemorgan (E, 1 ); })) {
571
+ checkEitherSide (
572
+ BinaryOp,
573
+ [this ](const Expr *E) { return isExpectedUnaryLNot (E); }) ||
574
+ checkEitherSide (
575
+ BinaryOp, [this ](const Expr *E) { return nestedDemorgan (E, 1 ); })) {
572
576
if (Check->reportDeMorgan (Context, Op, BinaryOp, !IsProcessing, parent (),
573
577
Parens) &&
574
578
!Check->areDiagsSelfContained ()) {
@@ -694,6 +698,10 @@ void SimplifyBooleanExprCheck::check(const MatchFinder::MatchResult &Result) {
694
698
Visitor (this , *Result.Context ).traverse ();
695
699
}
696
700
701
+ bool SimplifyBooleanExprCheck::canBeBypassed (const Stmt *S) const {
702
+ return IgnoreMacros && S->getBeginLoc ().isMacroID ();
703
+ }
704
+
697
705
void SimplifyBooleanExprCheck::issueDiag (const ASTContext &Context,
698
706
SourceLocation Loc,
699
707
StringRef Description,
0 commit comments