1 // RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -o - \
2 // RUN:   | FileCheck %s --check-prefixes=CHECK,CHECK-NOM
3 // RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -o - \
4 // RUN:   -mfunction-return=keep | FileCheck %s \
5 // RUN:   --check-prefixes=CHECK,CHECK-KEEP
6 // RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -o - \
7 // RUN:  -mfunction-return=thunk-extern | FileCheck %s \
8 // RUN:  --check-prefixes=CHECK,CHECK-EXTERN
9 
10 int foo(void) {
11   // CHECK: @"_ZZ3foovENK3$_0clEv"({{.*}}) [[NOATTR:#[0-9]+]]
12   return []() {
13     return 42;
14   }();
15 }
16 int bar(void) {
17   // CHECK: @"_ZZ3barvENK3$_1clEv"({{.*}}) [[EXTERN:#[0-9]+]]
18   return []() __attribute__((function_return("thunk-extern"))) {
19     return 42;
20   }
21   ();
22 }
23 int baz(void) {
24   // CHECK: @"_ZZ3bazvENK3$_2clEv"({{.*}}) [[KEEP:#[0-9]+]]
25   return []() __attribute__((function_return("keep"))) {
26     return 42;
27   }
28   ();
29 }
30 
31 class Foo {
32 public:
33   // CHECK: @_ZN3Foo3fooEv({{.*}}) [[EXTERN]]
34   __attribute__((function_return("thunk-extern"))) int foo() { return 42; }
35 };
36 
37 int quux() {
38   Foo my_foo;
39   return my_foo.foo();
40 }
41 
42 // CHECK: @extern_c() [[EXTERN]]
43 extern "C" __attribute__((function_return("thunk-extern"))) void extern_c() {}
44 extern "C" {
45 // CHECK: @extern_c2() [[EXTERN]]
46 __attribute__((function_return("thunk-extern"))) void extern_c2() {}
47 }
48 
49 // CHECK-NOM-NOT:   [[NOATTR]] = {{.*}}fn_ret_thunk_extern
50 // CHECK-KEEP-NOT:  [[NOATTR]] = {{.*}}fn_ret_thunk_extern
51 // CHECK-KEEP-NOT:  [[KEEP]] = {{.*}}fn_ret_thunk_extern
52 // CHECK-EXTERN:    [[EXTERN]] = {{.*}}fn_ret_thunk_extern
53