diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-08 17:13:11 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-08 17:13:11 +0000 |
| commit | 0a5fb09b599c1bdea3cd11168bb8f4ff4040316e (patch) | |
| tree | 5e94367d1a8032322c6871cfe16714c0982fd61a /test/CodeGen/aarch64-args.cpp | |
| parent | f0c0337bbfb63d1f9edf145aab535bdf82c20454 (diff) | |
Notes
Diffstat (limited to 'test/CodeGen/aarch64-args.cpp')
| -rw-r--r-- | test/CodeGen/aarch64-args.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/test/CodeGen/aarch64-args.cpp b/test/CodeGen/aarch64-args.cpp new file mode 100644 index 000000000000..409773627261 --- /dev/null +++ b/test/CodeGen/aarch64-args.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefix=CHECK-GNU-C +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-GNU-CXX + +// Empty structs are ignored for PCS purposes on Darwin and in C mode elsewhere. +// In C++ mode on ELF they consume a register slot though. Functions are +// slightly bigger than minimal to make confirmation against actual GCC +// behaviour easier. + +#if __cplusplus +#define EXTERNC extern "C" +#else +#define EXTERNC +#endif + +struct Empty {}; + +// CHECK: define i32 @empty_arg(i32 %a) +// CHECK-GNU-C: define i32 @empty_arg(i32 %a) +// CHECK-GNU-CXX: define i32 @empty_arg(i8 %e.coerce, i32 %a) +EXTERNC int empty_arg(struct Empty e, int a) { + return a; +} + +// CHECK: define void @empty_ret() +// CHECK-GNU-C: define void @empty_ret() +// CHECK-GNU-CXX: define void @empty_ret() +EXTERNC struct Empty empty_ret() { + struct Empty e; + return e; +} + +// However, what counts as "empty" is a baroque mess. This is super-empty, it's +// ignored even in C++ mode. It also has sizeof == 0, violating C++, but that's +// legacy for you: + +struct SuperEmpty { + int arr[0]; +}; + +// CHECK: define i32 @super_empty_arg(i32 %a) +// CHECK-GNU-C: define i32 @super_empty_arg(i32 %a) +// CHECK-GNU-CXX: define i32 @super_empty_arg(i32 %a) +EXTERNC int super_empty_arg(struct SuperEmpty e, int a) { + return a; +} + +// This is not empty. It has 0 size but consumes a register slot for GCC. + +struct SortOfEmpty { + struct SuperEmpty e; +}; + +// CHECK: define i32 @sort_of_empty_arg(i32 %a) +// CHECK-GNU-C: define i32 @sort_of_empty_arg(i32 %a) +// CHECK-GNU-CXX: define i32 @sort_of_empty_arg(i8 %e.coerce, i32 %a) +EXTERNC int sort_of_empty_arg(struct Empty e, int a) { + return a; +} + +// CHECK: define void @sort_of_empty_ret() +// CHECK-GNU-C: define void @sort_of_empty_ret() +// CHECK-GNU-CXX: define void @sort_of_empty_ret() +EXTERNC struct SortOfEmpty sort_of_empty_ret() { + struct SortOfEmpty e; + return e; +} |
