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