This patch fixes an invalid Winitializer-overrides warning that's shown for a piece of code like this:
template <typename T> struct Foo {
struct SubFoo {
int bar1;
int bar2;
};
static void Test() {
SubFoo sf = {.bar1 = 10,
// Incorrect "initializer overrides prior initialization" warning shown on the line below when instantiating Foo<bool>
.bar2 = 20};
}
};
void foo() {
Foo<int>::Test();
Foo<bool>::Test();
}The invalid warning is shown because in the second instantiation of Foo<T>::Test the DesignatedInitExpr that corresponds to the initializer for sf has a field designator with a pointer to the FieldDecl from the first instantiation of Foo<T>::SubFoo, which is incorrect in the context of the second instantiation. This means that InitListChecker::CheckDesignatedInitializer isn't able to find the correct FieldIndex for the correct field in the initialized record, leading to an incorrect warning.
This patch fixes this bug by ensuring that a DesignatedInitExpr is re-created by the tree-transformer when it has a field designator with a FieldDecl that has been already been set. This means that in the example above the DesignatedInitExpr won't be re-created by the tree-transformer in the first instantiation, but it will be re-created in the second instantiation, thus ensuring that the second instantiation doesn't have the incorrect FieldDecl pointers.