Clean up empty struct/union recognition.
Make use of getTypeSizeInChars to detect structs/unions of zero size. It allows
more accurate detection of types of zero size. It however has a side effect -
sequence of used types may change, that is why the test 'override-layout' was
modified.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184088 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 92e0042..e62834b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11236,32 +11236,34 @@
// Check if the structure/union declaration is a language extension.
if (!getLangOpts().CPlusPlus) {
bool ZeroSize = true;
- bool UnnamedOnly = true;
- unsigned UnnamedCnt = 0;
+ bool IsEmpty = true;
+ unsigned NonBitFields = 0;
for (RecordDecl::field_iterator I = Record->field_begin(),
- E = Record->field_end(); UnnamedOnly && I != E; ++I) {
+ E = Record->field_end();
+ (NonBitFields == 0 || ZeroSize) && I != E; ++I) {
+ IsEmpty = false;
if (I->isUnnamedBitfield()) {
- UnnamedCnt++;
if (I->getBitWidthValue(Context) > 0)
ZeroSize = false;
} else {
- UnnamedOnly = ZeroSize = false;
+ ++NonBitFields;
+ QualType FieldType = I->getType();
+ if (FieldType->isIncompleteType() ||
+ !Context.getTypeSizeInChars(FieldType).isZero())
+ ZeroSize = false;
}
}
// Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
// C++.
- if (ZeroSize) {
- if (UnnamedCnt == 0)
- Diag(RecLoc, diag::warn_empty_struct_union_compat) << Record->isUnion();
- else
- Diag(RecLoc, diag::warn_zero_size_struct_union_compat) << Record->isUnion();
- }
+ if (ZeroSize)
+ Diag(RecLoc, diag::warn_zero_size_struct_union_compat) << IsEmpty
+ << Record->isUnion() << (NonBitFields > 1);
// Structs without named members are extension in C (C99 6.7.2.1p7), but
// are accepted by GCC.
- if (UnnamedOnly) {
- if (UnnamedCnt == 0)
+ if (NonBitFields == 0) {
+ if (IsEmpty)
Diag(RecLoc, diag::ext_empty_struct_union) << Record->isUnion();
else
Diag(RecLoc, diag::ext_no_named_members_in_struct_union) << Record->isUnion();