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 }.