From: Alex Lorenz Date: Mon, 24 Oct 2016 09:33:32 +0000 (+0000) Subject: [Sema][TreeTransform] Re-create DesignatedInitExpr when a field designator X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=242de2f28eb87042be1bc365be1f1f51b92d88a5;p=clang [Sema][TreeTransform] Re-create DesignatedInitExpr when a field designator 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 --- diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 6aa1dbbc44..c54e194e83 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -8923,6 +8923,19 @@ TreeTransform::TransformDesignatedInitExpr(DesignatedInitExpr *E) { Desig.AddDesignator(Designator::getField(D.getFieldName(), D.getDotLoc(), D.getFieldLoc())); + if (D.getField()) { + FieldDecl *Field = cast_or_null( + 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; } diff --git a/test/SemaCXX/designated-initializers.cpp b/test/SemaCXX/designated-initializers.cpp new file mode 100644 index 0000000000..e5b5f3c9cc --- /dev/null +++ b/test/SemaCXX/designated-initializers.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Winitializer-overrides %s + +template struct Foo { + struct SubFoo { + int bar1; + int bar2; + }; + + static void Test() { SubFoo sf = {.bar1 = 10, .bar2 = 20}; } // Expected no warning +}; + +void foo() { + Foo::Test(); + Foo::Test(); + Foo::Test(); +} + +template 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::Test(); // expected-note {{in instantiation of member function 'Bar::Test' requested here}} + Bar::Test(); // expected-note {{in instantiation of member function 'Bar::Test' requested here}} +}