diff options
author | Anna Zaks <ganna@apple.com> | 2017-01-13 00:50:50 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2017-01-13 00:50:50 +0000 |
commit | e43b4fc0ae2930d8932cfdeab7c9c44791ec2053 (patch) | |
tree | d85265f78ca4ac792be01bc0f0693d4b75c212d4 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | dcfc19140412e77f443c635c0df87f93ba8677fe (diff) | |
download | bcm5719-llvm-e43b4fc0ae2930d8932cfdeab7c9c44791ec2053.tar.gz bcm5719-llvm-e43b4fc0ae2930d8932cfdeab7c9c44791ec2053.zip |
[tsan] Do not report errors in __destroy_helper_block_
There is a synchronization point between the reference count of a block dropping to zero and it's destruction, which TSan does not observe. Do not report errors in the compiler-emitted block destroy method and everything called from it.
This is similar to https://reviews.llvm.org/D25857
Differential Revision: https://reviews.llvm.org/D28387
llvm-svn: 291868
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 137c69420dd..39c1425842f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -708,6 +708,11 @@ static bool endsWithReturn(const Decl* F) { return false; } +static void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) { + Fn->addFnAttr("sanitize_thread_no_checking_at_run_time"); + Fn->removeFnAttr(llvm::Attribute::SanitizeThread); +} + void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, @@ -751,16 +756,19 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, Fn->addFnAttr(llvm::Attribute::SafeStack); // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize, - // .cxx_destruct and all of their calees at run time. + // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time. if (SanOpts.has(SanitizerKind::Thread)) { if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) { IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0); if (OMD->getMethodFamily() == OMF_dealloc || OMD->getMethodFamily() == OMF_initialize || (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) { - Fn->addFnAttr("sanitize_thread_no_checking_at_run_time"); - Fn->removeFnAttr(llvm::Attribute::SanitizeThread); + markAsIgnoreThreadCheckingAtRuntime(Fn); } + } else if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) { + IdentifierInfo *II = FD->getIdentifier(); + if (II && II->isStr("__destroy_helper_block_")) + markAsIgnoreThreadCheckingAtRuntime(Fn); } } |