summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-04-27 07:05:31 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-04-27 07:05:31 +0000
commit53caa4d4fac7f53c1942f55951905e3e2e145524 (patch)
tree3bfabd5286a5fedefda46ce3f2970fdd0474d37c /clang/lib/Sema/SemaChecking.cpp
parent5476666d173861917bab2d35c5402ab4f9bf1672 (diff)
downloadbcm5719-llvm-53caa4d4fac7f53c1942f55951905e3e2e145524.tar.gz
bcm5719-llvm-53caa4d4fac7f53c1942f55951905e3e2e145524.zip
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. llvm-svn: 130299
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9dec2596969..6b219612d14 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/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);
OpenPOWER on IntegriCloud