When we have a binary expression 'int operator symbol', properly rewrite this as
'symbol operator-reverse int'. This patch is a combination of code from
Zhongxing Xu and myself (Zhongxing noticed this bug for the cases of
relational operators).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56351 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index 89f7c3e..b33d512 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -126,12 +126,13 @@
 RVal GRSimpleVals::DetermEvalBinOpNN(GRStateManager& StateMgr,
                                      BinaryOperator::Opcode Op,
                                      NonLVal L, NonLVal R)  {
-  
+
   BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+  unsigned subkind = L.getSubKind();
   
   while (1) {
     
-    switch (L.getSubKind()) {
+    switch (subkind) {
       default:
         return UnknownVal();
         
@@ -169,18 +170,28 @@
         
         if (isa<nonlval::ConcreteInt>(R)) {          
           const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
-          const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);          
+          const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
           return L_CI.EvalBinOp(BasicVals, Op, R_CI);          
         }
         else {
+          subkind = R.getSubKind();
           NonLVal tmp = R;
           R = L;
           L = tmp;
+          
+          // Swap the operators.
+          switch (Op) {
+            case BinaryOperator::LT: Op = BinaryOperator::GT; break;
+            case BinaryOperator::GT: Op = BinaryOperator::LT; break;
+            case BinaryOperator::LE: Op = BinaryOperator::GE; break;
+            case BinaryOperator::GE: Op = BinaryOperator::LE; break;
+            default: break;
+          }
+          
           continue;
         }
         
-      case nonlval::SymbolValKind: {
-        
+      case nonlval::SymbolValKind:
         if (isa<nonlval::ConcreteInt>(R)) {
           const SymIntConstraint& C =
             BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
@@ -190,7 +201,6 @@
         }
         else
           return UnknownVal();
-      }
     }
   }
 }