================
@@ -1170,82 +1171,117 @@ class CFGBuilder {
     if (!areExprTypesCompatible(NumExpr1, NumExpr2))
       return {};
 
+    // Check that the two expressions are of the same type.
     Expr::EvalResult L1Result, L2Result;
-    if (!NumExpr1->EvaluateAsInt(L1Result, *Context) ||
-        !NumExpr2->EvaluateAsInt(L2Result, *Context))
-      return {};
-
-    llvm::APSInt L1 = L1Result.Val.getInt();
-    llvm::APSInt L2 = L2Result.Val.getInt();
-
-    // Can't compare signed with unsigned or with different bit width.
-    if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth())
+    if (!NumExpr1->EvaluateAsRValue(L1Result, *Context) ||
+        !NumExpr2->EvaluateAsRValue(L2Result, *Context))
       return {};
 
-    // Values that will be used to determine if result of logical
-    // operator is always true/false
-    const llvm::APSInt Values[] = {
-      // Value less than both Value1 and Value2
-      llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()),
-      // L1
-      L1,
-      // Value between Value1 and Value2
-      ((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1),
-                              L1.isUnsigned()),
-      // L2
-      L2,
-      // Value greater than both Value1 and Value2
-      llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()),
-    };
-
-    // Check whether expression is always true/false by evaluating the 
following
+    // Check whether expression is always true/false by evaluating the
+    // following
     // * variable x is less than the smallest literal.
     // * variable x is equal to the smallest literal.
     // * Variable x is between smallest and largest literal.
     // * Variable x is equal to the largest literal.
     // * Variable x is greater than largest literal.
-    bool AlwaysTrue = true, AlwaysFalse = true;
-    // Track value of both subexpressions.  If either side is always
-    // true/false, another warning should have already been emitted.
-    bool LHSAlwaysTrue = true, LHSAlwaysFalse = true;
-    bool RHSAlwaysTrue = true, RHSAlwaysFalse = true;
-    for (const llvm::APSInt &Value : Values) {
-      TryResult Res1, Res2;
-      Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
-      Res2 = analyzeLogicOperatorCondition(BO2, Value, L2);
-
-      if (!Res1.isKnown() || !Res2.isKnown())
-        return {};
+    auto analyzeConditions = [&](const auto &Values,
+                                 const BinaryOperatorKind *BO1,
+                                 const BinaryOperatorKind *BO2) -> TryResult {
+      bool AlwaysTrue = true, AlwaysFalse = true;
+      // Track value of both subexpressions.  If either side is always
+      // true/false, another warning should have already been emitted.
+      bool LHSAlwaysTrue = true, LHSAlwaysFalse = true;
+      bool RHSAlwaysTrue = true, RHSAlwaysFalse = true;
+
+      for (const auto &Value : Values) {
+        TryResult Res1 =
+            analyzeLogicOperatorCondition(*BO1, Value, Values[1] /* L1 */);
+        TryResult Res2 =
+            analyzeLogicOperatorCondition(*BO2, Value, Values[3] /* L2 */);
+
+        if (!Res1.isKnown() || !Res2.isKnown())
+          return {};
+
+        const bool isAnd = B->getOpcode() == BO_LAnd;
+        const bool combine = isAnd ? (Res1.isTrue() && Res2.isTrue())
+                                   : (Res1.isTrue() || Res2.isTrue());
+
+        AlwaysTrue &= combine;
+        AlwaysFalse &= !combine;
+
+        LHSAlwaysTrue &= Res1.isTrue();
+        LHSAlwaysFalse &= Res1.isFalse();
+        RHSAlwaysTrue &= Res2.isTrue();
+        RHSAlwaysFalse &= Res2.isFalse();
+      }
 
-      if (B->getOpcode() == BO_LAnd) {
-        AlwaysTrue &= (Res1.isTrue() && Res2.isTrue());
-        AlwaysFalse &= !(Res1.isTrue() && Res2.isTrue());
-      } else {
-        AlwaysTrue &= (Res1.isTrue() || Res2.isTrue());
-        AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue());
+      if (AlwaysTrue || AlwaysFalse) {
+        if (!LHSAlwaysTrue && !LHSAlwaysFalse && !RHSAlwaysTrue &&
+            !RHSAlwaysFalse && BuildOpts.Observer) {
+          BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
+        }
+        return TryResult(AlwaysTrue);
       }
+      return {};
+    };
 
-      LHSAlwaysTrue &= Res1.isTrue();
-      LHSAlwaysFalse &= Res1.isFalse();
-      RHSAlwaysTrue &= Res2.isTrue();
-      RHSAlwaysFalse &= Res2.isFalse();
+    // Handle integer comparison
----------------
Sirraide wrote:

```suggestion
    // Handle integer comparison.
```
nit: comments should end w/ a full stop (there’s another one below).

https://github.com/llvm/llvm-project/pull/133653
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to