1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-passes -o - %s | FileCheck %s
2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -disable-llvm-passes -o - %s | FileCheck -check-prefix=NO-METADATA %s
3// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-passes -o - %s -fobjc-arc-exceptions | FileCheck -check-prefix=NO-METADATA %s
4
5// The front-end should emit clang.arc.no_objc_arc_exceptions in -fobjc-arc-exceptions
6// mode when optimization is enabled, and not otherwise.
7
8void thrower(void);
9void not(void) __attribute__((nothrow));
10
11// CHECK-LABEL: define{{.*}} void @test0(
12// CHECK: call void @thrower(), !clang.arc.no_objc_arc_exceptions !
13// CHECK: call void @not() [[NUW:#[0-9]+]], !clang.arc.no_objc_arc_exceptions !
14// NO-METADATA-LABEL: define{{.*}} void @test0(
15// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
16// NO-METADATA: }
17void test0(void) {
18  thrower();
19  not();
20}
21
22// CHECK-LABEL: define{{.*}} void @test1(
23// CHECK: call void @thrower(), !clang.arc.no_objc_arc_exceptions !
24// CHECK: call void @not() [[NUW]], !clang.arc.no_objc_arc_exceptions !
25// NO-METADATA-LABEL: define{{.*}} void @test1(
26// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
27// NO-METADATA: }
28void test1(id x) {
29  id y = x;
30  thrower();
31  not();
32}
33
34void NSLog(id, ...);
35
36// CHECK-LABEL: define{{.*}} void @test2(
37// CHECK: invoke void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*), i32* %{{.*}})
38// CHECK:   to label %{{.*}} unwind label %{{.*}}, !clang.arc.no_objc_arc_exceptions !
39// NO-METADATA-LABEL: define{{.*}} void @test2(
40// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
41// NO-METADATA: }
42void test2(void) {
43    @autoreleasepool {
44        __attribute__((__blocks__(byref))) int x;
45        ^{ (void)x; };
46        NSLog(@"Address of x outside of block: %p", &x);
47    }
48}
49
50// CHECK-LABEL: define{{.*}} void @test3(
51// CHECK: invoke void %{{.*}}(i8* %{{.*}})
52// CHECK:   to label %{{.*}} unwind label %{{.*}}, !clang.arc.no_objc_arc_exceptions !
53// NO-METADATA-LABEL: define{{.*}} void @test3(
54// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
55// NO-METADATA: }
56void test3(void) {
57    @autoreleasepool {
58        __attribute__((__blocks__(byref))) int x;
59        ^{
60            NSLog(@"Address of x in non-assigned block: %p", &x);
61        }();
62    }
63}
64
65// CHECK-LABEL: define{{.*}} void @test4(
66// CHECK: invoke void %{{.*}}(i8* %{{.*}})
67// CHECK:   to label %{{.*}} unwind label %{{.*}}, !clang.arc.no_objc_arc_exceptions !
68// NO-METADATA-LABEL: define{{.*}} void @test4(
69// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
70// NO-METADATA: }
71void test4(void) {
72    @autoreleasepool {
73        __attribute__((__blocks__(byref))) int x;
74        void (^b)(void) = ^{
75            NSLog(@"Address of x in assigned block: %p", &x);
76        };
77        b();
78    }
79}
80
81// CHECK: attributes [[NUW]] = { nounwind }
82