Turn error about fastcall variadic function into warning in MS mode (PR12535)
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 llvm-svn: 192240
This commit is contained in:
parent
347c2aa3e3
commit
9112ac2136
|
@ -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">;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue