@@ -13880,56 +13880,6 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
13880
13880
return InvalidOperands(Loc, LHS, RHS);
13881
13881
}
13882
13882
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
-
13933
13883
// C99 6.5.[13,14]
13934
13884
inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
13935
13885
SourceLocation Loc,
@@ -13948,6 +13898,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
13948
13898
}
13949
13899
}
13950
13900
13901
+ if (EnumConstantInBoolContext)
13902
+ Diag(Loc, diag::warn_enum_constant_in_bool_context);
13903
+
13951
13904
// WebAssembly tables can't be used with logical operators.
13952
13905
QualType LHSTy = LHS.get()->getType();
13953
13906
QualType RHSTy = RHS.get()->getType();
@@ -13958,14 +13911,40 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
13958
13911
return InvalidOperands(Loc, LHS, RHS);
13959
13912
}
13960
13913
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
+ }
13969
13948
}
13970
13949
13971
13950
if (!Context.getLangOpts().CPlusPlus) {
0 commit comments