[clang] 7df43cc - [clang] Add -Wmissing-designated-field-initializers (#81364)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 5 08:28:08 PST 2024
Author: Vadim D
Date: 2024-03-05T11:27:58-05:00
New Revision: 7df43ccf08e40468354d0564f9bcd7dfe681590b
URL: https://github.com/llvm/llvm-project/commit/7df43ccf08e40468354d0564f9bcd7dfe681590b
DIFF: https://github.com/llvm/llvm-project/commit/7df43ccf08e40468354d0564f9bcd7dfe681590b.diff
LOG: [clang] Add -Wmissing-designated-field-initializers (#81364)
#56628 changed the behavior of `-Wmissing-field-initializers`, which
introduces many new warnings in C++ code that uses partial designated
initializers. If such code is being built with `-Wextra -Werror`, this
change will break the build.
This PR adds a new flag that allows to disable these new warnings and
keep the old ones, as was suggested by @AaronBallman in the original
issue:
https://github.com/llvm/llvm-project/issues/56628#issuecomment-1761510850
Fixes #68933
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaInit.cpp
clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index de5f339cc7f0ba..5e0352a7eaf6cd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,6 +150,10 @@ Non-comprehensive list of changes in this release
New Compiler Flags
------------------
+- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-field-initializers``.
+ This diagnostic can be disabled to make ``-Wmissing-field-initializers`` behave
+ like it did before Clang 18.x. Fixes (`#56628 <https://github.com/llvm/llvm-project/issues/68933>`_)
+
Deprecated Compiler Flags
-------------------------
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index e8b4139d7893ce..0791a0002319de 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -517,7 +517,15 @@ def MethodSignatures : DiagGroup<"method-signatures">;
def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
-def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def MissingDesignatedFieldInitializers : DiagGroup<"missing-designated-field-initializers">{
+ code Documentation = [{
+Warn about designated initializers with some fields missing (only in C++).
+ }];
+}
+// Default -Wmissing-field-initializers matches gcc behavior,
+// but missing-designated-field-initializers can be turned off to match old clang behavior.
+def MissingFieldInitializers : DiagGroup<"missing-field-initializers",
+ [MissingDesignatedFieldInitializers]>;
def ModuleLock : DiagGroup<"module-lock">;
def ModuleBuild : DiagGroup<"module-build">;
def ModuleImport : DiagGroup<"module-import">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b50a4895e171b5..708b3c7f1ede0a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6170,6 +6170,10 @@ def ext_initializer_string_for_char_array_too_long : ExtWarn<
def warn_missing_field_initializers : Warning<
"missing field %0 initializer">,
InGroup<MissingFieldInitializers>, DefaultIgnore;
+// The same warning, but another group is needed to disable it separately.
+def warn_missing_designated_field_initializers : Warning<
+ warn_missing_field_initializers.Summary>,
+ InGroup<MissingDesignatedFieldInitializers>, DefaultIgnore;
def warn_braces_around_init : Warning<
"braces around %select{scalar |}0initializer">,
InGroup<DiagGroup<"braced-scalar-init">>;
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 93b125382b164f..060fe35ad96808 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2227,8 +2227,6 @@ void InitListChecker::CheckStructUnionTypes(
size_t NumRecordDecls = llvm::count_if(RD->decls(), [&](const Decl *D) {
return isa<FieldDecl>(D) || isa<RecordDecl>(D);
});
- bool CheckForMissingFields =
- !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
bool HasDesignatedInit = false;
llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
@@ -2269,11 +2267,6 @@ void InitListChecker::CheckStructUnionTypes(
}
InitializedSomething = true;
-
- // Disable check for missing fields when designators are used.
- // This matches gcc behaviour.
- if (!SemaRef.getLangOpts().CPlusPlus)
- CheckForMissingFields = false;
continue;
}
@@ -2285,7 +2278,7 @@ void InitListChecker::CheckStructUnionTypes(
// These are okay for randomized structures. [C99 6.7.8p19]
//
// Also, if there is only one element in the structure, we allow something
- // like this, because it's really not randomized in the tranditional sense.
+ // like this, because it's really not randomized in the traditional sense.
//
// struct foo h = {bar};
auto IsZeroInitializer = [&](const Expr *I) {
@@ -2363,8 +2356,13 @@ void InitListChecker::CheckStructUnionTypes(
}
// Emit warnings for missing struct field initializers.
- if (!VerifyOnly && InitializedSomething && CheckForMissingFields &&
- !RD->isUnion()) {
+ // This check is disabled for designated initializers in C.
+ // This matches gcc behaviour.
+ bool IsCDesignatedInitializer =
+ HasDesignatedInit && !SemaRef.getLangOpts().CPlusPlus;
+ if (!VerifyOnly && InitializedSomething && !RD->isUnion() &&
+ !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) &&
+ !IsCDesignatedInitializer) {
// 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 = HasDesignatedInit ? RD->field_begin()
@@ -2376,9 +2374,10 @@ void InitListChecker::CheckStructUnionTypes(
if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() &&
!it->getType()->isIncompleteArrayType()) {
- SemaRef.Diag(IList->getSourceRange().getEnd(),
- diag::warn_missing_field_initializers)
- << *it;
+ auto Diag = HasDesignatedInit
+ ? diag::warn_missing_designated_field_initializers
+ : diag::warn_missing_field_initializers;
+ SemaRef.Diag(IList->getSourceRange().getEnd(), Diag) << *it;
break;
}
}
diff --git a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
index 510ace58c35a6a..1e9c5fa082d077 100644
--- a/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
+++ b/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp
@@ -4,7 +4,8 @@
// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,reorder -Wno-c99-designator -Werror=reorder-init-list -Wno-initializer-overrides
// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,override -Wno-c99-designator -Wno-reorder-init-list -Werror=initializer-overrides
// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
-// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing -Wmissing-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
+// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing,wmissing-designated -Wmissing-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
+// RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing -Wmissing-field-initializers -Wno-missing-designated-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
namespace class_with_ctor {
@@ -50,11 +51,11 @@ A a3 = {
A a4 = {
.x = 1, // override-note {{previous}}
.x = 1 // override-error {{overrides prior initialization}}
-}; // wmissing-warning {{missing field 'y' initializer}}
+}; // wmissing-designated-warning {{missing field 'y' initializer}}
A a5 = {
.y = 1, // override-note {{previous}}
.y = 1 // override-error {{overrides prior initialization}}
-}; // wmissing-warning {{missing field 'x' initializer}}
+}; // wmissing-designated-warning {{missing field 'x' initializer}}
B b2 = {.a = 1}; // pedantic-error {{brace elision for designated initializer is a C99 extension}}
// wmissing-warning at -1 {{missing field 'y' initializer}}
B b3 = {.a = 1, 2}; // pedantic-error {{mixture of designated and non-designated}} pedantic-note {{first non-designated}} pedantic-error {{brace elision}}
@@ -74,8 +75,8 @@ C c = {
struct Foo { int a, b; };
struct Foo foo0 = { 1 }; // wmissing-warning {{missing field 'b' initializer}}
-struct Foo foo1 = { .a = 1 }; // wmissing-warning {{missing field 'b' initializer}}
-struct Foo foo2 = { .b = 1 }; // wmissing-warning {{missing field 'a' initializer}}
+struct Foo foo1 = { .a = 1 }; // wmissing-designated-warning {{missing field 'b' initializer}}
+struct Foo foo2 = { .b = 1 }; // wmissing-designated-warning {{missing field 'a' initializer}}
}
More information about the cfe-commits
mailing list