diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-17 17:22:34 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2012-08-17 17:22:34 +0000 |
commit | bbb8afd7f0bdac635583e07c72a9fcf905aa7c4c (patch) | |
tree | 4fe2e9e053c0a31a5d48a3da651e9fd3dd1dd529 /lib/Sema/SemaCast.cpp | |
parent | d6bbc98fe4690f31904f306c61090404843466fe (diff) |
c: implement gcc's -Wbad-function-cast which warns
on unsafe cast of a c-function call. This is
a C-only option.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162109 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCast.cpp')
-rw-r--r-- | lib/Sema/SemaCast.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index d8d51e77ee..6c513b9669 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -1903,6 +1903,43 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, SrcExpr = ExprError(); } +/// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a +/// non-matching type. Such as enum function call to int, int call to +/// pointer; etc. Cast to 'void' is an exception. +static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, + QualType DestType) { + if (Self.Diags.getDiagnosticLevel(diag::warn_bad_function_cast, + SrcExpr.get()->getExprLoc()) + == DiagnosticsEngine::Ignored) + return; + + if (!isa<CallExpr>(SrcExpr.get())) + return; + + QualType SrcType = SrcExpr.get()->getType(); + if (DestType.getUnqualifiedType()->isVoidType()) + return; + if ((SrcType->isAnyPointerType() || SrcType->isBlockPointerType()) + && (DestType->isAnyPointerType() || DestType->isBlockPointerType())) + return; + if (SrcType->isIntegerType() && DestType->isIntegerType() && + (SrcType->isBooleanType() == DestType->isBooleanType()) && + (SrcType->isEnumeralType() == DestType->isEnumeralType())) + return; + if (SrcType->isRealFloatingType() && DestType->isRealFloatingType()) + return; + if (SrcType->isEnumeralType() && DestType->isEnumeralType()) + return; + if (SrcType->isComplexType() && DestType->isComplexType()) + return; + if (SrcType->isComplexIntegerType() && DestType->isComplexIntegerType()) + return; + + Self.Diag(SrcExpr.get()->getExprLoc(), + diag::warn_bad_function_cast) + << SrcType << DestType << SrcExpr.get()->getSourceRange(); +} + /// Check the semantics of a C-style cast operation, in C. void CastOperation::CheckCStyleCast() { assert(!Self.getLangOpts().CPlusPlus); @@ -2076,7 +2113,7 @@ void CastOperation::CheckCStyleCast() { } } DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType); - + DiagnoseBadFunctionCast(Self, SrcExpr, DestType); Kind = Self.PrepareScalarCast(SrcExpr, DestType); if (SrcExpr.isInvalid()) return; |