blob: 5742a44444e3ecea5e48225c72193aba609d7832 [file] [edit]
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -emit-llvm -fexperimental-abi-lowering %s -o - | FileCheck %s
struct Empty {};
struct alignas(16) EmptyAligned {};
extern "C" {
// The empty member's alignment outranks the int's, so it wins the union's
// storage-type comparison and the coercion widens to i64 unless members that
// supply no bytes are skipped.
union OverAligned { EmptyAligned e; int i; };
void take_over_aligned(union OverAligned u);
void call_over_aligned(union OverAligned u) { take_over_aligned(u); }
// CHECK-DAG: declare void @take_over_aligned(i32)
// At equal alignment the comparison falls to size, which an array of empty
// records wins without supplying any bytes.
union ArrOfEmpty { Empty a[2]; char c; };
void take_arr_of_empty(union ArrOfEmpty u);
void call_arr_of_empty(union ArrOfEmpty u) { take_arr_of_empty(u); }
// CHECK-DAG: declare void @take_arr_of_empty(i8)
// The same array spanning a whole eightbyte.
union Arr8OfEmpty { Empty a[8]; char c; };
void take_arr8_of_empty(union Arr8OfEmpty u);
void call_arr8_of_empty(union Arr8OfEmpty u) { take_arr8_of_empty(u); }
// CHECK-DAG: declare void @take_arr8_of_empty(i8)
// Where the other member does fill the eightbyte there is nothing to narrow.
union EmptyAndBytes { Empty e; char c[8]; };
void take_empty_and_bytes(union EmptyAndBytes u);
void call_empty_and_bytes(union EmptyAndBytes u) { take_empty_and_bytes(u); }
// CHECK-DAG: declare void @take_empty_and_bytes(i64)
// Skipping the empty member leaves the remaining member's class intact.
union EmptyAndDouble { Empty e; double d; };
void take_empty_and_double(union EmptyAndDouble u);
void call_empty_and_double(union EmptyAndDouble u) { take_empty_and_double(u); }
// CHECK-DAG: declare void @take_empty_and_double(double)
}