aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorOliver Hunt <oliver@apple.com>2025-05-13 14:00:20 -0700
committerGitHub <noreply@github.com>2025-05-13 14:00:20 -0700
commit8a05c20c963db27db0c93b422dab061a0d53a91f (patch)
tree98712f74b9ee6f8bd283d151c9dfc74f6624d2e2 /clang/lib/Sema/SemaDecl.cpp
parent22fac63bde4a4a1cdae2ab2500d66dd3a6ce5a59 (diff)
downloadllvm-8a05c20c963db27db0c93b422dab061a0d53a91f.zip
llvm-8a05c20c963db27db0c93b422dab061a0d53a91f.tar.gz
llvm-8a05c20c963db27db0c93b422dab061a0d53a91f.tar.bz2
Add an off-by-default warning to complain about MSVC bitfield padding (#117428)
This just adds a warning for bitfields placed next to other bitfields where the underlying type has different storage. Under the MS struct bitfield packing ABI such bitfields are not packed.
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp27
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;