diff options
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 152f3f3..a7d59ec2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -19399,9 +19399,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Verify that all the fields are okay. SmallVector<FieldDecl*, 32> RecFields; - + const FieldDecl *PreviousField = nullptr; for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end(); - i != end; ++i) { + i != end; PreviousField = cast<FieldDecl>(*i), ++i) { FieldDecl *FD = cast<FieldDecl>(*i); // Get the type for the field. @@ -19617,6 +19617,29 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (Record && FD->getType().isVolatileQualified()) Record->setHasVolatileMember(true); + bool ReportMSBitfieldStoragePacking = + Record && PreviousField && + !Diags.isIgnored(diag::warn_ms_bitfield_mismatched_storage_packing, + Record->getLocation()); + auto IsNonDependentBitField = [](const FieldDecl *FD) { + return FD->isBitField() && !FD->getType()->isDependentType(); + }; + + if (ReportMSBitfieldStoragePacking && IsNonDependentBitField(FD) && + IsNonDependentBitField(PreviousField)) { + CharUnits FDStorageSize = Context.getTypeSizeInChars(FD->getType()); + CharUnits PreviousFieldStorageSize = + Context.getTypeSizeInChars(PreviousField->getType()); + if (FDStorageSize != PreviousFieldStorageSize) { + Diag(FD->getLocation(), + diag::warn_ms_bitfield_mismatched_storage_packing) + << FD << FD->getType() << FDStorageSize.getQuantity() + << PreviousFieldStorageSize.getQuantity(); + Diag(PreviousField->getLocation(), + diag::note_ms_bitfield_mismatched_storage_size_previous) + << PreviousField << PreviousField->getType(); + } + } // Keep track of the number of named members. if (FD->getIdentifier()) ++NumNamedMembers; |