Fix <rdar://problem/6845148>. Signed integers compared against pointers should
implicitly be changed to unsigned values in GRSimpleVals.cpp. This can happen
when the comparison involves logic in specialized transfer functions (e.g.,
OSAtomicCompareAndSwap).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71200 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/misc-ps-64.m b/test/Analysis/misc-ps-64.m
index c95998f..163da4b 100644
--- a/test/Analysis/misc-ps-64.m
+++ b/test/Analysis/misc-ps-64.m
@@ -6,6 +6,7 @@
 // <rdar://problem/6440393> - A bunch of misc. failures involving evaluating
 //  these expressions and building CFGs.  These tests are here to prevent
 //  regressions.
+typedef long long int64_t;
 @class NSString, NSDictionary;
 typedef long NSInteger;
 typedef unsigned long NSUInteger;
@@ -23,3 +24,26 @@
   shazam(x, &bufptr);
 }
 
+// <rdar://problem/6845148> - In this example we got a signedness
+// mismatch between the literal '0' and the value of 'scrooge'.  The
+// trick is to have the evaluator convert the literal to an unsigned
+// integer when doing a comparison with the pointer.  This happens
+// because of the transfer function logic of
+// OSAtomicCompareAndSwap64Barrier, which doesn't have special casts
+// in place to do this for us.
+_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
+extern id objc_lookUpClass(const char *name);
+void rdar_6845148(id debug_yourself) {
+  if (!debug_yourself) {
+    const char *wacky = ((void *)0);  
+    Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);  
+    OSAtomicCompareAndSwap64Barrier(0, (int64_t)scrooge, (int64_t*)&debug_yourself);
+  }
+}
+void rdar_6845148_b(id debug_yourself) {
+  if (!debug_yourself) {
+    const char *wacky = ((void *)0);  
+    Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);  
+    OSAtomicCompareAndSwap64Barrier((int64_t)scrooge, 0, (int64_t*)&debug_yourself);
+  }
+}