]> granicus.if.org Git - clang/commitdiff
Turn error about fastcall variadic function into warning in MS mode (PR12535)
authorHans Wennborg <hans@hanshq.net>
Tue, 8 Oct 2013 21:52:56 +0000 (21:52 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 8 Oct 2013 21:52:56 +0000 (21:52 +0000)
MSVC allows this and silently falls back to __cdecl for variadic functions.
This patch turns Clang's error into a warning in MS mode and adds a test
to make sure we generate correct code.

Differential Revision: http://llvm-reviews.chandlerc.com/D1861

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaType.cpp
test/CodeGen/microsoft-call-conv.c
test/Sema/callingconv.c

index 4a77004c9e7333df66023588f3095eaab0603b8a..b30fd3fc7211910de0c593ae5d43df5a854d4afe 100644 (file)
@@ -2053,6 +2053,9 @@ 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_cconv_varargs : Warning<
+  "%0 calling convention ignored on variadic function">,
+  InGroup<IgnoredAttributes>;
 def err_regparm_mismatch : Error<"function declared with regparm(%0) "
   "attribute was previously declared "
   "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
index c327fffc67268ef1b5bc4164b4588f9b5f3923ee..13cb15dca43c31bf3663a61364b89c21306437f2 100644 (file)
@@ -4553,7 +4553,11 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
 
     const FunctionProtoType *FnP = cast<FunctionProtoType>(fn);
     if (FnP->isVariadic()) {
-      S.Diag(attr.getLoc(), diag::err_cconv_varargs)
+      // In MS compatibility mode, this is just a warning.
+      const LangOptions &L = S.getLangOpts();
+      unsigned DiagID = L.MicrosoftMode ? diag::warn_cconv_varargs
+                                        : diag::err_cconv_varargs;
+      S.Diag(attr.getLoc(), DiagID)
         << FunctionType::getNameForCallConv(CC);
       attr.setInvalid();
       return true;
index 1f8bd7318eb8dc2e7411181ed7473b31a75c642d..18074243aa9b352544c9ec99281c17594d6b4c69 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i386-pc-linux -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-linux -emit-llvm -fms-compatibility -DWIN < %s | FileCheck --check-prefix=WIN %s
 
 void __fastcall f1(void);
 void __stdcall f2(void);
@@ -48,3 +49,11 @@ void f8(void) {
   f7(0);
   // CHECK: call x86_stdcallcc void @f7(i32 0)
 }
+
+// PR12535
+#ifdef WIN
+void __fastcall f9(int x, int y) {};
+// WIN: define x86_fastcallcc void @f9({{.*}})
+void __fastcall f10(int x, ...) {};
+// WIN: define void @f10({{.*}})
+#endif
index 5badc14a01ff76c1eead31dc787e6118becbc574..732c6add6ea9f063cb71a85d7091c4a17f4399aa 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -fsyntax-only -triple i386-unknown-unknown -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple i386-unknown-unknown -fms-compatibility -DWIN -verify
 
 void __attribute__((fastcall)) foo(float *a) {
 }
@@ -15,8 +16,13 @@ void __attribute__((fastcall)) test0() { // expected-error {{function with no pr
 void __attribute__((fastcall)) test1(void) {
 }
 
+#ifdef WIN
+void __attribute__((fastcall)) test2(int a, ...) { // expected-warning {{fastcall calling convention ignored on variadic function}}
+}
+#else
 void __attribute__((fastcall)) test2(int a, ...) { // expected-error {{variadic function cannot use fastcall calling convention}}
 }
+#endif
 
 void __attribute__((cdecl)) ctest0() {}