| // RUN: %clang_cc1 -triple x86_64-windows-msvc -ffreestanding -emit-llvm -O0 \ |
| // RUN: -x c++ -o - %s | FileCheck %s |
| |
| int global_i = 0; |
| |
| // Pass and return object with a reference type (pass directly, return indirectly). |
| // CHECK: define dso_local void @"?f1@@YA?AUS1@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S1) align 8 {{.*}}) |
| // CHECK: call void @"?func1@@YA?AUS1@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S1) align 8 {{.*}}, i64 {{.*}}) |
| struct S1 { |
| int& r; |
| }; |
| |
| S1 func1(S1 x); |
| S1 f1() { |
| S1 x{ global_i }; |
| return func1(x); |
| } |
| |
| // Pass and return object with a reference type within an inner struct (pass directly, return indirectly). |
| // CHECK: define dso_local void @"?f2@@YA?AUS2@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S2) align 8 {{.*}}) |
| // CHECK: call void @"?func2@@YA?AUS2@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S2) align 8 {{.*}}, i64 {{.*}}) |
| struct Inner { |
| int& r; |
| }; |
| |
| struct S2 { |
| Inner i; |
| }; |
| |
| S2 func2(S2 x); |
| S2 f2() { |
| S2 x{ { global_i } }; |
| return func2(x); |
| } |
| |
| // Pass and return object with a reference type (pass directly, return indirectly). |
| // CHECK: define dso_local void @"?f3@@YA?AUS3@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S3) align 8 {{.*}}) |
| // CHECK: call void @"?func3@@YA?AUS3@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S3) align 8 {{.*}}, i64 {{.*}}) |
| struct S3 { |
| const int& r; |
| }; |
| |
| S3 func3(S3 x); |
| S3 f3() { |
| S3 x{ global_i }; |
| return func3(x); |
| } |
| |
| // Pass and return object with a reference type within an inner struct (pass directly, return indirectly). |
| // CHECK: define dso_local void @"?f4@@YA?AUS4@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S4) align 8 {{.*}}) |
| // CHECK: call void @"?func4@@YA?AUS4@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S4) align 8 {{.*}}, i64 {{.*}}) |
| struct InnerConst { |
| const int& r; |
| }; |
| |
| struct S4 { |
| InnerConst i; |
| }; |
| |
| S4 func4(S4 x); |
| S4 f4() { |
| S4 x{ { global_i } }; |
| return func4(x); |
| } |
| |
| // Pass and return an object with an explicitly deleted copy assignment operator (pass directly, return indirectly). |
| // CHECK: define dso_local void @"?f5@@YA?AUS5@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S5) align 4 {{.*}}) |
| // CHECK: call void @"?func5@@YA?AUS5@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S5) align 4 {{.*}}, i32 {{.*}}) |
| struct S5 { |
| S5& operator=(const S5&) = delete; |
| int i; |
| }; |
| |
| S5 func5(S5 x); |
| S5 f5() { |
| S5 x{ 1 }; |
| return func5(x); |
| } |
| |
| // Pass and return an object with an explicitly defaulted copy assignment operator that is implicitly deleted (pass directly, return indirectly). |
| // CHECK: define dso_local void @"?f6@@YA?AUS6@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S6) align 8 {{.*}}) |
| // CHECK: call void @"?func6@@YA?AUS6@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S6) align 8 {{.*}}, i64 {{.*}}) |
| struct S6 { |
| S6& operator=(const S6&) = default; |
| int& i; |
| }; |
| |
| S6 func6(S6 x); |
| S6 f6() { |
| S6 x{ global_i }; |
| return func6(x); |
| } |