@@ -13880,56 +13880,6 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
1388013880 return InvalidOperands(Loc, LHS, RHS);
1388113881}
1388213882
13883- // Diagnose cases where the user write a logical and/or but probably meant a
13884- // bitwise one. We do this when one of the operands is a non-bool integer and
13885- // the other is a constant.
13886- void Sema::diagnoseLogicalInsteadOfBitwise(Expr *Op1, Expr *Op2,
13887- SourceLocation Loc,
13888- BinaryOperatorKind Opc) {
13889- if (Op1->getType()->isIntegerType() && !Op1->getType()->isBooleanType() &&
13890- Op2->getType()->isIntegerType() && !Op2->isValueDependent() &&
13891- // Don't warn in macros or template instantiations.
13892- !Loc.isMacroID() && !inTemplateInstantiation() &&
13893- !Op2->getExprLoc().isMacroID() &&
13894- !Op1->getExprLoc().isMacroID()) {
13895- bool IsOp1InMacro = Op1->getExprLoc().isMacroID();
13896- bool IsOp2InMacro = Op2->getExprLoc().isMacroID();
13897-
13898- // Exclude the specific expression from triggering the warning.
13899- if (!(IsOp1InMacro && IsOp2InMacro && Op1->getSourceRange() == Op2->getSourceRange())) {
13900- // If the RHS can be constant folded, and if it constant folds to something
13901- // that isn't 0 or 1 (which indicate a potential logical operation that
13902- // happened to fold to true/false) then warn.
13903- // Parens on the RHS are ignored.
13904- // If the RHS can be constant folded, and if it constant folds to something
13905- // that isn't 0 or 1 (which indicate a potential logical operation that
13906- // happened to fold to true/false) then warn.
13907- // Parens on the RHS are ignored.
13908- Expr::EvalResult EVResult;
13909- if (Op2->EvaluateAsInt(EVResult, Context)) {
13910- llvm::APSInt Result = EVResult.Val.getInt();
13911- if ((getLangOpts().Bool && !Op2->getType()->isBooleanType() &&
13912- !Op2->getExprLoc().isMacroID()) ||
13913- (Result != 0 && Result != 1)) {
13914- Diag(Loc, diag::warn_logical_instead_of_bitwise)
13915- << Op2->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
13916- // Suggest replacing the logical operator with the bitwise version
13917- Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
13918- << (Opc == BO_LAnd ? "&" : "|")
13919- << FixItHint::CreateReplacement(
13920- SourceRange(Loc, getLocForEndOfToken(Loc)),
13921- Opc == BO_LAnd ? "&" : "|");
13922- if (Opc == BO_LAnd)
13923- // Suggest replacing "Foo() && kNonZero" with "Foo()"
13924- Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
13925- << FixItHint::CreateRemoval(SourceRange(
13926- getLocForEndOfToken(Op1->getEndLoc()), Op2->getEndLoc()));
13927- }
13928- }
13929- }
13930- }
13931- }
13932-
1393313883// C99 6.5.[13,14]
1393413884inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1393513885 SourceLocation Loc,
@@ -13948,6 +13898,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1394813898 }
1394913899 }
1395013900
13901+ if (EnumConstantInBoolContext)
13902+ Diag(Loc, diag::warn_enum_constant_in_bool_context);
13903+
1395113904 // WebAssembly tables can't be used with logical operators.
1395213905 QualType LHSTy = LHS.get()->getType();
1395313906 QualType RHSTy = RHS.get()->getType();
@@ -13958,14 +13911,40 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1395813911 return InvalidOperands(Loc, LHS, RHS);
1395913912 }
1396013913
13961- if (EnumConstantInBoolContext) {
13962- // Warn when converting the enum constant to a boolean
13963- Diag(Loc, diag::warn_enum_constant_in_bool_context);
13964- } else {
13965- // Diagnose cases where the user write a logical and/or but probably meant a
13966- // bitwise one.
13967- diagnoseLogicalInsteadOfBitwise(LHS.get(), RHS.get(), Loc, Opc);
13968- diagnoseLogicalInsteadOfBitwise(RHS.get(), LHS.get(), Loc, Opc);
13914+ // Diagnose cases where the user write a logical and/or but probably meant a
13915+ // bitwise one. We do this when the LHS is a non-bool integer and the RHS
13916+ // is a constant.
13917+ if (!EnumConstantInBoolContext && LHS.get()->getType()->isIntegerType() &&
13918+ !LHS.get()->getType()->isBooleanType() &&
13919+ RHS.get()->getType()->isIntegerType() && !RHS.get()->isValueDependent() &&
13920+ // Don't warn in macros or template instantiations.
13921+ !Loc.isMacroID() && !inTemplateInstantiation()) {
13922+ // If the RHS can be constant folded, and if it constant folds to something
13923+ // that isn't 0 or 1 (which indicate a potential logical operation that
13924+ // happened to fold to true/false) then warn.
13925+ // Parens on the RHS are ignored.
13926+ Expr::EvalResult EVResult;
13927+ if (RHS.get()->EvaluateAsInt(EVResult, Context)) {
13928+ llvm::APSInt Result = EVResult.Val.getInt();
13929+ if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
13930+ !RHS.get()->getExprLoc().isMacroID()) ||
13931+ (Result != 0 && Result != 1)) {
13932+ Diag(Loc, diag::warn_logical_instead_of_bitwise)
13933+ << RHS.get()->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
13934+ // Suggest replacing the logical operator with the bitwise version
13935+ Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
13936+ << (Opc == BO_LAnd ? "&" : "|")
13937+ << FixItHint::CreateReplacement(
13938+ SourceRange(Loc, getLocForEndOfToken(Loc)),
13939+ Opc == BO_LAnd ? "&" : "|");
13940+ if (Opc == BO_LAnd)
13941+ // Suggest replacing "Foo() && kNonZero" with "Foo()"
13942+ Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
13943+ << FixItHint::CreateRemoval(
13944+ SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
13945+ RHS.get()->getEndLoc()));
13946+ }
13947+ }
1396913948 }
1397013949
1397113950 if (!Context.getLangOpts().CPlusPlus) {
0 commit comments