| // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -std=c++20 \ | |
| // RUN: -emit-llvm -o - %s | FileCheck %s | |
| using u8 = unsigned char; | |
| using u64 = unsigned long long; | |
| struct Padded { | |
| u8 Head{}; | |
| u64 Middle{}; | |
| u8 Tail{}; | |
| u8 First[2]{}; | |
| u8 Second[2]{}; | |
| u8 Third[2]{}; | |
| constexpr bool operator==(const Padded &) const = default; | |
| }; | |
| template <Padded P> int readFirst() { | |
| volatile int I = 0; | |
| return P.First[I]; | |
| } | |
| template <Padded P> int readSecond() { | |
| volatile int I = 0; | |
| return P.Second[I]; | |
| } | |
| constexpr Padded P = [] { | |
| Padded Result{}; | |
| Result.First[0] = 5; | |
| Result.Second[0] = 6; | |
| Result.Third[0] = 7; | |
| return Result; | |
| }(); | |
| int use() { return readFirst<P>() + readSecond<P>(); } | |
| // `First` starts immediately after Head, Middle, and Tail, including the | |
| // padding before Middle: 1 + 7 + 8 + 1 == 17. | |
| // CHECK-LABEL: define {{.*}} @_Z9readFirst | |
| // CHECK: getelementptr {{.*}}(i8, ptr @_ZTAX{{.*}}, i64 17) | |
| // `Second` starts after `First`: 17 + 2 == 19. | |
| // CHECK-LABEL: define {{.*}} @_Z10readSecond | |
| // CHECK: getelementptr {{.*}}(i8, ptr @_ZTAX{{.*}}, i64 19) |