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.