Author: rnk Date: Tue Jan 31 13:37:45 2017 New Revision: 293677 URL: http://llvm.org/viewvc/llvm-project?rev=293677&view=rev Log: 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. Modified: cfe/trunk/lib/Sema/SemaCast.cpp cfe/trunk/test/Sema/callingconv-cast.c Modified: cfe/trunk/lib/Sema/SemaCast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=293677&r1=293676&r2=293677&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaCast.cpp (original) +++ cfe/trunk/lib/Sema/SemaCast.cpp Tue Jan 31 13:37:45 2017 @@ -1763,13 +1763,12 @@ static void DiagnoseCallingConvCast(Sema 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 // 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; Modified: cfe/trunk/test/Sema/callingconv-cast.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/callingconv-cast.c?rev=293677&r1=293676&r2=293677&view=diff ============================================================================== --- cfe/trunk/test/Sema/callingconv-cast.c (original) +++ cfe/trunk/test/Sema/callingconv-cast.c Tue Jan 31 13:37:45 2017 @@ -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. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits