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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits