summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaType.cpp6
-rw-r--r--clang/test/CodeGen/microsoft-call-conv.c9
-rw-r--r--clang/test/Sema/callingconv.c6
4 files changed, 23 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4a77004c9e7..b30fd3fc721 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index c327fffc672..13cb15dca43 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -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;
diff --git a/clang/test/CodeGen/microsoft-call-conv.c b/clang/test/CodeGen/microsoft-call-conv.c
index 1f8bd7318eb..18074243aa9 100644
--- a/clang/test/CodeGen/microsoft-call-conv.c
+++ b/clang/test/CodeGen/microsoft-call-conv.c
@@ -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
diff --git a/clang/test/Sema/callingconv.c b/clang/test/Sema/callingconv.c
index 5badc14a01f..732c6add6ea 100644
--- a/clang/test/Sema/callingconv.c
+++ b/clang/test/Sema/callingconv.c
@@ -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() {}
OpenPOWER on IntegriCloud