Diagnose calling convention attribute incompatibilities. Fixes rdar://8876096.

llvm-svn: 124244
This commit is contained in:
Argyrios Kyrtzidis 2011-01-25 23:16:40 +00:00
parent cd81fe033c
commit 4e52cc7de4
2 changed files with 32 additions and 1 deletions

View File

@ -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);

View File

@ -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}}