arphaman created this revision. arphaman added reviewers: rjmccall, manmanren. arphaman added a subscriber: cfe-commits. arphaman set the repository for this revision to rL LLVM.
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. Repository: rL LLVM https://reviews.llvm.org/D25777 Files: lib/Sema/TreeTransform.h test/SemaCXX/designated-initializers.cpp Index: test/SemaCXX/designated-initializers.cpp =================================================================== --- /dev/null +++ test/SemaCXX/designated-initializers.cpp @@ -0,0 +1,31 @@ +// 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}} +} Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -8923,6 +8923,8 @@ Desig.AddDesignator(Designator::getField(D.getFieldName(), D.getDotLoc(), D.getFieldLoc())); + if (D.getField()) + ExprChanged = true; continue; }
Index: test/SemaCXX/designated-initializers.cpp =================================================================== --- /dev/null +++ test/SemaCXX/designated-initializers.cpp @@ -0,0 +1,31 @@ +// 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}} +} Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -8923,6 +8923,8 @@ Desig.AddDesignator(Designator::getField(D.getFieldName(), D.getDotLoc(), D.getFieldLoc())); + if (D.getField()) + ExprChanged = true; continue; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits