Author: Dan Blackwell Date: 2026-11-02T13:53:42-08:00 New Revision: 8a64345b184e89ac59b5064da1d6093eaa6d0523
URL: https://github.com/llvm/llvm-project/commit/8a64345b184e89ac59b5064da1d6093eaa6d0523 DIFF: https://github.com/llvm/llvm-project/commit/8a64345b184e89ac59b5064da1d6093eaa6d0523.diff LOG: [Objective-C][TSan] Do not emit fused ARC calls under TSan at -O0 to detect races on __strong refs (#235150) At -O0, Clang normally emits fused @llvm.objc.storeStrong calls for __strong assignments instead of expanding them into retain, load, store, and release (which it does at -O1 and above). Because TSan does not instrument @llvm.objc.storeStrong, races on __strong references were missed at -O0. This patch makes shouldUseFusedARCCalls() return false when TSan is enabled so that standard TSan load/store instrumentation makes the race detectable. Assisted by LLMs rdar://35283534 Added: clang/test/CodeGenObjC/sanitize-thread-store-strong.m compiler-rt/test/tsan/Darwin/objc-store-strong-race.mm Modified: clang/lib/CodeGen/CodeGenFunction.h Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 4cc0a45067a017..22f72ead623700 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2269,7 +2269,8 @@ class CodeGenFunction : public CodeGenTypeCache { void enableDebugInfo() { DisableDebugInfo = false; } bool shouldUseFusedARCCalls() { - return CGM.getCodeGenOpts().OptimizationLevel == 0; + return CGM.getCodeGenOpts().OptimizationLevel == 0 && + !SanOpts.has(SanitizerKind::Thread); } const LangOptions &getLangOpts() const { return CGM.getLangOpts(); } diff --git a/clang/test/CodeGenObjC/sanitize-thread-store-strong.m b/clang/test/CodeGenObjC/sanitize-thread-store-strong.m new file mode 100644 index 00000000000000..9ee3174645bb61 --- /dev/null +++ b/clang/test/CodeGenObjC/sanitize-thread-store-strong.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple arm64-apple-macosx -O0 -emit-llvm -fobjc-arc -fsanitize=thread -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-macosx -O1 -emit-llvm -fobjc-arc -fsanitize=thread -o - %s | FileCheck %s + +extern id val; + +// CHECK-LABEL: define{{.*}} void @test_store_strong( +// CHECK-NOT: call void @llvm.objc.storeStrong +// CHECK: call void @__tsan_write8(ptr [[DST:%.*]]) +// CHECK-NEXT: store ptr {{.*}}, ptr [[DST]], align 8 +// CHECK-NOT: call void @llvm.objc.storeStrong +// CHECK: ret void +void test_store_strong(__strong id *dst) { + *dst = val; +} diff --git a/compiler-rt/test/tsan/Darwin/objc-store-strong-race.mm b/compiler-rt/test/tsan/Darwin/objc-store-strong-race.mm new file mode 100644 index 00000000000000..9efd3104f0008d --- /dev/null +++ b/compiler-rt/test/tsan/Darwin/objc-store-strong-race.mm @@ -0,0 +1,47 @@ +// RUN: %clangxx_tsan %s -o %t-O0 -O0 -fobjc-arc -framework Foundation +// RUN: %deflake %run %t-O0 2>&1 | FileCheck %s +// RUN: %clangxx_tsan %s -o %t-O2 -O2 -fobjc-arc -framework Foundation +// RUN: %deflake %run %t-O2 2>&1 | FileCheck %s + +#import <Foundation/Foundation.h> + +#import "../test.h" + +@interface MyObj : NSObject { +@public + __strong id strongField; +} +@end + +@implementation MyObj +@end + +int main() { + barrier_init(&barrier, 2); + + MyObj *container = [MyObj new]; + id val1 = [NSObject new]; + id val2 = [NSObject new]; + + dispatch_queue_t q = + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_apply(2, q, ^(size_t i) { + if (i == 0) { + container->strongField = val1; + barrier_wait(&barrier); + } else { + barrier_wait(&barrier); + container->strongField = val2; + } + }); + + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK: WARNING: ThreadSanitizer: data race +// CHECK: Write of size 8 at {{.*}} by {{thread T.*|main thread}}: +// CHECK: #0 {{.*}} objc-store-strong-race.mm:[[@LINE-10]] +// CHECK: Previous write of size 8 at {{.*}} by {{thread T.*|main thread}}: +// CHECK: #0 {{.*}} objc-store-strong-race.mm:[[@LINE-16]] +// CHECK: Done. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
