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,25 @@ 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
+ static bool isExpectedUnaryLNot (SimplifyBooleanExprCheck *Check,
517
+ const Expr *E) {
518
+ return !Check->canBeBypassed (E) && isa<UnaryOperator>(E) &&
518
519
cast<UnaryOperator>(E)->getOpcode () == UO_LNot;
519
520
}
520
521
522
+ static bool isExpectedBinaryOp (SimplifyBooleanExprCheck *Check,
523
+ const Expr *E) {
524
+ const auto *BinaryOp = dyn_cast<BinaryOperator>(E);
525
+ return !Check->canBeBypassed (E) && BinaryOp && BinaryOp->isLogicalOp () &&
526
+ BinaryOp->getType ()->isBooleanType ();
527
+ }
528
+
521
529
template <typename Functor>
522
530
static bool checkEitherSide (const BinaryOperator *BO, Functor Func) {
523
531
return Func (BO->getLHS ()) || Func (BO->getRHS ());
524
532
}
525
533
526
- static bool nestedDemorgan (const Expr *E, unsigned NestingLevel) {
534
+ bool nestedDemorgan (const Expr *E, unsigned NestingLevel) {
527
535
const auto *BO = dyn_cast<BinaryOperator>(E->IgnoreUnlessSpelledInSource ());
528
536
if (!BO)
529
537
return false ;
@@ -539,15 +547,14 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
539
547
return true ;
540
548
case BO_LAnd:
541
549
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 ;
550
+ return checkEitherSide (BO,
551
+ [this ](const Expr *E) {
552
+ return isExpectedUnaryLNot (Check, E);
553
+ }) ||
554
+ (NestingLevel &&
555
+ checkEitherSide (BO, [this , NestingLevel](const Expr *E) {
556
+ return nestedDemorgan (E, NestingLevel - 1 );
557
+ }));
551
558
default :
552
559
return false ;
553
560
}
@@ -556,19 +563,19 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
556
563
bool TraverseUnaryOperator (UnaryOperator *Op) {
557
564
if (!Check->SimplifyDeMorgan || Op->getOpcode () != UO_LNot)
558
565
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 ())
566
+ const Expr *SubImp = Op->getSubExpr ()->IgnoreImplicit ();
567
+ const auto *Parens = dyn_cast<ParenExpr>(SubImp);
568
+ const Expr *SubExpr =
569
+ Parens ? Parens->getSubExpr ()->IgnoreImplicit () : SubImp;
570
+ if (!isExpectedBinaryOp (Check, SubExpr))
567
571
return Base::TraverseUnaryOperator (Op);
572
+ const auto *BinaryOp = cast<BinaryOperator>(SubExpr);
568
573
if (Check->SimplifyDeMorganRelaxed ||
569
- checkEitherSide (BinaryOp, isUnaryLNot) ||
570
- checkEitherSide (BinaryOp,
571
- [](const Expr *E) { return nestedDemorgan (E, 1 ); })) {
574
+ checkEitherSide (
575
+ BinaryOp,
576
+ [this ](const Expr *E) { return isExpectedUnaryLNot (Check, E); }) ||
577
+ checkEitherSide (
578
+ BinaryOp, [this ](const Expr *E) { return nestedDemorgan (E, 1 ); })) {
572
579
if (Check->reportDeMorgan (Context, Op, BinaryOp, !IsProcessing, parent (),
573
580
Parens) &&
574
581
!Check->areDiagsSelfContained ()) {
@@ -694,6 +701,10 @@ void SimplifyBooleanExprCheck::check(const MatchFinder::MatchResult &Result) {
694
701
Visitor (this , *Result.Context ).traverse ();
695
702
}
696
703
704
+ bool SimplifyBooleanExprCheck::canBeBypassed (const Stmt *S) const {
705
+ return IgnoreMacros && S->getBeginLoc ().isMacroID ();
706
+ }
707
+
697
708
void SimplifyBooleanExprCheck::issueDiag (const ASTContext &Context,
698
709
SourceLocation Loc,
699
710
StringRef Description,
0 commit comments