From cb642b91363660df0d2ac5d466ffe0a13e10aa66 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Mon, 24 Oct 2016 09:33:32 +0000 Subject: [PATCH] [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 llvm-svn: 284959 --- clang/lib/Sema/TreeTransform.h | 13 +++++++++++ clang/test/SemaCXX/designated-initializers.cpp | 31 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 clang/test/SemaCXX/designated-initializers.cpp diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6aa1dbb..c54e194 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/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/clang/test/SemaCXX/designated-initializers.cpp b/clang/test/SemaCXX/designated-initializers.cpp new file mode 100644 index 0000000..e5b5f3c --- /dev/null +++ b/clang/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}} +} -- 2.7.4