diff options
author | John McCall <rjmccall@apple.com> | 2010-03-11 19:32:38 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-11 19:32:38 +0000 |
commit | 80639debfb2d90b2f1ffdbcd9a391f744cb0a393 (patch) | |
tree | 9de4aa664572ef5d6c92670ba0e55329a7f84249 | |
parent | d295d78645503711d67ce54be2faddf7abdbc4e9 (diff) |
Implement -Wmissing-field-initializers. Patch by mikem!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98275 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticGroups.td | 3 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 20 | ||||
-rw-r--r-- | test/Sema/missing-field-initializers.c | 48 |
4 files changed, 73 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 17bad64e9c..e5793fa58b 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -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 diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 13ac9ece54..1e1c0aa317 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 3540cd02e6..51d2f15376 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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; diff --git a/test/Sema/missing-field-initializers.c b/test/Sema/missing-field-initializers.c new file mode 100644 index 0000000000..0ceded07f2 --- /dev/null +++ b/test/Sema/missing-field-initializers.c @@ -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}} +}; |