[PATCH] D142609: [Clang] Fix -Wconstant-logical-operand when LHS is a constant
Shivam Gupta via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 26 02:36:55 PST 2023
xgupta created this revision.
xgupta added reviewers: nickdesaulniers, aaron.ballman.
Herald added a project: All.
xgupta requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This fix PR37919
The below code produces -Wconstant-logical-operand for the first statement,
but not the second.
void foo(int x) {
if (x && 5) {}
if (5 && x) {}
}
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D142609
Files:
clang/lib/Sema/SemaExpr.cpp
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13593,18 +13593,21 @@
Diag(Loc, diag::warn_enum_constant_in_bool_context);
// Diagnose cases where the user write a logical and/or but probably meant a
- // bitwise one. We do this when the LHS is a non-bool integer and the RHS
- // is a constant.
- if (!EnumConstantInBoolContext && LHS.get()->getType()->isIntegerType() &&
- !LHS.get()->getType()->isBooleanType() &&
- RHS.get()->getType()->isIntegerType() && !RHS.get()->isValueDependent() &&
+ // bitwise one. We do this when one of the operand is a non-bool integer and
+ // the other is a constant.
+ if (!EnumConstantInBoolContext &&
+ ((RHS.get()->getType()->isIntegerType() && !RHS.get()->getType()->isBooleanType() &&
+ LHS.get()->getType()->isIntegerType() && !LHS.get()->isValueDependent()) ||
+ ( RHS.get()->getType()->isIntegerType() && !RHS.get()->getType()->isBooleanType() &&
+ LHS.get()->getType()->isIntegerType() && !LHS.get()->isValueDependent())) &&
// Don't warn in macros or template instantiations.
!Loc.isMacroID() && !inTemplateInstantiation()) {
- // If the RHS can be constant folded, and if it constant folds to something
+ // If the operand can be constant folded, and if it constant folds to something
// that isn't 0 or 1 (which indicate a potential logical operation that
// happened to fold to true/false) then warn.
- // Parens on the RHS are ignored.
+ // Parens on the operand are ignored.
Expr::EvalResult EVResult;
+
if (RHS.get()->EvaluateAsInt(EVResult, Context)) {
llvm::APSInt Result = EVResult.Val.getInt();
if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
@@ -13626,6 +13629,28 @@
RHS.get()->getEndLoc()));
}
}
+
+ if (LHS.get()->EvaluateAsInt(EVResult, Context)) {
+ llvm::APSInt Result = EVResult.Val.getInt();
+ if ((getLangOpts().Bool && !LHS.get()->getType()->isBooleanType() &&
+ !LHS.get()->getExprLoc().isMacroID()) ||
+ (Result != 0 && Result != 1)) {
+ Diag(Loc, diag::warn_logical_instead_of_bitwise)
+ << LHS.get()->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
+ // Suggest replacing the logical operator with the bitwise version
+ Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
+ << (Opc == BO_LAnd ? "&" : "|")
+ << FixItHint::CreateReplacement(
+ SourceRange(Loc, getLocForEndOfToken(Loc)),
+ Opc == BO_LAnd ? "&" : "|");
+ if (Opc == BO_LAnd)
+ // Suggest replacing "kNonZero && foo() " with "Foo()"
+ Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
+ << FixItHint::CreateRemoval(
+ SourceRange(getLocForEndOfToken(RHS.get()->getEndLoc()),
+ LHS.get()->getEndLoc()));
+ }
+ }
}
if (!Context.getLangOpts().CPlusPlus) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142609.492364.patch
Type: text/x-patch
Size: 3145 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230126/4c7c8ea9/attachment.bin>
More information about the cfe-commits
mailing list