aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-05-03 20:37:33 +0000
committerDouglas Gregor <dgregor@apple.com>2011-05-03 20:37:33 +0000
commit06bc9eb9908e42696775b395b290827bde468c8b (patch)
treefe8280c605f7acd9d135df70a54d3a778fd9c6fe /lib/Sema/SemaChecking.cpp
parentbd82a8f7160b4b1ffefd5db29118208e37872fa7 (diff)
Extend -Wnon-pod-memset to also encompass memcpy() and memmove(),
checking both the source and the destination operands, renaming the warning group to -Wnon-pod-memaccess and tweaking the diagnostic text in the process. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130786 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp80
1 files changed, 44 insertions, 36 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 76f20ce530..10645fd23e 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -318,11 +318,13 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
TheCall->getCallee()->getLocStart());
}
- // Memset handling
- if (FnInfo->isStr("memset") &&
- FDecl->getLinkage() == ExternalLinkage &&
- (!getLangOptions().CPlusPlus || FDecl->isExternC()))
- CheckMemsetArguments(TheCall);
+ // Memset/memcpy/memmove handling
+ if (FDecl->getLinkage() == ExternalLinkage &&
+ (!getLangOptions().CPlusPlus || FDecl->isExternC())) {
+ if (FnInfo->isStr("memset") || FnInfo->isStr("memcpy") ||
+ FnInfo->isStr("memmove"))
+ CheckMemsetcpymoveArguments(TheCall, FnInfo);
+ }
return false;
}
@@ -1813,45 +1815,51 @@ static bool isDynamicClassType(QualType T) {
/// \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.
+/// arguments to the standard 'memset', 'memcpy', and 'memmove' function calls.
///
/// \param Call The call expression to diagnose.
-void Sema::CheckMemsetArguments(const CallExpr *Call) {
+void Sema::CheckMemsetcpymoveArguments(const CallExpr *Call,
+ const IdentifierInfo *FnName) {
// It is possible to have a non-standard definition of memset. Validate
// we have the proper number of arguments, and if not, abort further
// checking.
if (Call->getNumArgs() != 3)
return;
- const Expr *Dest = Call->getArg(0)->IgnoreParenImpCasts();
-
- QualType DestTy = Dest->getType();
- if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) {
- QualType PointeeTy = DestPtrTy->getPointeeType();
- if (PointeeTy->isVoidType())
- return;
-
- unsigned DiagID = 0;
- // Always complain about dynamic classes.
- if (isDynamicClassType(PointeeTy))
- DiagID = diag::warn_dyn_class_memset;
- // Check the C++11 POD definition regardless of language mode; it is more
- // relaxed than earlier definitions and we don't want spurious warnings.
- else if (!PointeeTy->isCXX11PODType())
- DiagID = diag::warn_non_pod_memset;
- else
- return;
-
- DiagRuntimeBehavior(
- Dest->getExprLoc(), Dest,
- PDiag(DiagID)
- << 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*)"));
+ unsigned LastArg = FnName->isStr("memset")? 1 : 2;
+ for (unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
+ const Expr *Dest = Call->getArg(ArgIdx)->IgnoreParenImpCasts();
+
+ QualType DestTy = Dest->getType();
+ if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) {
+ QualType PointeeTy = DestPtrTy->getPointeeType();
+ if (PointeeTy->isVoidType())
+ continue;
+
+ unsigned DiagID = 0;
+ // Always complain about dynamic classes.
+ if (isDynamicClassType(PointeeTy))
+ DiagID = diag::warn_dyn_class_memaccess;
+ // Check the C++11 POD definition regardless of language mode; it is more
+ // relaxed than earlier definitions and we don't want spurious warnings.
+ else if (!PointeeTy->isCXX11PODType())
+ DiagID = diag::warn_non_pod_memaccess;
+ else
+ continue;
+
+ DiagRuntimeBehavior(
+ Dest->getExprLoc(), Dest,
+ PDiag(DiagID)
+ << ArgIdx << FnName << PointeeTy
+ << Call->getCallee()->getSourceRange());
+
+ SourceRange ArgRange = Call->getArg(0)->getSourceRange();
+ DiagRuntimeBehavior(
+ Dest->getExprLoc(), Dest,
+ PDiag(diag::note_non_pod_memaccess_silence)
+ << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)"));
+ break;
+ }
}
}