diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-05-03 20:37:33 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-05-03 20:37:33 +0000 |
commit | 06bc9eb9908e42696775b395b290827bde468c8b (patch) | |
tree | fe8280c605f7acd9d135df70a54d3a778fd9c6fe /lib/Sema/SemaChecking.cpp | |
parent | bd82a8f7160b4b1ffefd5db29118208e37872fa7 (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.cpp | 80 |
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; + } } } |