diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-04-27 07:05:31 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-04-27 07:05:31 +0000 |
commit | 7ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1 (patch) | |
tree | a0ee5fcc77c93f3b704f7c4b821c800af8573118 /lib | |
parent | d46a1125d43bcfd47fbd1206ebd1226863549390 (diff) |
Add a warning (-Wnon-pod-memset) for calls to memset() with
a destination pointer that points to a non-POD type. This can flag such
horrible bugs as overwriting vptrs when a previously POD structure is
suddenly given a virtual method, or creating objects that crash on
practically any use by zero-ing out a member when its changed from
a const char* to a std::string, etc.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130299 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 9dec259696..6b219612d1 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -318,6 +318,10 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { TheCall->getCallee()->getLocStart()); } + // Memset handling + if (FnInfo->isStr("memset")) + CheckMemsetArguments(TheCall); + return false; } @@ -1791,6 +1795,36 @@ void Sema::CheckFormatString(const StringLiteral *FExpr, } } +//===--- CHECK: Standard memory functions ---------------------------------===// + +/// \brief Check for dangerous or invalid arguments to memset(). +/// +/// This issues warnings on known problematic or dangerous or unspecified +/// arguments to the standard 'memset' function call. +/// +/// \param Call The call expression to diagnose. +void Sema::CheckMemsetArguments(const CallExpr *Call) { + assert(Call->getNumArgs() == 3 && "Unexpected number of arguments to memset"); + const Expr *Dest = Call->getArg(0)->IgnoreParenImpCasts(); + + QualType DestTy = Dest->getType(); + if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) { + QualType PointeeTy = DestPtrTy->getPointeeType(); + if (!PointeeTy->isPODType()) { + DiagRuntimeBehavior( + Dest->getExprLoc(), Dest, + PDiag(diag::warn_non_pod_memset) + << PointeeTy << Call->getCallee()->getSourceRange()); + + SourceRange ArgRange = Call->getArg(0)->getSourceRange(); + DiagRuntimeBehavior( + Dest->getExprLoc(), Dest, + PDiag(diag::note_non_pod_memset_silence) + << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)")); + } + } +} + //===--- CHECK: Return Address of Stack Variable --------------------------===// static Expr *EvalVal(Expr *E, llvm::SmallVectorImpl<DeclRefExpr *> &refVars); |