Fix __clear_cache on ARM.

Current gcc's produce an error if __clear_cache is anything but

__clear_cache(char *a, char *b);

It looks like we had just implemented a gcc bug that is now fixed.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181784 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 888e529..3dbeb0b 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -15,7 +15,7 @@
 // The format of this database matches clang/Basic/Builtins.def.
 
 // In libgcc
-BUILTIN(__clear_cache, "v.", "")
+BUILTIN(__clear_cache, "vc*c*", "")
 BUILTIN(__builtin_thread_pointer, "v*", "")
 
 // Saturating arithmetic
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index d187678..bd5afb6 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1645,11 +1645,10 @@
 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
                                            const CallExpr *E) {
   if (BuiltinID == ARM::BI__clear_cache) {
+    assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
     const FunctionDecl *FD = E->getDirectCallee();
-    // Oddly people write this call without args on occasion and gcc accepts
-    // it - it's also marked as varargs in the description file.
     SmallVector<Value*, 2> Ops;
-    for (unsigned i = 0; i < E->getNumArgs(); i++)
+    for (unsigned i = 0; i < 2; i++)
       Ops.push_back(EmitScalarExpr(E->getArg(i)));
     llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
     llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
diff --git a/test/CodeGen/arm-clear.c b/test/CodeGen/arm-clear.c
index 51506df..8ef3675 100644
--- a/test/CodeGen/arm-clear.c
+++ b/test/CodeGen/arm-clear.c
@@ -1,21 +1,8 @@
 // REQUIRES: arm-registered-target
 // RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -w -o - %s | FileCheck %s
 
-void clear0(void *ptr) {
-  // CHECK: clear0
-  // CHECK-NOT: load i8**
-  __clear_cache();
-}
-
-void clear1(void *ptr) {
-  // CHECK: clear1
-  // CHECK: load i8**
-  // CHECK-NOT: load i8**
-  __clear_cache(ptr);
-}
-
-void clear2(void *ptr, void *ptr2) {
-  // CHECK: clear2
+void clear(void *ptr, void *ptr2) {
+  // CHECK: clear
   // CHECK: load i8**
   // CHECK: load i8**
   __clear_cache(ptr, ptr2);
diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c
index 7b48af1..b516040 100644
--- a/test/Sema/builtins-arm.c
+++ b/test/Sema/builtins-arm.c
@@ -1,15 +1,15 @@
-// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify -DTEST0 %s
-// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify -DTEST1 %s
+// RUN: %clang_cc1 -triple armv7 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple armv7 -target-abi apcs-gnu \
-// RUN:   -fsyntax-only -verify -DTEST1 %s
+// RUN:   -fsyntax-only -verify %s
 
-#ifdef TEST0
+void f(char *a, char *b) {
+  __clear_cache(); // expected-error {{too few arguments to function call, expected 2, have 0}} // expected-note {{'__clear_cache' is a builtin with type 'void (char *, char *)}}
+  __clear_cache(a); // expected-error {{too few arguments to function call, expected 2, have 1}}
+  __clear_cache(a, b);
+}
+
+void __clear_cache(void*, void*); // expected-error {{conflicting types for '__clear_cache'}}
 void __clear_cache(char*, char*);
-#endif
-
-#ifdef TEST1
-void __clear_cache(void*, void*);
-#endif
 
 #if defined(__ARM_PCS) || defined(__ARM_EABI__)
 // va_list on ARM AAPCS is struct { void* __ap }.