has no field declaration.
This commit fixes an invalid Winitializer-overrides warning that's shown
when analyzing a second (or any after the first) instantiation of a designated
initializer. This invalid warning is fixed by making sure that a
DesignatedInitExpr is rebuilt by the tree transformer when it has a field
designator whose FieldDecl* hasn't been yet initialized. This ensures that a
different DesignatedInitExpr is processed by Sema for every instantiation, and
thus the invalid warning is avoided.
rdar://
28768441
Differential Revision: https://reviews.llvm.org/D25777
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284959
91177308-0d34-0410-b5e6-
96231b3b80d8
Desig.AddDesignator(Designator::getField(D.getFieldName(),
D.getDotLoc(),
D.getFieldLoc()));
+ if (D.getField()) {
+ FieldDecl *Field = cast_or_null<FieldDecl>(
+ getDerived().TransformDecl(D.getFieldLoc(), D.getField()));
+ if (Field != D.getField())
+ // Rebuild the expression when the transformed FieldDecl is
+ // different to the already assigned FieldDecl.
+ ExprChanged = true;
+ } else {
+ // Ensure that the designator expression is rebuilt when there isn't
+ // a resolved FieldDecl in the designator as we don't want to assign
+ // a FieldDecl to a pattern designator that will be instantiated again.
+ ExprChanged = true;
+ }
continue;
}
--- /dev/null
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Winitializer-overrides %s
+
+template <typename T> struct Foo {
+ struct SubFoo {
+ int bar1;
+ int bar2;
+ };
+
+ static void Test() { SubFoo sf = {.bar1 = 10, .bar2 = 20}; } // Expected no warning
+};
+
+void foo() {
+ Foo<int>::Test();
+ Foo<bool>::Test();
+ Foo<float>::Test();
+}
+
+template <typename T> struct Bar {
+ struct SubFoo {
+ int bar1;
+ int bar2;
+ };
+
+ static void Test() { SubFoo sf = {.bar1 = 10, // expected-note 2 {{previous initialization is here}}
+ .bar1 = 20}; } // expected-warning 2 {{initializer overrides prior initialization of this subobject}}
+};
+
+void bar() {
+ Bar<int>::Test(); // expected-note {{in instantiation of member function 'Bar<int>::Test' requested here}}
+ Bar<bool>::Test(); // expected-note {{in instantiation of member function 'Bar<bool>::Test' requested here}}
+}