reimplement __sync_* builtins to be variadic and to follow the same
semantic rules that gcc and icc use.  This implements the variadic
and concrete versions as builtins and has sema do the 
disambiguation.  There are probably a bunch of details to finish up
but this seems like a large monotonic step forward :)


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71212 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c
index d1b3cbb..c224cbd 100644
--- a/test/CodeGen/atomic.c
+++ b/test/CodeGen/atomic.c
@@ -1,15 +1,15 @@
 // RUN: clang-cc %s -emit-llvm -o - > %t1 &&
 // RUN: grep @llvm.atomic.load.add.i32 %t1 | count 3 &&
-// RUN: grep @llvm.atomic.load.sub.i32 %t1 | count 3 &&
+// RUN: grep @llvm.atomic.load.sub.i8 %t1 | count 2 &&
 // RUN: grep @llvm.atomic.load.min.i32 %t1 &&
 // RUN: grep @llvm.atomic.load.max.i32 %t1 &&
 // RUN: grep @llvm.atomic.load.umin.i32 %t1 &&
 // RUN: grep @llvm.atomic.load.umax.i32 %t1 &&
 // RUN: grep @llvm.atomic.swap.i32 %t1 &&
 // RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 3 &&
-// RUN: grep @llvm.atomic.load.and.i32 %t1 | count 3 &&
-// RUN: grep @llvm.atomic.load.or.i32 %t1 | count 3 &&
-// RUN: grep @llvm.atomic.load.xor.i32 %t1 | count 3
+// RUN: grep @llvm.atomic.load.and.i32 %t1 | count 2 &&
+// RUN: grep @llvm.atomic.load.or.i8 %t1  &&
+// RUN: grep @llvm.atomic.load.xor.i8 %t1
 
 
 int atomic(void)
@@ -17,11 +17,12 @@
   // nonsenical test for sync functions
   int old;
   int val = 1;
+  char valc = 1;
   unsigned int uval = 1;
   int cmp = 0;
 
   old = __sync_fetch_and_add(&val, 1);
-  old = __sync_fetch_and_sub(&val, 2);
+  old = __sync_fetch_and_sub(&valc, 2);
   old = __sync_fetch_and_min(&val, 3);
   old = __sync_fetch_and_max(&val, 4);
   old = __sync_fetch_and_umin(&uval, 5u);
@@ -35,9 +36,9 @@
 
   old = __sync_add_and_fetch(&val, 1);
   old = __sync_sub_and_fetch(&val, 2);
-  old = __sync_and_and_fetch(&val, 3);
-  old = __sync_or_and_fetch(&val, 4);
-  old = __sync_xor_and_fetch(&val, 5);
+  old = __sync_and_and_fetch(&valc, 3);
+  old = __sync_or_and_fetch(&valc, 4);
+  old = __sync_xor_and_fetch(&valc, 5);
 
   return old;
 }
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index ce7c348..c6ef5ea 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -24,7 +24,7 @@
 
 
 #define CFSTR __builtin___CFStringMakeConstantString
-void cfstring() {
+void test7() {
   CFSTR("\242");
   CFSTR("\0"); // expected-warning {{ CFString literal contains NUL character }}
   CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible integer to pointer conversion}}
@@ -35,8 +35,18 @@
 typedef __attribute__(( ext_vector_type(16) )) unsigned char uchar16;
 
 // rdar://5905347
-unsigned char foo( short v ) {
+unsigned char test8( short v ) {
   uchar16 c;
   return __builtin_ia32_vec_ext_v4si( c );  // expected-error {{too few arguments to function}}
 }
 
+
+// atomics.
+
+unsigned char test9(short v) {
+  unsigned i, old;
+  
+  old = __sync_fetch_and_add();  // expected-error {{too few arguments to function call}}
+  old = __sync_fetch_and_add(&old);  // expected-error {{too few arguments to function call}}
+  old = __sync_fetch_and_add((int**)0, 42i); // expected-error {{operand of type '_Complex int' cannot be cast to a pointer type}} expected-warning {{imaginary constants are an extension}}
+}