diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-06-16 17:56:04 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-06-16 17:56:04 +0000 |
commit | 18739c343c4350598fc5e5d31cb7ba622cb307f8 (patch) | |
tree | 6614ce12ce43cfa23f7cc37d5280ebf8d8eed29f /clang/lib/Sema/SemaChecking.cpp | |
parent | 7f191b2a3bafe4995e183c43fd3136a6d8e87e1a (diff) | |
download | bcm5719-llvm-18739c343c4350598fc5e5d31cb7ba622cb307f8.tar.gz bcm5719-llvm-18739c343c4350598fc5e5d31cb7ba622cb307f8.zip |
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>.
llvm-svn: 133173
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 81506bf571a..54900e0cf15 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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; |