Standardize the parsing of function type attributes in a way that
follows (as conservatively as possible) gcc's current behavior: attributes
written on return types that don't apply there are applied to the function
instead, etc. Only parse CC attributes as type attributes, not as decl attributes;
don't accepet noreturn as a decl attribute on ValueDecls, either (it still
needs to apply to other decls, like blocks). Consistently consume CC/noreturn
information throughout codegen; enforce this by removing their default values
in CodeGenTypes::getFunctionInfo().
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95436 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
index 68bc73d..770ce76 100644
--- a/test/CodeGen/attributes.c
+++ b/test/CodeGen/attributes.c
@@ -74,3 +74,10 @@
void t20(void) {
__builtin_abort();
}
+
+void (__attribute__((fastcall)) *fptr)(int);
+void t21(void) {
+ fptr(10);
+}
+// CHECK: [[FPTRVAR:%[a-z0-9]+]] = load void (i32)** @fptr
+// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 10)
diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c
index 24f90e0..bea6df3 100644
--- a/test/CodeGen/stdcall-fastcall.c
+++ b/test/CodeGen/stdcall-fastcall.c
@@ -24,10 +24,10 @@
// CHECK: call x86_fastcallcc void @f3()
// CHECK: call x86_stdcallcc void @f4()
pf1(); pf2(); pf3(); pf4();
- // CHECK: call x86_fastcallcc void %tmp()
- // CHECK: call x86_stdcallcc void %tmp1()
- // CHECK: call x86_fastcallcc void %tmp2()
- // CHECK: call x86_stdcallcc void %tmp3()
+ // CHECK: call x86_fastcallcc void %{{.*}}()
+ // CHECK: call x86_stdcallcc void %{{.*}}()
+ // CHECK: call x86_fastcallcc void %{{.*}}()
+ // CHECK: call x86_stdcallcc void %{{.*}}()
return 0;
}
diff --git a/test/Sema/attr-noreturn.c b/test/Sema/attr-noreturn.c
index 3f064a0..b17f9fd 100644
--- a/test/Sema/attr-noreturn.c
+++ b/test/Sema/attr-noreturn.c
@@ -11,7 +11,7 @@
// On K&R
int f1() __attribute__((noreturn));
-int g0 __attribute__((noreturn)); // expected-warning {{'noreturn' attribute only applies to function types}}
+int g0 __attribute__((noreturn)); // expected-warning {{'noreturn' only applies to function types; type here is 'int'}}
int f2() __attribute__((noreturn(1, 2))); // expected-error {{attribute requires 0 argument(s)}}
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
index 0337c06..0752606 100644
--- a/test/Sema/callingconv.c
+++ b/test/Sema/callingconv.c
@@ -9,13 +9,13 @@
void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{attribute requires 0 argument(s)}}
}
-void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use 'fastcall' calling convention}}
+void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use fastcall calling convention}}
}
void __attribute__((fastcall)) test1(void) {
}
-void __attribute__((fastcall)) test2(int a, ...) { // expected-error {{variadic function cannot use 'fastcall' calling convention}}
+void __attribute__((fastcall)) test2(int a, ...) { // expected-error {{variadic function cannot use fastcall calling convention}}
}
void __attribute__((cdecl)) ctest0() {}
@@ -33,3 +33,6 @@
void ctest2() {}
void (__attribute__((cdecl)) *pctest2)() = ctest2;
+typedef void (__attribute__((fastcall)) *Handler) (float *);
+Handler H = foo;
+
diff --git a/test/Sema/stdcall-fastcall.c b/test/Sema/stdcall-fastcall.c
index c45f93e..a069526 100644
--- a/test/Sema/stdcall-fastcall.c
+++ b/test/Sema/stdcall-fastcall.c
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// CC qualifier can be applied only to functions
-int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' attribute only applies to function types}}
-int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' attribute only applies to function types}}
+int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' only applies to function types; type here is 'int'}}
+int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies to function types; type here is 'int'}}
// Different CC qualifiers are not compatible
void __attribute__((stdcall, fastcall)) foo3(void); // expected-error{{stdcall and fastcall attributes are not compatible}}
-void __attribute__((stdcall)) foo4();
-void __attribute__((fastcall)) foo4(void); // expected-error{{fastcall and stdcall attributes are not compatible}}
+void __attribute__((stdcall)) foo4(); // expected-note{{previous declaration is here}}
+void __attribute__((fastcall)) foo4(void); // expected-error{{function declared 'fastcall' here was previously declared 'stdcall'}}