[PATCH] D142609: [Clang] Fix -Wconstant-logical-operand when LHS is a constant

Nick Desaulniers via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 16 10:30:54 PST 2023


nickdesaulniers added a comment.

I did kernel builds of x86_64 and aarch64 defconfigs. This found new instance:
https://github.com/ClangBuiltLinux/linux/issues/1806
which looks like something we can fix in the kernel sources.  Our CI will probably find more instances once this lands, but I'm happy with it.



================
Comment at: clang/lib/Sema/SemaExpr.cpp:13584
+// the other is a constant.
+void Sema::diagnoseLogicalInsteadOfBitwise(ExprResult &Op1, ExprResult &Op2,
                                            SourceLocation Loc,
----------------
Every reference to Op1 and Op2 immediately calls `.get()` on it. That's annoying. How about `Sema::diagnoseLogicalInsteadOfBitwise` accepts `Expr*` (or whatever ExprResult::get returns), and we call `.get()` in the caller?


================
Comment at: clang/lib/Sema/SemaExpr.cpp:13588
+                                           bool EnumConstantInBoolContext) {
+  if (!EnumConstantInBoolContext && Op1.get()->getType()->isIntegerType() &&
+      !Op1.get()->getType()->isBooleanType() &&
----------------
This is the only use of `EnumConstantInBoolContext` in `Sema::diagnoseLogicalInsteadOfBitwise`. It's being used to elide the entirety of the method.  In that case, it seems wasteful to bother to pass it as a parameter.  Instead, I don't think `Sema::diagnoseLogicalInsteadOfBitwise` should be called if `EnumConstantInBoolContext` is `true`.

If you remove the parameter `EnumConstantInBoolContext` then...


================
Comment at: clang/lib/Sema/SemaExpr.cpp:13588
+                                           bool EnumConstantInBoolContext) {
+  if (!EnumConstantInBoolContext && Op1.get()->getType()->isIntegerType() &&
+      !Op1.get()->getType()->isBooleanType() &&
----------------
nickdesaulniers wrote:
> This is the only use of `EnumConstantInBoolContext` in `Sema::diagnoseLogicalInsteadOfBitwise`. It's being used to elide the entirety of the method.  In that case, it seems wasteful to bother to pass it as a parameter.  Instead, I don't think `Sema::diagnoseLogicalInsteadOfBitwise` should be called if `EnumConstantInBoolContext` is `true`.
> 
> If you remove the parameter `EnumConstantInBoolContext` then...
Do you mind pulling the types into dedicated variables, then reusing them? I kind of hate seeing verbose OpX.get()->getType() so much in this method.

Type T1 = Op1.get()->getType();
Type T2 = Op2.get()->getType();

if (T1->isIntegerType() && !T1->isBooleanType() ...
  ...


================
Comment at: clang/lib/Sema/SemaExpr.cpp:13640-13648
+  if (EnumConstantInBoolContext)
+    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.
+  diagnoseLogicalInsteadOfBitwise(LHS, RHS, Loc, Opc,
+                                  EnumConstantInBoolContext);
----------------
...this can become:

```
if (EnumConstantInBoolContext) {
  Diag(...
} else {
  diagnoseLogicalInsteadOfBitwise(...
  diagnoseLogicalInsteadOfBitwise(...
}
```
```
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e61b9252901d..47cfd0884911 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12569,8 +12569,7 @@ public:
       BinaryOperatorKind Opc);
   void diagnoseLogicalInsteadOfBitwise(ExprResult &Op1, ExprResult &Op2,
                                        SourceLocation Loc,
-                                       BinaryOperatorKind Opc,
-                                       bool EnumConstantInBoolContext);
+                                       BinaryOperatorKind Opc);
   QualType CheckLogicalOperands( // C99 6.5.[13,14]
     ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
     BinaryOperatorKind Opc);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 7acf6f41625e..fa64b0cdbe94 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13583,9 +13583,8 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
 // the other is a constant.
 void Sema::diagnoseLogicalInsteadOfBitwise(ExprResult &Op1, ExprResult &Op2,
                                            SourceLocation Loc,
-                                           BinaryOperatorKind Opc,
-                                           bool EnumConstantInBoolContext) {
-  if (!EnumConstantInBoolContext && Op1.get()->getType()->isIntegerType() &&
+                                           BinaryOperatorKind Opc) {
+  if (Op1.get()->getType()->isIntegerType() &&
       !Op1.get()->getType()->isBooleanType() &&
       Op2.get()->getType()->isIntegerType() && !Op2.get()->isValueDependent() &&
       // Don't warn in macros or template instantiations.
@@ -13639,13 +13638,12 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
 
   if (EnumConstantInBoolContext)
     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.
-  diagnoseLogicalInsteadOfBitwise(LHS, RHS, Loc, Opc,
-                                  EnumConstantInBoolContext);
-  diagnoseLogicalInsteadOfBitwise(RHS, LHS, Loc, Opc,
-                                  EnumConstantInBoolContext);
+  else {
+    // Diagnose cases where the user write a logical and/or but probably meant
+    // a bitwise one.
+    diagnoseLogicalInsteadOfBitwise(LHS, RHS, Loc, Opc);
+    diagnoseLogicalInsteadOfBitwise(RHS, LHS, Loc, Opc);
+  }
 
   if (!Context.getLangOpts().CPlusPlus) {
     // OpenCL v1.1 s6.3.g: The logical operators and (&&), or (||) do
```
(That diff probably needs to be reformatted...)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142609/new/

https://reviews.llvm.org/D142609



More information about the cfe-commits mailing list