]> granicus.if.org Git - clang/commitdiff
Diagnose the use of 'fastcall' on functions without prototypes or with
authorJohn McCall <rjmccall@apple.com>
Wed, 4 Nov 2009 03:36:09 +0000 (03:36 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 4 Nov 2009 03:36:09 +0000 (03:36 +0000)
varargs prototypes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86001 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/Sema/callingconv.c
test/Sema/stdcall-fastcall.c

index 9aae77090a5ad1505fb0adcc67377e5979e902f5..99fddb581088a7435c5278f15f1faf7da9b5bb70 100644 (file)
@@ -619,6 +619,10 @@ def warn_attribute_wrong_decl_type : Warning<
 def warn_gnu_inline_attribute_requires_inline : Warning<
   "'gnu_inline' attribute requires function to be marked 'inline',"
   " attribute ignored">;
+def err_cconv_knr : Error<
+  "function with no prototype cannot use '%0' calling convention">;
+def err_cconv_varargs : Error<
+  "variadic function cannot use '%0' calling convention">;
 
 def warn_attribute_ignored_for_field_of_type : Warning<
   "%0 attribute ignored for field of type %1">;
index a3f8eb5a0e7710f0f33aa5bfbb0b61c3be42e056..18f57da76912793ad9a7ad3060f0fb18893f8bb7 100644 (file)
@@ -1032,6 +1032,22 @@ static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   d->addAttr(::new (S.Context) StdCallAttr());
 }
 
+/// Diagnose the use of a non-standard calling convention on the given
+/// function.
+static void DiagnoseCConv(FunctionDecl *D, const char *CConv,
+                          SourceLocation Loc, Sema &S) {
+  if (!D->hasPrototype()) {
+    S.Diag(Loc, diag::err_cconv_knr) << CConv;
+    return;
+  }
+
+  const FunctionProtoType *T = D->getType()->getAs<FunctionProtoType>();
+  if (T->isVariadic()) {
+    S.Diag(Loc, diag::err_cconv_varargs) << CConv;
+    return;
+  }
+}
+
 static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // Attribute has no arguments.
   if (Attr.getNumArgs() != 0) {
@@ -1045,6 +1061,8 @@ static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
+  DiagnoseCConv(cast<FunctionDecl>(d), "fastcall", Attr.getLoc(), S);
+
   // stdcall and fastcall attributes are mutually incompatible.
   if (d->getAttr<StdCallAttr>()) {
     S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
index cb69c59c403a8c6bc480392d9931b9f8420b9e57..102115b3bf2ba111b79bcb50e1ee173b4727df47 100644 (file)
@@ -8,3 +8,12 @@ void __attribute__((stdcall)) bar(float *a) {
 
 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)) test1(void) {
+}
+
+void __attribute__((fastcall)) test2(int a, ...) { // expected-error {{variadic function cannot use 'fastcall' calling convention}}
+}
index 353bbfc252974447312d8b9973ac31b37a64e816..e0db63822fb3a5b9585c411d85533a052ab11bb4 100644 (file)
@@ -5,6 +5,6 @@ int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' attribute only
 int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' attribute only applies to function types}}
 
 // Different CC qualifiers are not compatible
-void __attribute__((stdcall, fastcall)) foo3(); // expected-error{{stdcall and fastcall attributes 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(); // expected-error{{fastcall and stdcall attributes are not compatible}}
+void __attribute__((fastcall)) foo4(void); // expected-error{{fastcall and stdcall attributes are not compatible}}