https://github.com/vvd170501 updated https://github.com/llvm/llvm-project/pull/81364
>From f73060f7f09a747c90fa559641abd8c72f4ee66f Mon Sep 17 00:00:00 2001 From: vvd170501 <36827317+vvd170...@users.noreply.github.com> Date: Sat, 10 Feb 2024 19:19:52 +0300 Subject: [PATCH 1/5] Add -Wmissing-designated-field-initializers, decide whether to skip m-f-i check only when needed --- clang/include/clang/Basic/DiagnosticGroups.td | 10 +++- .../clang/Basic/DiagnosticSemaKinds.td | 4 ++ clang/lib/Sema/SemaInit.cpp | 50 ++++++++++--------- .../SemaCXX/cxx2a-initializer-aggregates.cpp | 11 ++-- 4 files changed, 45 insertions(+), 30 deletions(-) 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 91105d4231f06a..8cf58299602ec7 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6167,6 +6167,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< + "missing field %0 initializer">, + 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 0fd458837163e5..3227f16dd0c1ce 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,23 +2356,32 @@ void InitListChecker::CheckStructUnionTypes( } // Emit warnings for missing struct field initializers. - if (!VerifyOnly && InitializedSomething && CheckForMissingFields && - !RD->isUnion()) { - // 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() - : Field, - end = RD->field_end(); - it != end; ++it) { - if (HasDesignatedInit && InitializedFields.count(*it)) - continue; + if (!VerifyOnly && InitializedSomething && !RD->isUnion()) { + // Disable missing fields check for: + // - Zero initializers + // - Designated initializers (only in C). This matches gcc behaviour. + bool DisableCheck = + IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) || + (HasDesignatedInit && !SemaRef.getLangOpts().CPlusPlus); + + if (!DisableCheck) { + // 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() + : Field, + end = RD->field_end(); + it != end; ++it) { + if (HasDesignatedInit && InitializedFields.count(*it)) + continue; - if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() && - !it->getType()->isIncompleteArrayType()) { - SemaRef.Diag(IList->getSourceRange().getEnd(), - diag::warn_missing_field_initializers) - << *it; - break; + if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() && + !it->getType()->isIncompleteArrayType()) { + 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@-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}} } >From 1dc1b14e90faa2d9aaddffa1a250e0631f784f77 Mon Sep 17 00:00:00 2001 From: vvd170501 <36827317+vvd170...@users.noreply.github.com> Date: Tue, 13 Feb 2024 01:11:27 +0300 Subject: [PATCH 2/5] Reuse summary --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8cf58299602ec7..f82cb8dc33914d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6169,7 +6169,7 @@ def warn_missing_field_initializers : Warning< InGroup<MissingFieldInitializers>, DefaultIgnore; // The same warning, but another group is needed to disable it separately. def warn_missing_designated_field_initializers : Warning< - "missing field %0 initializer">, + warn_missing_field_initializers.Summary>, InGroup<MissingDesignatedFieldInitializers>, DefaultIgnore; def warn_braces_around_init : Warning< "braces around %select{scalar |}0initializer">, >From 83864610d6b6470a0f229c516821d8344d994562 Mon Sep 17 00:00:00 2001 From: vvd170501 <36827317+vvd170...@users.noreply.github.com> Date: Tue, 13 Feb 2024 01:11:44 +0300 Subject: [PATCH 3/5] Reduce indentation --- clang/lib/Sema/SemaInit.cpp | 45 +++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 3227f16dd0c1ce..6d5986fccd1133 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2356,32 +2356,27 @@ void InitListChecker::CheckStructUnionTypes( } // Emit warnings for missing struct field initializers. - if (!VerifyOnly && InitializedSomething && !RD->isUnion()) { - // Disable missing fields check for: - // - Zero initializers - // - Designated initializers (only in C). This matches gcc behaviour. - bool DisableCheck = - IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) || - (HasDesignatedInit && !SemaRef.getLangOpts().CPlusPlus); - - if (!DisableCheck) { - // 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() - : Field, - end = RD->field_end(); - it != end; ++it) { - if (HasDesignatedInit && InitializedFields.count(*it)) - continue; + // This check is disabled for designated initializers in C. + // This matches gcc behaviour. + if (!VerifyOnly && InitializedSomething && !RD->isUnion() && + !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) && + !(HasDesignatedInit && !SemaRef.getLangOpts().CPlusPlus)) { + // 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() + : Field, + end = RD->field_end(); + it != end; ++it) { + if (HasDesignatedInit && InitializedFields.count(*it)) + continue; - if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() && - !it->getType()->isIncompleteArrayType()) { - auto Diag = HasDesignatedInit - ? diag::warn_missing_designated_field_initializers - : diag::warn_missing_field_initializers; - SemaRef.Diag(IList->getSourceRange().getEnd(), Diag) << *it; - break; - } + if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() && + !it->getType()->isIncompleteArrayType()) { + auto Diag = HasDesignatedInit + ? diag::warn_missing_designated_field_initializers + : diag::warn_missing_field_initializers; + SemaRef.Diag(IList->getSourceRange().getEnd(), Diag) << *it; + break; } } } >From 61a4489d839f162f8b81c765cbc5993a76881d62 Mon Sep 17 00:00:00 2001 From: vvd170501 <36827317+vvd170...@users.noreply.github.com> Date: Tue, 13 Feb 2024 01:32:08 +0300 Subject: [PATCH 4/5] Update release notes --- clang/docs/ReleaseNotes.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6f6ce7c68a7a71..b6a83328f67338 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -148,6 +148,10 @@ Non-comprehensive list of changes in this release New Compiler Flags ------------------ +- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-designated-field-initializers``. + This diagnostic can be disabled to make ``-Wmissing-designated-field-initializers`` behave + like it did before Clang 18.x. Fixes (`#56628 <https://github.com/llvm/llvm-project/issues/68933>`_) + Deprecated Compiler Flags ------------------------- >From d21b608e672425eb1bab6f1580934214f9d9f2df Mon Sep 17 00:00:00 2001 From: Vadim D <36827317+vvd170...@users.noreply.github.com> Date: Tue, 5 Mar 2024 00:02:49 +0300 Subject: [PATCH 5/5] Fix flag description in release notes Co-authored-by: Aaron Ballman <aa...@aaronballman.com> --- clang/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b6a83328f67338..eb5901ed014590 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -148,7 +148,7 @@ Non-comprehensive list of changes in this release New Compiler Flags ------------------ -- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-designated-field-initializers``. +- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-field-initializers``. This diagnostic can be disabled to make ``-Wmissing-designated-field-initializers`` behave like it did before Clang 18.x. Fixes (`#56628 <https://github.com/llvm/llvm-project/issues/68933>`_) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits