Skip to content

Commit cf8be1b

Browse files
committed
Consider "_BitInt(5) : 6" to be oversized; add tests for bit-fields
1 parent b98b2e6 commit cf8be1b

File tree

3 files changed

+118
-4
lines changed

3 files changed

+118
-4
lines changed

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,9 +2433,17 @@ DiagnosticBuilder ItaniumRecordLayoutBuilder::Diag(SourceLocation Loc,
24332433
/// This function does not check if the type is POD first
24342434
static bool isItaniumPOD(const ASTContext &Context, const CXXRecordDecl *RD) {
24352435
const auto IsDisqualifying = [&](const FieldDecl *FD) -> bool {
2436-
if (FD->isBitField())
2437-
if (FD->getBitWidthValue(Context) > Context.getTypeSize(FD->getType()))
2436+
if (FD->isBitField()) {
2437+
QualType DeclaredType = FD->getType();
2438+
unsigned DeclaredWidth;
2439+
if (const BitIntType *BIT = DeclaredType->getAs<BitIntType>())
2440+
DeclaredWidth = BIT->getNumBits();
2441+
else
2442+
DeclaredWidth = Context.getTypeSize(FD->getType());
2443+
2444+
if (FD->getBitWidthValue(Context) > DeclaredWidth)
24382445
return true;
2446+
}
24392447

24402448
return FD->isPotentiallyOverlapping();
24412449
};
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// RUN: %clang_cc1 -DOLD_ABI=false -std=c++17 -fsyntax-only -triple %itanium_abi_triple -fdump-record-layouts -Wno-bitfield-width %s | FileCheck %s --check-prefixes=CHECK,NEW
2+
// RUN: %clang_cc1 -fclang-abi-compat=19.0 -DOLD_ABI=true -std=c++17 -fsyntax-only -triple %itanium_abi_triple -fdump-record-layouts -Wno-bitfield-width %s | FileCheck %s --check-prefixes=CHECK,OLD
3+
4+
using i4 = __INT32_TYPE__;
5+
using i1 = __INT8_TYPE__;
6+
7+
struct OversizedBase {
8+
i4 i : 33;
9+
};
10+
11+
static_assert(sizeof(OversizedBase) == 8);
12+
// CHECK:*** Dumping AST Record Layout
13+
// CHECK: 0 | struct OversizedBase
14+
// CHECK-NEXT: 0:0-32 | i4 i
15+
16+
// NEW-NEXT: | [sizeof=8, dsize=5, align=4,
17+
// NEW-NEXT: | nvsize=5, nvalign=4]
18+
19+
// OLD-NEXT: | [sizeof=8, dsize=8, align=4,
20+
// OLD-NEXT: | nvsize=8, nvalign=4]
21+
22+
struct X : OversizedBase {
23+
i1 in_padding;
24+
};
25+
static_assert(sizeof(X) == (OLD_ABI ? 12 : 8));
26+
// CHECK:*** Dumping AST Record Layout
27+
// CHECK: 0 | struct X
28+
// CHECK-NEXT: 0 | struct OversizedBase (base)
29+
// CHECK-NEXT: 0:0-32 | i4 i
30+
31+
// NEW-NEXT: 5 | i1 in_padding
32+
// NEW-NEXT: | [sizeof=8, dsize=6, align=4,
33+
// NEW-NEXT: | nvsize=6, nvalign=4]
34+
35+
// OLD-NEXT: 8 | i1 in_padding
36+
// OLD-NEXT: | [sizeof=12, dsize=9, align=4,
37+
// OLD-NEXT: | nvsize=9, nvalign=4]
38+
39+
struct Y : OversizedBase {
40+
i1 in_padding[3];
41+
};
42+
43+
static_assert(sizeof(Y) == (OLD_ABI ? 12 : 8));
44+
// CHECK:*** Dumping AST Record Layout
45+
// CHECK: 0 | struct Y
46+
// CHECK-NEXT: 0 | struct OversizedBase (base)
47+
// CHECK-NEXT: 0:0-32 | i4 i
48+
49+
// NEW-NEXT: 5 | i1[3] in_padding
50+
// NEW-NEXT: | [sizeof=8, dsize=8, align=4,
51+
// NEW-NEXT: | nvsize=8, nvalign=4]
52+
53+
// OLD-NEXT: 8 | i1[3] in_padding
54+
// OLD-NEXT: | [sizeof=12, dsize=11, align=4,
55+
// OLD-NEXT: | nvsize=11, nvalign=4]
56+
57+
struct Z : OversizedBase {
58+
i1 in_padding[4];
59+
};
60+
61+
static_assert(sizeof(Z) == 12);
62+
// CHECK:*** Dumping AST Record Layout
63+
// CHECK: 0 | struct Z
64+
// CHECK-NEXT: 0 | struct OversizedBase (base)
65+
// CHECK-NEXT: 0:0-32 | i4 i
66+
67+
// NEW-NEXT: 5 | i1[4] in_padding
68+
// NEW-NEXT: | [sizeof=12, dsize=9, align=4,
69+
// NEW-NEXT: | nvsize=9, nvalign=4]
70+
71+
// OLD-NEXT: 8 | i1[4] in_padding
72+
// OLD-NEXT: | [sizeof=12, dsize=12, align=4,
73+
// OLD-NEXT: | nvsize=12, nvalign=4]
74+
75+
namespace BitInt {
76+
struct alignas(4) OversizedBase {
77+
_BitInt(9) i : 10;
78+
};
79+
static_assert(sizeof(OversizedBase) == 4);
80+
// CHECK:*** Dumping AST Record Layout
81+
// CHECK: 0 | struct BitInt::OversizedBase
82+
// CHECK-NEXT: 0:0-9 | _BitInt(9) i
83+
84+
// NEW-NEXT: | [sizeof=4, dsize=2, align=4,
85+
// NEW-NEXT: | nvsize=2, nvalign=4]
86+
87+
// OLD-NEXT: | [sizeof=4, dsize=4, align=4,
88+
// OLD-NEXT: | nvsize=4, nvalign=4]
89+
90+
struct X : OversizedBase {
91+
i1 in_padding;
92+
};
93+
static_assert(sizeof(X) == (OLD_ABI ? 8 : 4));
94+
// CHECK:*** Dumping AST Record Layout
95+
// CHECK: 0 | struct BitInt::X
96+
// CHECK-NEXT: 0 | struct BitInt::OversizedBase (base)
97+
// CHECK-NEXT: 0:0-9 | _BitInt(9) i
98+
99+
// NEW-NEXT: 2 | i1 in_padding
100+
// NEW-NEXT: | [sizeof=4, dsize=3, align=4,
101+
// NEW-NEXT: | nvsize=3, nvalign=4]
102+
103+
// OLD-NEXT: 4 | i1 in_padding
104+
// OLD-NEXT: | [sizeof=8, dsize=5, align=4,
105+
// OLD-NEXT: | nvsize=5, nvalign=4]
106+
}

clang/test/Layout/no-unique-address.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s --check-prefix=NEW --check-prefix=CHECK
2-
// RUN: %clang_cc1 -fclang-abi-compat=19.0 -DOLD_ABI=1 -std=c++2a -fsyntax-only -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s --check-prefix=OLD --check-prefix=CHECK
1+
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s --check-prefixes=CHECK,NEW
2+
// RUN: %clang_cc1 -fclang-abi-compat=19.0 -std=c++20 -fsyntax-only -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s --check-prefixes=CHECK,OLD
33

44
namespace Empty {
55
struct A {};

0 commit comments

Comments
 (0)