Files
clang-p2996/clang/test/CodeGenObjC/synchronized.m
John McCall 2dd7d44135 Some more correctness fixes and code-size optimizations for fragile-ABI
ObjC exceptions:
  - don't enter a try for the catch blocks unless there's a finally
  - put the setjmp buffer in the locals set for liveness reasons
  - dump the sync object into an alloca in the locals set for liveness reasons
Some of this can go away if the backend starts to properly calculate liveness
in the presence of setjmp (which would also be a *much* stabler solution).

llvm-svn: 110188
2010-08-04 05:59:32 +00:00

80 lines
1.9 KiB
Objective-C

// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin9 -o - %s -O2 | FileCheck %s
@interface MyClass
{
}
- (void)method;
@end
@implementation MyClass
// CHECK: define internal void @"\01-[MyClass method]"
- (void)method
{
// CHECK: call void @objc_sync_enter
// CHECK: call void @objc_exception_try_enter
// CHECK: call i32 @_setjmp
@synchronized(self) {
}
}
@end
// CHECK: define void @foo(
void foo(id a) {
// CHECK: [[A:%.*]] = alloca i8*
// CHECK: [[SYNC:%.*]] = alloca i8*
// CHECK: store i8* [[AVAL:%.*]], i8** [[A]]
// CHECK-NEXT: call void @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** [[A]], i8** [[SYNC]]
// CHECK: call void @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: [[T:%.*]] = load i8** [[SYNC]]
// CHECK-NEXT: call void @objc_sync_exit
// CHECK: ret void
return;
}
}
// CHECK: define i32 @f0(
int f0(id a) {
// TODO: we can optimize the ret to a constant if we can figure out
// either that x isn't stored to within the synchronized block or
// that the synchronized block can't longjmp.
// CHECK: [[X:%.*]] = alloca i32
// CHECK: store i32 1, i32* [[X]]
int x = 0;
@synchronized((x++, a)) {
}
// CHECK: [[T:%.*]] = load i32* [[X]]
// CHECK: ret i32 [[T]]
return x;
}
// CHECK: 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;
}
}