aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-06-16 17:56:04 +0000
committerDouglas Gregor <dgregor@apple.com>2011-06-16 17:56:04 +0000
commit707a23e8b87410332b55bb4534fa1c799edef38a (patch)
tree456b272b77e0288d0e3618beaf9463959e53e62c /lib/Sema/SemaChecking.cpp
parentb1f7d2496a2916cfad17633e403151dd09118821 (diff)
Teach the warning about non-POD memset/memcpy/memmove to deal with the
__builtin_ versions of these functions as well as the normal function versions, so that it works on platforms where memset/memcpy/memmove are macros that map down to the builtins (e.g., Darwin). Fixes <rdar://problem/9372688>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133173 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp52
1 files changed, 40 insertions, 12 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 81506bf571..54900e0cf1 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -320,12 +320,41 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *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);
+ int CMF = -1;
+ switch (FDecl->getBuiltinID()) {
+ case Builtin::BI__builtin_memset:
+ case Builtin::BI__builtin___memset_chk:
+ case Builtin::BImemset:
+ CMF = CMF_Memset;
+ break;
+
+ case Builtin::BI__builtin_memcpy:
+ case Builtin::BI__builtin___memcpy_chk:
+ case Builtin::BImemcpy:
+ CMF = CMF_Memcpy;
+ break;
+
+ case Builtin::BI__builtin_memmove:
+ case Builtin::BI__builtin___memmove_chk:
+ case Builtin::BImemmove:
+ CMF = CMF_Memmove;
+ break;
+
+ default:
+ if (FDecl->getLinkage() == ExternalLinkage &&
+ (!getLangOptions().CPlusPlus || FDecl->isExternC())) {
+ if (FnInfo->isStr("memset"))
+ CMF = CMF_Memset;
+ else if (FnInfo->isStr("memcpy"))
+ CMF = CMF_Memcpy;
+ else if (FnInfo->isStr("memmove"))
+ CMF = CMF_Memmove;
+ }
+ break;
}
+
+ if (CMF != -1)
+ CheckMemsetcpymoveArguments(TheCall, CheckedMemoryFunction(CMF), FnInfo);
return false;
}
@@ -1856,14 +1885,14 @@ static QualType getSizeOfArgType(const Expr* E) {
///
/// \param Call The call expression to diagnose.
void Sema::CheckMemsetcpymoveArguments(const CallExpr *Call,
- const IdentifierInfo *FnName) {
+ CheckedMemoryFunction CMF,
+ 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)
+ // we have enough arguments, and if not, abort further checking.
+ if (Call->getNumArgs() < 3)
return;
- unsigned LastArg = FnName->isStr("memset")? 1 : 2;
+ unsigned LastArg = (CMF == CMF_Memset? 1 : 2);
const Expr *LenExpr = Call->getArg(2)->IgnoreParenImpCasts();
// We have special checking when the length is a sizeof expression.
@@ -1934,8 +1963,7 @@ void Sema::CheckMemsetcpymoveArguments(const CallExpr *Call,
// Always complain about dynamic classes.
if (isDynamicClassType(PointeeTy))
DiagID = diag::warn_dyn_class_memaccess;
- else if (PointeeTy.hasNonTrivialObjCLifetime() &&
- !FnName->isStr("memset"))
+ else if (PointeeTy.hasNonTrivialObjCLifetime() && CMF != CMF_Memset)
DiagID = diag::warn_arc_object_memaccess;
else
continue;