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 | 91f548b04b7d4def318e2037f62828fc77bc6b45 (patch) | |
| tree | bf26f977f16c0fa6888e5077e958aff3ce77f826 /clang/lib | |
| parent | 7ee271360d92e41c4f2122eaadc99f1c10c9e991 (diff) | |
| download | bcm5719-llvm-91f548b04b7d4def318e2037f62828fc77bc6b45.tar.gz bcm5719-llvm-91f548b04b7d4def318e2037f62828fc77bc6b45.zip | |
c: implement gcc's -Wbad-function-cast which warns
on unsafe cast of a c-function call. This is
a C-only option.
llvm-svn: 162109
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index d8d51e77ee2..6c513b9669b 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/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; |

