Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

missing-field-initializers warning not reporting missing designated initializers #56628

Closed
ottojo opened this issue Jul 20, 2022 · 14 comments
Closed
Labels
clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer confirmed Verified by a second party

Comments

@ottojo
Copy link
Member

ottojo commented Jul 20, 2022

In the following code, the missing-field-initializers does not produce a warning that b is not explicitly initialized.

Changing CheckForMissingFields to True here:

// Disable check for missing fields when designators are used.
// This matches gcc behaviour.
CheckForMissingFields = false;

seems to produce the expected warning.

The comment suggests

// Disable check for missing fields when designators are used.
// This matches gcc behaviour.

However, GCC does produce the warning in that case.
Comparison with GCC: https://godbolt.org/z/WeYdY11q3

struct ExampleStruct {
    int a;
    int b;
};

ExampleStruct buildExampleStruct(int a) {
    ExampleStruct e{
            .a=a
    };
    return e;
}

Build flags: -Werror=missing-field-initializers -std=c++20

Expected behavior:

main.cpp:10:5: error: missing field 'b' initializer [-Werror,-Wmissing-field-initializers]

matching GCCs

<source>:9:5: error: missing initializer for member 'ExampleStruct::b' [-Werror=missing-field-initializers]

Actual behavior: Compiles without warning/error.

@EugeneZelenko EugeneZelenko added clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer and removed new issue labels Jul 20, 2022
@dbelousoff
Copy link

Is there any updates/workarounds for this?

@shafik
Copy link
Collaborator

shafik commented May 3, 2023

I don't see a workaround, it looks out of date at this point. Someone needs to remove the CheckForMissingFields = false; but this is a potentially breaking change since there may be folks that using this flag that won't expect the warning to start popping up. Although it should.

@shafik shafik added the confirmed Verified by a second party label May 3, 2023
@ottojo
Copy link
Member Author

ottojo commented May 3, 2023

I see how this would be a breaking change, although i guess if someone enabled Wextra and Wall Werror they would expect some breakage when updating the compiler...

Anyways, i felt like hacking at this a bit and maybe introducing a dedicated switch for this might be an idea? I think the warning is useful, and i would certainly enable it in my projects (although discovery of this flag might be a problem...)
An attempt of an implementation is here, which seems to work in the above test at least 😄 https://github.com/ottojo/llvm-project/pull/2/files

@gracicot
Copy link

I'm actually hit by this issue and I actually missed a bug in my code because I assumed the warning was working on Clang too.

@shafik
Copy link
Collaborator

shafik commented Jun 28, 2023

@AaronBallman sounds like missing this case is not ideal, wdyt about making this change?

@AaronBallman
Copy link
Collaborator

@AaronBallman sounds like missing this case is not ideal, wdyt about making this change?

I'm comfortable with the change. If it turns out to be highly disruptive, we can always put the diagnostic under a new warning flag grouped under -Wmissing-field-initializers so that users can selectively disable this (but hopefully we won't need such a measure).

@Fznamznon
Copy link
Contributor

https://reviews.llvm.org/D157879

razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 2, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 2, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 2, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 3, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 3, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 6, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
razmser pushed a commit to SuduIDE/llvm-project that referenced this issue Oct 11, 2023
Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.

Fixes llvm#56628

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D157879
@jamesruan
Copy link

It is how we understand designated initializers that matters.
IMHO it means we want some fields to be initialized as designated while other fields default initialized. It explicitly leave the 'not designated fields' to be default initialized. Somissing-field-initializers should not report it as warning.

Our project builds failed with this change. We want the diagnostic flag to report for fields we are really forget to init instead of reporting designated initializers that DO means other fields to be default initialized.

The GCC community is still discussing this issue and has not drawn a conclusion yet ( for C++ ).

@shafik
Copy link
Collaborator

shafik commented Oct 12, 2023

So we are hitting dcl.init.aggr p5.2:

Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list ([dcl.init.list]).

and if we try another example w/o designated init: https://godbolt.org/z/Yn48KWvrM

ExampleStruct buildExampleStruct(int a) {
    ExampleStruct e{1};
    return e;
}

We obtain the same diagnostic, so we are being entirely consistent here. I don't see a convincing argument that we should not warn for designated init but we should warn for non-designated aggregate init. The standard does not differentiate these cases.

@AaronBallman
Copy link
Collaborator

IMHO it means we want some fields to be initialized as designated while other fields default initialized. It explicitly leave the 'not designated fields' to be default initialized. Somissing-field-initializers should not report it as warning.

I think that any field initializer not explicitly mentioned is missing (per the usual English sense of the word) and to get your reading of the diagnostic, we'd want it named differently.

Our project builds failed with this change. We want the diagnostic flag to report for fields we are really forget to init instead of reporting designated initializers that DO means other fields to be default initialized.

That said, this could be a reason to add a new group under -Wmissing-field-initializers for this functionality. I'm curious what the GCC folks think on the topic.

@gracicot
Copy link

@jamesruan Also note that with this warning, it's really easy for an implementer to specify when that warning happen.

struct AB {
    int a = {}; // A is an optional struct parameter
    int b;
};

AB test{
    .b = 0 // no warning for a since it has a default value
};

That way this warning only happen when users really make a mistake.

@floooh
Copy link

floooh commented Dec 27, 2023

It looks to me like the missing-field-initializers warning for designated initialization in Clang 18.0.0 is also triggered in C, which definitely looks like a bug (since missing field initializers for designated init in C are a well-defined feature, such items are explicitly initialized to zero, which can be detected and then patched to default values in libraries which are designed with designated init in mind - FWIW, this change breaks all my C code when compiling with -Wall -Wextra -Werror).

The Clang 18 release notes say this:

  • Clang now reports missing-field-initializers warning for missing designated initializers in C++. (#56628)

...but it also happens in C mode.

I'm seeing this issue in the latest Emscripten SDK (3.1.51) which is using Clang 18.0.0.

See code like this to understand why the warning is a serious issue:

https://github.com/floooh/sokol-samples/blob/b3bc55c4411fa03770e2ff4303e1d49f9f36616d/sapp/triangle-sapp.c#L42-L52

The sg_pipeline_desc struct has dozens of members which are checked for zero and patched to sane defaults inside the sg_make_pipeline() call. Having to provide dozens of explicit = 0 statements in the struct initialization would kill all readability, because the important non-default items would disappear in the noise.

@shafik
Copy link
Collaborator

shafik commented Dec 27, 2023

Note there are several discussions in the review: http://108.170.204.19/D157879

notably: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96868

CC @Fznamznon @AaronBallman

@Fznamznon
Copy link
Contributor

@floooh , the issue you're seeing can be a side effect of #70829 which I reverted before holidays season since there was no intention in enabling the warnings in C. Please check with clang built with trunk.

AaronBallman pushed a commit that referenced this issue Mar 5, 2024
#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:
#56628 (comment)

Fixes  #68933
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer confirmed Verified by a second party
Projects
None yet
Development

No branches or pull requests

9 participants