@@ -2274,9 +2274,9 @@ static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag) {
2274
2274
}
2275
2275
}
2276
2276
2277
- void ItaniumRecordLayoutBuilder:: CheckFieldPadding (
2278
- uint64_t Offset, uint64_t UnpaddedOffset , uint64_t UnpackedOffset ,
2279
- unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) {
2277
+ static void CheckFieldPadding (const ASTContext &Context, bool IsUnion,
2278
+ uint64_t Offset , uint64_t UnpaddedOffset ,
2279
+ const FieldDecl *D) {
2280
2280
// We let objc ivars without warning, objc interfaces generally are not used
2281
2281
// for padding tricks.
2282
2282
if (isa<ObjCIvarDecl>(D))
@@ -2300,23 +2300,31 @@ void ItaniumRecordLayoutBuilder::CheckFieldPadding(
2300
2300
if (D->getIdentifier ()) {
2301
2301
auto Diagnostic = D->isBitField () ? diag::warn_padded_struct_bitfield
2302
2302
: diag::warn_padded_struct_field;
2303
- Diag (D->getLocation (), Diagnostic)
2303
+ Context.getDiagnostics ().Report (D->getLocation (),
2304
+ Diagnostic)
2304
2305
<< getPaddingDiagFromTagKind (D->getParent ()->getTagKind ())
2305
2306
<< Context.getTypeDeclType (D->getParent ()) << PadSize
2306
2307
<< (InBits ? 1 : 0 ) // (byte|bit)
2307
2308
<< D->getIdentifier ();
2308
2309
} else {
2309
2310
auto Diagnostic = D->isBitField () ? diag::warn_padded_struct_anon_bitfield
2310
2311
: diag::warn_padded_struct_anon_field;
2311
- Diag (D->getLocation (), Diagnostic)
2312
+ Context.getDiagnostics ().Report (D->getLocation (),
2313
+ Diagnostic)
2312
2314
<< getPaddingDiagFromTagKind (D->getParent ()->getTagKind ())
2313
2315
<< Context.getTypeDeclType (D->getParent ()) << PadSize
2314
2316
<< (InBits ? 1 : 0 ); // (byte|bit)
2315
2317
}
2316
- }
2317
- if (isPacked && Offset != UnpackedOffset) {
2318
- HasPackedField = true ;
2319
- }
2318
+ }
2319
+ }
2320
+
2321
+ void ItaniumRecordLayoutBuilder::CheckFieldPadding (
2322
+ uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset,
2323
+ unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) {
2324
+ ::CheckFieldPadding (Context, IsUnion, Offset, UnpaddedOffset, D);
2325
+ if (isPacked && Offset != UnpackedOffset) {
2326
+ HasPackedField = true ;
2327
+ }
2320
2328
}
2321
2329
2322
2330
static const CXXMethodDecl *computeKeyFunction (ASTContext &Context,
@@ -2642,8 +2650,6 @@ struct MicrosoftRecordLayoutBuilder {
2642
2650
// / virtual base classes and their offsets in the record.
2643
2651
ASTRecordLayout::VBaseOffsetsMapTy VBases;
2644
2652
// / The number of remaining bits in our last bitfield allocation.
2645
- // / This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is
2646
- // / true.
2647
2653
unsigned RemainingBitsInField;
2648
2654
bool IsUnion : 1 ;
2649
2655
// / True if the last field laid out was a bitfield and was not 0
@@ -3004,6 +3010,15 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
3004
3010
} else {
3005
3011
FieldOffset = Size.alignTo (Info.Alignment );
3006
3012
}
3013
+
3014
+ uint64_t UnpaddedFielddOffsetInBits =
3015
+ Context.toBits (DataSize) - RemainingBitsInField;
3016
+
3017
+ ::CheckFieldPadding (Context, IsUnion, Context.toBits(FieldOffset),
3018
+ UnpaddedFielddOffsetInBits, FD);
3019
+
3020
+ RemainingBitsInField = 0 ;
3021
+
3007
3022
placeFieldAtOffset (FieldOffset);
3008
3023
3009
3024
if (!IsOverlappingEmptyField)
@@ -3049,10 +3064,14 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) {
3049
3064
} else {
3050
3065
// Allocate a new block of memory and place the bitfield in it.
3051
3066
CharUnits FieldOffset = Size.alignTo (Info.Alignment );
3067
+ uint64_t UnpaddedFieldOffsetInBits =
3068
+ Context.toBits (DataSize) - RemainingBitsInField;
3052
3069
placeFieldAtOffset (FieldOffset);
3053
3070
Size = FieldOffset + Info.Size ;
3054
3071
Alignment = std::max (Alignment, Info.Alignment );
3055
3072
RemainingBitsInField = Context.toBits (Info.Size ) - Width;
3073
+ ::CheckFieldPadding (Context, IsUnion, Context.toBits(FieldOffset),
3074
+ UnpaddedFieldOffsetInBits, FD);
3056
3075
}
3057
3076
DataSize = Size;
3058
3077
}
@@ -3076,9 +3095,14 @@ MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) {
3076
3095
} else {
3077
3096
// Round up the current record size to the field's alignment boundary.
3078
3097
CharUnits FieldOffset = Size.alignTo (Info.Alignment );
3098
+ uint64_t UnpaddedFieldOffsetInBits =
3099
+ Context.toBits (DataSize) - RemainingBitsInField;
3079
3100
placeFieldAtOffset (FieldOffset);
3101
+ RemainingBitsInField = 0 ;
3080
3102
Size = FieldOffset;
3081
3103
Alignment = std::max (Alignment, Info.Alignment );
3104
+ ::CheckFieldPadding (Context, IsUnion, Context.toBits(FieldOffset),
3105
+ UnpaddedFieldOffsetInBits, FD);
3082
3106
}
3083
3107
DataSize = Size;
3084
3108
}
@@ -3203,6 +3227,9 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
3203
3227
}
3204
3228
3205
3229
void MicrosoftRecordLayoutBuilder::finalizeLayout (const RecordDecl *RD) {
3230
+ uint64_t UnpaddedSizeInBits = Context.toBits (DataSize);
3231
+ UnpaddedSizeInBits -= RemainingBitsInField;
3232
+
3206
3233
// Respect required alignment. Note that in 32-bit mode Required alignment
3207
3234
// may be 0 and cause size not to be updated.
3208
3235
DataSize = Size;
@@ -3231,6 +3258,22 @@ void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) {
3231
3258
Size = Context.toCharUnitsFromBits (External.Size );
3232
3259
if (External.Align )
3233
3260
Alignment = Context.toCharUnitsFromBits (External.Align );
3261
+ return ;
3262
+ }
3263
+ unsigned CharBitNum = Context.getTargetInfo ().getCharWidth ();
3264
+ uint64_t SizeInBits = Context.toBits (Size);
3265
+ if (SizeInBits > UnpaddedSizeInBits) {
3266
+ unsigned int PadSize = SizeInBits - UnpaddedSizeInBits;
3267
+ bool InBits = true ;
3268
+ if (PadSize % CharBitNum == 0 ) {
3269
+ PadSize = PadSize / CharBitNum;
3270
+ InBits = false ;
3271
+ }
3272
+
3273
+ Context.getDiagnostics ().Report (RD->getLocation (),
3274
+ diag::warn_padded_struct_size)
3275
+ << Context.getTypeDeclType (RD) << PadSize
3276
+ << (InBits ? 1 : 0 ); // (byte|bit)
3234
3277
}
3235
3278
}
3236
3279
0 commit comments