зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
d295d78645
Коммит
80639debfb
|
@ -59,7 +59,7 @@ def : DiagGroup<"nested-externs">;
|
||||||
def : DiagGroup<"newline-eof">;
|
def : DiagGroup<"newline-eof">;
|
||||||
def LongLong : DiagGroup<"long-long">;
|
def LongLong : DiagGroup<"long-long">;
|
||||||
def MismatchedTags : DiagGroup<"mismatched-tags">;
|
def MismatchedTags : DiagGroup<"mismatched-tags">;
|
||||||
def : DiagGroup<"missing-field-initializers">;
|
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
|
||||||
def NonNull : DiagGroup<"nonnull">;
|
def NonNull : DiagGroup<"nonnull">;
|
||||||
def : DiagGroup<"nonportable-cfstrings">;
|
def : DiagGroup<"nonportable-cfstrings">;
|
||||||
def : DiagGroup<"non-virtual-dtor">;
|
def : DiagGroup<"non-virtual-dtor">;
|
||||||
|
@ -147,6 +147,7 @@ def Format2 : DiagGroup<"format=2",
|
||||||
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
|
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
|
||||||
|
|
||||||
def Extra : DiagGroup<"extra", [
|
def Extra : DiagGroup<"extra", [
|
||||||
|
MissingFieldInitializers,
|
||||||
SemiBeforeMethodBody,
|
SemiBeforeMethodBody,
|
||||||
SignCompare,
|
SignCompare,
|
||||||
UnusedParameter
|
UnusedParameter
|
||||||
|
|
|
@ -1562,6 +1562,9 @@ def warn_excess_initializers_in_char_array_initializer : ExtWarn<
|
||||||
"excess elements in char array initializer">;
|
"excess elements in char array initializer">;
|
||||||
def warn_initializer_string_for_char_array_too_long : ExtWarn<
|
def warn_initializer_string_for_char_array_too_long : ExtWarn<
|
||||||
"initializer-string for char array is too long">;
|
"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<
|
def warn_braces_around_scalar_init : Warning<
|
||||||
"braces around scalar initializer">;
|
"braces around scalar initializer">;
|
||||||
def err_many_braces_around_scalar_init : Error<
|
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 *RD = DeclType->getAs<RecordType>()->getDecl();
|
||||||
RecordDecl::field_iterator FieldEnd = RD->field_end();
|
RecordDecl::field_iterator FieldEnd = RD->field_end();
|
||||||
bool InitializedSomething = false;
|
bool InitializedSomething = false;
|
||||||
|
bool CheckForMissingFields = true;
|
||||||
while (Index < IList->getNumInits()) {
|
while (Index < IList->getNumInits()) {
|
||||||
Expr *Init = IList->getInit(Index);
|
Expr *Init = IList->getInit(Index);
|
||||||
|
|
||||||
|
@ -1070,6 +1071,10 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
|
||||||
hadError = true;
|
hadError = true;
|
||||||
|
|
||||||
InitializedSomething = true;
|
InitializedSomething = true;
|
||||||
|
|
||||||
|
// Disable check for missing fields when designators are used.
|
||||||
|
// This matches gcc behaviour.
|
||||||
|
CheckForMissingFields = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,6 +1111,21 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
|
||||||
++Field;
|
++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() ||
|
if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() ||
|
||||||
Index >= IList->getNumInits())
|
Index >= IList->getNumInits())
|
||||||
return;
|
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}}
|
||||||
|
};
|
Загрузка…
Ссылка в новой задаче