[analyzer] When promoting constant integers in a comparison, use the larger width of the two to avoid truncation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156089 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp
index 1a87ccf..3c9bf3b 100644
--- a/test/Analysis/additive-folding.cpp
+++ b/test/Analysis/additive-folding.cpp
@@ -240,3 +240,31 @@
   if (1 == (local + 1))
     malloc(1); // expected-warning{{never executed}}
 }
+
+void PR12206_truncation(signed char x) {
+  // Build a SymIntExpr, dependent on x.
+  signed char local = x - 1;
+
+  // Constrain the value of x.
+  if (x != 1) return;
+
+  // Constant-folding will turn (local+1) back into the symbol for x.
+  // The point of this dance is to make SValBuilder be responsible for
+  // turning the symbol into a ConcreteInt, rather than ExprEngine.
+
+  // Construct a value that cannot be represented by 'char',
+  // but that has the same lower bits as x.
+  signed int value = 1 + (1 << 8);
+
+  // Test relational operators.
+  if ((local + 1) >= value)
+    malloc(1); // expected-warning{{never executed}}
+  if (value <= (local + 1))
+    malloc(1); // expected-warning{{never executed}}
+
+  // Test equality operators.
+  if ((local + 1) == value) 
+    malloc(1); // expected-warning{{never executed}}
+  if (value == (local + 1))
+    malloc(1); // expected-warning{{never executed}}
+}