// RUN: %clang_cc1 -emit-llvm -triple x86_64 -O3 -o %t.opt.ll %s \
// RUN: -fdump-record-layouts > %t.dump.txt
// RUN: FileCheck -check-prefix=CHECK-RECORD < %t.dump.txt %s
// RUN: FileCheck -check-prefix=CHECK-OPT < %t.opt.ll %s
/****/
// Check that we don't read off the end a packed 24-bit structure.
// PR6176
// CHECK-RECORD: *** Dumping IRgen Record Layout
// CHECK-RECORD: Record: RecordDecl{{.*}}s0
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s0 = type { [3 x i8] }
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:24 IsSigned:1 StorageSize:24 StorageOffset:0
;
struct s0 g0 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i64 @test_0()
// CHECK-OPT: ret i64 1
// CHECK-OPT: }
unsigned long long
/****/
// PR5591
// CHECK-RECORD: *** Dumping IRgen Record Layout
// CHECK-RECORD: Record: RecordDecl{{.*}}s1
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s1 = type { [3 x i8] }
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:10 IsSigned:1 StorageSize:24 StorageOffset:0
// CHECK-RECORD: <CGBitFieldInfo Offset:10 Size:10 IsSigned:1 StorageSize:24 StorageOffset:0
;
struct s1 g1 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i64 @test_1()
// CHECK-OPT: ret i64 210
// CHECK-OPT: }
unsigned long long
/****/
// Check that we don't access beyond the bounds of a union.
//
// PR5567
// CHECK-RECORD: *** Dumping IRgen Record Layout
// CHECK-RECORD: Record: RecordDecl{{.*}}u2
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%union.u2 = type { i8 }
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:3 IsSigned:0 StorageSize:8 StorageOffset:0
;
union u2 g2 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i64 @test_2()
// CHECK-OPT: ret i64 2
// CHECK-OPT: }
unsigned long long
/***/
// PR5039
;
struct s3 g3 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i64 @test_3()
// CHECK-OPT: ret i64 -559039940
// CHECK-OPT: }
unsigned long long
/***/
// This is a case where the bitfield access will straddle an alignment boundary
// of its underlying type.
;
struct s4 g4 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i64 @test_4()
// CHECK-OPT: ret i64 4860
// CHECK-OPT: }
unsigned long long
/***/
;
struct s5 g5 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i64 @test_5()
// CHECK-OPT: ret i64 2
// CHECK-OPT: }
unsigned long long
/***/
;
struct s6 g6 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} zeroext i1 @test_6()
// CHECK-OPT: ret i1 true
// CHECK-OPT: }
_Bool
/***/
// Check that we compute the best alignment possible for each access.
//
// CHECK-RECORD: *** Dumping IRgen Record Layout
// CHECK-RECORD: Record: RecordDecl{{.*}}s7
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s7 = type { i32, i32, i32, i8, i32, [12 x i8] }
// CHECK-RECORD: IsZeroInitializable:1
// CHECK-RECORD: BitFields:[
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:5 IsSigned:1 StorageSize:8 StorageOffset:12
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:29 IsSigned:1 StorageSize:32 StorageOffset:16
;
int
/***/
// This is a case where we narrow the access width immediately.
;
struct s8 g8 = ;
int
int
int
// CHECK-OPT-LABEL: define{{.*}} i32 @test_8()
// CHECK-OPT: ret i32 -3
// CHECK-OPT: }
unsigned
/***/
// This is another case where we narrow the access width immediately.
//
// <rdar://problem/7893760>
;
int