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