@@ -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,28 @@ static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const A
747747 return false ;
748748}
749749
750+ static bool areSidesBinaryConstExpressionsOrDefinesOrIntegerConstant (
751+ const BinaryOperator *&BinOp, const ASTContext *AstCtx) {
752+ if (areSidesBinaryConstExpressions (BinOp, AstCtx))
753+ return true ;
754+
755+ const Expr *Lhs = BinOp->getLHS ();
756+ const Expr *Rhs = BinOp->getRHS ();
757+
758+ if (!Lhs || !Rhs)
759+ return false ;
760+
761+ auto IsDefineExpr = [AstCtx](const Expr *E) {
762+ SourceRange Lsr = E->getSourceRange ();
763+ if (!Lsr.getBegin ().isMacroID () || E->isValueDependent () ||
764+ !E->isIntegerConstantExpr (*AstCtx))
765+ return false ;
766+ return true ;
767+ };
768+
769+ return IsDefineExpr (Lhs) || IsDefineExpr (Rhs);
770+ }
771+
750772// Retrieves integer constant subexpressions from binary operator expressions
751773// that have two equivalent sides.
752774// E.g.: from (X == 5) && (X == 5) retrieves 5 and 5.
@@ -785,7 +807,7 @@ static bool retrieveConstExprFromBothSides(const BinaryOperator *&BinOp,
785807}
786808
787809static bool isSameRawIdentifierToken (const Token &T1, const Token &T2,
788- const SourceManager &SM) {
810+ const SourceManager &SM) {
789811 if (T1.getKind () != T2.getKind ())
790812 return false ;
791813 if (T1.isNot (tok::raw_identifier))
@@ -852,6 +874,58 @@ static bool areExprsMacroAndNonMacro(const Expr *&LhsExpr,
852874
853875 return LhsLoc.isMacroID () != RhsLoc.isMacroID ();
854876}
877+
878+ static bool areExprsSameMacroOrLiteral (const BinaryOperator *BinOp,
879+ const ASTContext *Context) {
880+
881+ if (!BinOp)
882+ return false ;
883+
884+ const Expr *Lhs = BinOp->getLHS ();
885+ const Expr *Rhs = BinOp->getRHS ();
886+ const SourceManager &SM = Context->getSourceManager ();
887+
888+ SourceRange Lsr = Lhs->getSourceRange ();
889+ SourceRange Rsr = Rhs->getSourceRange ();
890+ if (Lsr.getBegin ().isMacroID ()) {
891+ // Left is macro so right macro too
892+ if (Rsr.getBegin ().isMacroID ()) {
893+ // Both sides are macros so they are same macro or literal
894+ llvm::StringRef L = Lexer::getSourceText (
895+ CharSourceRange::getTokenRange (Lsr), SM, LangOptions (), 0 );
896+ llvm::StringRef R = Lexer::getSourceText (
897+ CharSourceRange::getTokenRange (Rsr), SM, LangOptions (), 0 );
898+ return L.compare (R) == 0 ;
899+ }
900+ // Left is macro but right is not so they are not same macro or literal
901+ return false ;
902+ } else {
903+ const auto *Lil = dyn_cast<IntegerLiteral>(Lhs);
904+ const auto *Ril = dyn_cast<IntegerLiteral>(Rhs);
905+ if (Lil && Ril) {
906+ return Lil->getValue () == Ril->getValue ();
907+ }
908+
909+ const auto *LStrl = dyn_cast<StringLiteral>(Lhs);
910+ const auto *RStrl = dyn_cast<StringLiteral>(Rhs);
911+ if (Lil && Ril) {
912+ llvm::StringRef L = Lexer::getSourceText (
913+ CharSourceRange::getTokenRange (LStrl->getBeginLoc ()), SM,
914+ LangOptions (), 0 );
915+ llvm::StringRef R = Lexer::getSourceText (
916+ CharSourceRange::getTokenRange (RStrl->getBeginLoc ()), SM,
917+ LangOptions (), 0 );
918+ return L.compare (R) == 0 ;
919+ }
920+
921+ const auto *Lbl = dyn_cast<CXXBoolLiteralExpr>(Lhs);
922+ const auto *Rbl = dyn_cast<CXXBoolLiteralExpr>(Rhs);
923+ if (Lbl && Rbl) {
924+ return Lbl->getValue () == Rbl->getValue ();
925+ }
926+ }
927+ return false ;
928+ }
855929} // namespace
856930
857931void RedundantExpressionCheck::registerMatchers (MatchFinder *Finder) {
@@ -1089,7 +1163,6 @@ static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, APSInt Value) {
10891163 ((Opcode == BO_And || Opcode == BO_AndAssign) && ~Value == 0 );
10901164}
10911165
1092-
10931166void RedundantExpressionCheck::checkBitwiseExpr (
10941167 const MatchFinder::MatchResult &Result) {
10951168 if (const auto *ComparisonOperator = Result.Nodes .getNodeAs <BinaryOperator>(
@@ -1134,8 +1207,8 @@ void RedundantExpressionCheck::checkBitwiseExpr(
11341207 ConstExpr))
11351208 return ;
11361209
1137- if ((Value != 0 && ~Value != 0 ) || Sym->getExprLoc ().isMacroID ())
1138- return ;
1210+ if ((Value != 0 && ~Value != 0 ) || Sym->getExprLoc ().isMacroID ())
1211+ return ;
11391212
11401213 SourceLocation Loc = IneffectiveOperator->getOperatorLoc ();
11411214
@@ -1276,19 +1349,23 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) {
12761349 return ;
12771350 }
12781351
1279- if (areSidesBinaryConstExpressions (BinOp, Result.Context )) {
1352+ if (areSidesBinaryConstExpressionsOrDefinesOrIntegerConstant (
1353+ BinOp, Result.Context )) {
12801354 const Expr *LhsConst = nullptr , *RhsConst = nullptr ;
12811355 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 ;
1356+ if (areSidesBinaryConstExpressions (BinOp, Result.Context )) {
1357+ if (!retrieveConstExprFromBothSides (BinOp, MainOpcode, SideOpcode,
1358+ LhsConst, RhsConst, Result.Context ))
1359+ return ;
1360+
1361+ if (areExprsFromDifferentMacros (LhsConst, RhsConst, Result.Context ) ||
1362+ areExprsMacroAndNonMacro (LhsConst, RhsConst))
1363+ return ;
1364+ } else {
1365+ if (!areExprsSameMacroOrLiteral (BinOp, Result.Context ))
1366+ return ;
1367+ }
12901368 }
1291-
12921369 diag (BinOp->getOperatorLoc (), " both sides of operator are equivalent" );
12931370 }
12941371
0 commit comments