From: Argyrios Kyrtzidis Date: Tue, 25 Jan 2011 23:16:40 +0000 (+0000) Subject: Diagnose calling convention attribute incompatibilities. Fixes rdar://8876096. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce95566b36a4ff16e90507633dad8b7a76572999;p=clang Diagnose calling convention attribute incompatibilities. Fixes rdar://8876096. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124244 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 09ebbc085f..2a54bcc3af 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2560,6 +2560,17 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, if (!unwrapped.isFunctionType()) return false; + // Diagnose regparm with fastcall. + const FunctionType *fn = unwrapped.get(); + CallingConv CC = fn->getCallConv(); + if (CC == CC_X86FastCall) { + S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible) + << FunctionType::getNameForCallConv(CC) + << "regparm"; + attr.setInvalid(); + return true; + } + FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withRegParm(value); type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); @@ -2578,7 +2589,8 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, CallingConv CCOld = fn->getCallConv(); if (S.Context.getCanonicalCallConv(CC) == S.Context.getCanonicalCallConv(CCOld)) { - attr.setInvalid(); + FunctionType::ExtInfo EI= unwrapped.get()->getExtInfo().withCallingConv(CC); + type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI)); return true; } @@ -2607,6 +2619,15 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, attr.setInvalid(); return true; } + + // Also diagnose fastcall with regparm. + if (fn->getRegParmType()) { + S.Diag(attr.getLoc(), diag::err_attributes_are_not_compatible) + << "regparm" + << FunctionType::getNameForCallConv(CC); + attr.setInvalid(); + return true; + } } FunctionType::ExtInfo EI = unwrapped.get()->getExtInfo().withCallingConv(CC); diff --git a/test/Sema/stdcall-fastcall.c b/test/Sema/stdcall-fastcall.c index dffcb969a9..4531eb2a81 100644 --- a/test/Sema/stdcall-fastcall.c +++ b/test/Sema/stdcall-fastcall.c @@ -8,3 +8,13 @@ int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies void __attribute__((stdcall, fastcall)) foo3(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'}} + +// rdar://8876096 +void rdar8876096foo1(int i, int j) __attribute__((fastcall, cdecl)); // expected-error {{not compatible}} +void rdar8876096foo2(int i, int j) __attribute__((fastcall, stdcall)); // expected-error {{not compatible}} +void rdar8876096foo3(int i, int j) __attribute__((fastcall, regparm(2))); // expected-error {{not compatible}} +void rdar8876096foo4(int i, int j) __attribute__((stdcall, cdecl)); // expected-error {{not compatible}} +void rdar8876096foo5(int i, int j) __attribute__((stdcall, fastcall)); // expected-error {{not compatible}} +void rdar8876096foo6(int i, int j) __attribute__((cdecl, fastcall)); // expected-error {{not compatible}} +void rdar8876096foo7(int i, int j) __attribute__((cdecl, stdcall)); // expected-error {{not compatible}} +void rdar8876096foo8(int i, int j) __attribute__((regparm(2), fastcall)); // expected-error {{not compatible}}