@@ -139,10 +139,8 @@ static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
139139 return cast<BinaryOperator>(Left)->getOpcode () ==
140140 cast<BinaryOperator>(Right)->getOpcode ();
141141 case Stmt::UnaryExprOrTypeTraitExprClass:
142- const auto *LeftUnaryExpr =
143- cast<UnaryExprOrTypeTraitExpr>(Left);
144- const auto *RightUnaryExpr =
145- cast<UnaryExprOrTypeTraitExpr>(Right);
142+ const auto *LeftUnaryExpr = cast<UnaryExprOrTypeTraitExpr>(Left);
143+ const auto *RightUnaryExpr = cast<UnaryExprOrTypeTraitExpr>(Right);
146144 if (LeftUnaryExpr->isArgumentType () && RightUnaryExpr->isArgumentType ())
147145 return LeftUnaryExpr->getKind () == RightUnaryExpr->getKind () &&
148146 LeftUnaryExpr->getArgumentType () ==
@@ -699,7 +697,8 @@ static bool retrieveRelationalIntegerConstantExpr(
699697
700698 Symbol = OverloadedOperatorExpr->getArg (IntegerConstantIsFirstArg ? 1 : 0 );
701699 OperandExpr = OverloadedOperatorExpr;
702- Opcode = BinaryOperator::getOverloadedOpcode (OverloadedOperatorExpr->getOperator ());
700+ Opcode = BinaryOperator::getOverloadedOpcode (
701+ OverloadedOperatorExpr->getOperator ());
703702
704703 if (!retrieveIntegerConstantExpr (Result, Id, Value, ConstExpr))
705704 return false ;
@@ -728,7 +727,8 @@ static bool retrieveRelationalIntegerConstantExpr(
728727}
729728
730729// Checks for expressions like (X == 4) && (Y != 9)
731- static bool areSidesBinaryConstExpressions (const BinaryOperator *&BinOp, const ASTContext *AstCtx) {
730+ static bool areSidesBinaryConstExpressions (const BinaryOperator *&BinOp,
731+ const ASTContext *AstCtx) {
732732 const auto *LhsBinOp = dyn_cast<BinaryOperator>(BinOp->getLHS ());
733733 const auto *RhsBinOp = dyn_cast<BinaryOperator>(BinOp->getRHS ());
734734
@@ -747,6 +747,31 @@ static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const A
747747 return false ;
748748}
749749
750+ static bool
751+ areSidesBinaryConstExpressionsOrDefines (const BinaryOperator *&BinOp,
752+ const ASTContext *AstCtx) {
753+ if (areSidesBinaryConstExpressions (BinOp, AstCtx))
754+ return true ;
755+
756+ const auto *Lhs = BinOp->getLHS ();
757+ const auto *Rhs = BinOp->getRHS ();
758+
759+ if (!Lhs || !Rhs)
760+ return false ;
761+
762+ auto IsDefineExpr = [AstCtx](const Expr *E) {
763+ SourceRange Lsr = E->getSourceRange ();
764+ if (!Lsr.getBegin ().isMacroID () || E->isValueDependent () ||
765+ !E->isIntegerConstantExpr (*AstCtx))
766+ return false ;
767+ return true ;
768+ };
769+
770+ if (IsDefineExpr (Lhs) || IsDefineExpr (Rhs))
771+ return true ;
772+ return false ;
773+ }
774+
750775// Retrieves integer constant subexpressions from binary operator expressions
751776// that have two equivalent sides.
752777// E.g.: from (X == 5) && (X == 5) retrieves 5 and 5.
@@ -785,7 +810,7 @@ static bool retrieveConstExprFromBothSides(const BinaryOperator *&BinOp,
785810}
786811
787812static bool isSameRawIdentifierToken (const Token &T1, const Token &T2,
788- const SourceManager &SM) {
813+ const SourceManager &SM) {
789814 if (T1.getKind () != T2.getKind ())
790815 return false ;
791816 if (T1.isNot (tok::raw_identifier))
@@ -852,6 +877,58 @@ static bool areExprsMacroAndNonMacro(const Expr *&LhsExpr,
852877
853878 return LhsLoc.isMacroID () != RhsLoc.isMacroID ();
854879}
880+
881+ static bool areExprsSameMacroOrLiteral (const BinaryOperator *BinOp,
882+ const ASTContext *Context) {
883+
884+ if (!BinOp)
885+ return false ;
886+
887+ const auto *Lhs = BinOp->getLHS ();
888+ const auto *Rhs = BinOp->getRHS ();
889+ const SourceManager &SM = Context->getSourceManager ();
890+
891+ SourceRange Lsr = Lhs->getSourceRange ();
892+ SourceRange Rsr = Rhs->getSourceRange ();
893+ if (Lsr.getBegin ().isMacroID ()) {
894+ // Left is macro so right macro too
895+ if (Rsr.getBegin ().isMacroID ()) {
896+ // Both sides are macros so they are same macro or literal
897+ llvm::StringRef L = Lexer::getSourceText (
898+ CharSourceRange::getTokenRange (Lsr), SM, LangOptions (), 0 );
899+ llvm::StringRef R = Lexer::getSourceText (
900+ CharSourceRange::getTokenRange (Rsr), SM, LangOptions (), 0 );
901+ return L.compare (R) == 0 ;
902+ }
903+ // Left is macro but right is not so they are not same macro or literal
904+ return false ;
905+ } else {
906+ const IntegerLiteral *Lil = dyn_cast<IntegerLiteral>(Lhs);
907+ const IntegerLiteral *Ril = dyn_cast<IntegerLiteral>(Rhs);
908+ if (Lil && Ril) {
909+ return Lil->getValue () == Ril->getValue ();
910+ }
911+
912+ const StringLiteral *LStrl = dyn_cast<StringLiteral>(Lhs);
913+ const StringLiteral *RStrl = dyn_cast<StringLiteral>(Rhs);
914+ if (Lil && Ril) {
915+ llvm::StringRef L = Lexer::getSourceText (
916+ CharSourceRange::getTokenRange (LStrl->getBeginLoc ()), SM,
917+ LangOptions (), 0 );
918+ llvm::StringRef R = Lexer::getSourceText (
919+ CharSourceRange::getTokenRange (RStrl->getBeginLoc ()), SM,
920+ LangOptions (), 0 );
921+ return L.compare (R) == 0 ;
922+ }
923+
924+ const CXXBoolLiteralExpr *Lbl = dyn_cast<CXXBoolLiteralExpr>(Lhs);
925+ const CXXBoolLiteralExpr *Rbl = dyn_cast<CXXBoolLiteralExpr>(Rhs);
926+ if (Lbl && Rbl) {
927+ return Lbl->getValue () == Rbl->getValue ();
928+ }
929+ }
930+ return false ;
931+ }
855932} // namespace
856933
857934void RedundantExpressionCheck::registerMatchers (MatchFinder *Finder) {
@@ -1089,7 +1166,6 @@ static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, APSInt Value) {
10891166 ((Opcode == BO_And || Opcode == BO_AndAssign) && ~Value == 0 );
10901167}
10911168
1092-
10931169void RedundantExpressionCheck::checkBitwiseExpr (
10941170 const MatchFinder::MatchResult &Result) {
10951171 if (const auto *ComparisonOperator = Result.Nodes .getNodeAs <BinaryOperator>(
@@ -1134,8 +1210,8 @@ void RedundantExpressionCheck::checkBitwiseExpr(
11341210 ConstExpr))
11351211 return ;
11361212
1137- if ((Value != 0 && ~Value != 0 ) || Sym->getExprLoc ().isMacroID ())
1138- return ;
1213+ if ((Value != 0 && ~Value != 0 ) || Sym->getExprLoc ().isMacroID ())
1214+ return ;
11391215
11401216 SourceLocation Loc = IneffectiveOperator->getOperatorLoc ();
11411217
@@ -1276,17 +1352,21 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) {
12761352 return ;
12771353 }
12781354
1279- if (areSidesBinaryConstExpressions (BinOp, Result.Context )) {
1355+ if (areSidesBinaryConstExpressionsOrDefines (BinOp, Result.Context )) {
12801356 const Expr *LhsConst = nullptr , *RhsConst = nullptr ;
12811357 BinaryOperatorKind MainOpcode{}, SideOpcode{};
1282-
1283- if (!retrieveConstExprFromBothSides (BinOp, MainOpcode, SideOpcode,
1284- LhsConst, RhsConst, Result.Context ))
1285- return ;
1286-
1287- if (areExprsFromDifferentMacros (LhsConst, RhsConst, Result.Context ) ||
1288- areExprsMacroAndNonMacro (LhsConst, RhsConst))
1289- return ;
1358+ if (areSidesBinaryConstExpressions (BinOp, Result.Context )) {
1359+ if (!retrieveConstExprFromBothSides (BinOp, MainOpcode, SideOpcode,
1360+ LhsConst, RhsConst, Result.Context ))
1361+ return ;
1362+
1363+ if (areExprsFromDifferentMacros (LhsConst, RhsConst, Result.Context ) ||
1364+ areExprsMacroAndNonMacro (LhsConst, RhsConst))
1365+ return ;
1366+ } else {
1367+ if (!areExprsSameMacroOrLiteral (BinOp, Result.Context ))
1368+ return ;
1369+ }
12901370 }
12911371
12921372 diag (BinOp->getOperatorLoc (), " both sides of operator are equivalent" );
0 commit comments