forked from OSchip/llvm-project
Extend -Wcast-calling-convention to warn on declarations as well as definitions
My original warning was very conservative and I never revisited the heuristics that were used. This would have caught http://crbug.com/687251 at compile time. llvm-svn: 293677
This commit is contained in:
parent
bd99882cf2
commit
0b009e8269
|
@ -1763,13 +1763,12 @@ static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr,
|
|||
if (!DRE)
|
||||
return;
|
||||
auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
|
||||
const FunctionDecl *Definition;
|
||||
if (!FD || !FD->hasBody(Definition))
|
||||
if (!FD)
|
||||
return;
|
||||
|
||||
// Only warn if we are casting from the default convention to a non-default
|
||||
// convention. This can happen when the programmer forgot to apply the calling
|
||||
// convention to the function definition and then inserted this cast to
|
||||
// convention to the function declaration and then inserted this cast to
|
||||
// satisfy the type system.
|
||||
CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(
|
||||
FD->isVariadic(), FD->isCXXInstanceMember());
|
||||
|
@ -1792,7 +1791,7 @@ static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr,
|
|||
// whose address was taken. Try to use the latest macro for the convention.
|
||||
// For example, users probably want to write "WINAPI" instead of "__stdcall"
|
||||
// to match the Windows header declarations.
|
||||
SourceLocation NameLoc = Definition->getNameInfo().getLoc();
|
||||
SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
|
||||
Preprocessor &PP = Self.getPreprocessor();
|
||||
SmallVector<TokenValue, 6> AttrTokens;
|
||||
SmallString<64> CCAttrText;
|
||||
|
|
|
@ -15,6 +15,13 @@ void mismatched_before_winapi(int x) {}
|
|||
// expected-note@+1 3 {{consider defining 'mismatched' with the 'stdcall' calling convention}}
|
||||
void mismatched(int x) {}
|
||||
|
||||
// expected-note@+1 {{consider defining 'mismatched_declaration' with the 'stdcall' calling convention}}
|
||||
void mismatched_declaration(int x);
|
||||
|
||||
// expected-note@+1 {{consider defining 'suggest_fix_first_redecl' with the 'stdcall' calling convention}}
|
||||
void suggest_fix_first_redecl(int x);
|
||||
void suggest_fix_first_redecl(int x);
|
||||
|
||||
typedef void (WINAPI *callback_t)(int);
|
||||
void take_callback(callback_t callback);
|
||||
|
||||
|
@ -46,6 +53,12 @@ int main() {
|
|||
// Another way to suppress the warning.
|
||||
take_callback((callback_t)(void*)mismatched);
|
||||
|
||||
// Warn on declarations as well as definitions.
|
||||
// expected-warning@+1 {{cast between incompatible calling conventions 'cdecl' and 'stdcall'}}
|
||||
take_callback((callback_t)mismatched_declaration);
|
||||
// expected-warning@+1 {{cast between incompatible calling conventions 'cdecl' and 'stdcall'}}
|
||||
take_callback((callback_t)suggest_fix_first_redecl);
|
||||
|
||||
// Don't warn, because we're casting from stdcall to cdecl. Usually that means
|
||||
// the programmer is rinsing the function pointer through some kind of opaque
|
||||
// API.
|
||||
|
|
Loading…
Reference in New Issue