Files
clang-p2996/clang/test/CodeGenObjC/synchronized.m
Nikita Popov 656296b1c2 Reapply [CaptureTracking] Do not check domination
Reapply after adjusting the synchronized.m test case, where the
TODO is now resolved. The pointer is only captured on the exception
handling path.

-----

For the CapturesBefore tracker, it is sufficient to check that
I can not reach BeforeHere. This does not necessarily require
that BeforeHere dominates I, it can also occur if the capture
happens on an entirely disjoint path.

This change was previously accepted in D90688, but had to be
reverted due to large compile-time impact in some cases: It
increases the number of reachability queries that are performed.

After recent changes, the compile-time impact is largely mitigated,
so I'm reapplying this patch. The remaining compile-time impact
is largely proportional to changes in code-size.
2021-05-16 15:46:31 +02:00

77 lines
1.8 KiB
Objective-C

// RUN: %clang_cc1 -emit-llvm -triple i686-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -o - %s -O2 | FileCheck %s
@interface MyClass
{
}
- (void)method;
@end
@implementation MyClass
// CHECK: define internal void @"\01-[MyClass method]"
- (void)method
{
// CHECK: call i32 @objc_sync_enter
// CHECK: call void @objc_exception_try_enter
// CHECK: call i32 @_setjmp
@synchronized(self) {
}
}
@end
// CHECK-LABEL: define{{.*}} void @foo(
void foo(id a) {
// CHECK: [[A:%.*]] = alloca i8*
// CHECK: [[SYNC:%.*]] = alloca i8*
// CHECK: store i8* [[AVAL:%.*]], i8** [[A]]
// CHECK-NEXT: call i32 @objc_sync_enter(i8* [[AVAL]])
// CHECK-NEXT: store i8* [[AVAL]], i8** [[SYNC]]
// CHECK-NEXT: call void @objc_exception_try_enter
// CHECK: call i32 @_setjmp
@synchronized(a) {
// This is unreachable, but the optimizers can't know that.
// CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** nonnull [[A]], i8** nonnull [[SYNC]]
// CHECK: call i32 @objc_sync_exit
// CHECK: call i8* @objc_exception_extract
// CHECK: call void @objc_exception_throw
// CHECK: unreachable
// CHECK: call void @objc_exception_try_exit
// CHECK-NEXT: call i32 @objc_sync_exit
// CHECK: ret void
return;
}
}
// CHECK-LABEL: define{{.*}} i32 @f0(
int f0(id a) {
// We can optimize the ret to a constant as we can figure out
// that x isn't stored to within the synchronized block.
// CHECK: [[X:%.*]] = alloca i32
// CHECK: store i32 1, i32* [[X]]
int x = 0;
@synchronized((x++, a)) {
}
// CHECK: ret i32 1
return x;
}
// CHECK-LABEL: define{{.*}} void @f1(
void f1(id a) {
// Check that the return doesn't go through the cleanup.
extern void opaque(void);
opaque();
// CHECK: call void @opaque()
// CHECK-NEXT: ret void
@synchronized(({ return; }), a) {
return;
}
}