Implement -Wmissing-field-initializers. Patch by mikem!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98275 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2010-03-11 19:32:38 +00:00
Родитель d295d78645
Коммит 80639debfb
4 изменённых файлов: 73 добавлений и 1 удалений

Просмотреть файл

@ -59,7 +59,7 @@ def : DiagGroup<"nested-externs">;
def : DiagGroup<"newline-eof">;
def LongLong : DiagGroup<"long-long">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def : DiagGroup<"missing-field-initializers">;
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
def NonNull : DiagGroup<"nonnull">;
def : DiagGroup<"nonportable-cfstrings">;
def : DiagGroup<"non-virtual-dtor">;
@ -147,6 +147,7 @@ def Format2 : DiagGroup<"format=2",
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
def Extra : DiagGroup<"extra", [
MissingFieldInitializers,
SemiBeforeMethodBody,
SignCompare,
UnusedParameter

Просмотреть файл

@ -1562,6 +1562,9 @@ def warn_excess_initializers_in_char_array_initializer : ExtWarn<
"excess elements in char array initializer">;
def warn_initializer_string_for_char_array_too_long : ExtWarn<
"initializer-string for char array is too long">;
def warn_missing_field_initializers : Warning<
"missing field '%0' initializer">,
InGroup<MissingFieldInitializers>, DefaultIgnore;
def warn_braces_around_scalar_init : Warning<
"braces around scalar initializer">;
def err_many_braces_around_scalar_init : Error<

Просмотреть файл

@ -1051,6 +1051,7 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
RecordDecl::field_iterator FieldEnd = RD->field_end();
bool InitializedSomething = false;
bool CheckForMissingFields = true;
while (Index < IList->getNumInits()) {
Expr *Init = IList->getInit(Index);
@ -1070,6 +1071,10 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
hadError = true;
InitializedSomething = true;
// Disable check for missing fields when designators are used.
// This matches gcc behaviour.
CheckForMissingFields = false;
continue;
}
@ -1106,6 +1111,21 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
++Field;
}
// Emit warnings for missing struct field initializers.
if (CheckForMissingFields && Field != FieldEnd &&
!Field->getType()->isIncompleteArrayType() && !DeclType->isUnionType()) {
// It is possible we have one or more unnamed bitfields remaining.
// Find first (if any) named field and emit warning.
for (RecordDecl::field_iterator it = Field, end = RD->field_end();
it != end; ++it) {
if (!it->isUnnamedBitfield()) {
SemaRef.Diag(IList->getSourceRange().getEnd(),
diag::warn_missing_field_initializers) << it->getName();
break;
}
}
}
if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() ||
Index >= IList->getNumInits())
return;

Просмотреть файл

@ -0,0 +1,48 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-field-initializers %s
struct Foo { int a, b; };
struct Foo foo0 = { 1 }; // expected-warning {{missing field 'b' initializer}}
struct Foo foo1 = { .a = 1 }; // designator avoids MFI warning
struct Foo foo2 = { .b = 1 }; // designator avoids MFI warning
struct Foo bar0[] = {
{ 1,2 },
{ 1 }, // expected-warning {{missing field 'b' initializer}}
{ 1,2 }
};
struct Foo bar1[] = {
1, 2,
1, 2,
1
}; // expected-warning {{missing field 'b' initializer}}
struct One { int a; int b; };
struct Two { float c; float d; float e; };
struct Three {
union {
struct One one;
struct Two two;
} both;
};
struct Three t0 = {
{ .one = { 1, 2 } }
};
struct Three t1 = {
{ .two = { 1.0f, 2.0f, 3.0f } }
};
struct Three data[] = {
{ { .one = { 1, 2 } } },
{ { .one = { 1 } } }, // expected-warning {{missing field 'b' initializer}}
{ { .two = { 1.0f, 2.0f, 3.0f } } },
{ { .two = { 1.0f, 2.0f } } } // expected-warning {{missing field 'e' initializer}}
};
struct { int:5; int a; int:5; int b; int:5 } noNamedImplicit[] = {
{ 1, 2 },
{ 1 } // expected-warning {{missing field 'b' initializer}}
};