|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|