[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-24 Thread Alex Lorenz via cfe-commits
This revision was automatically updated to reflect the committed changes.
arphaman marked an inline comment as done.
Closed by commit rL284959: [Sema][TreeTransform] Re-create DesignatedInitExpr 
when a field designator (authored by arphaman).

Changed prior to commit:
  https://reviews.llvm.org/D25777?vs=75414&id=75559#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D25777

Files:
  cfe/trunk/lib/Sema/TreeTransform.h
  cfe/trunk/test/SemaCXX/designated-initializers.cpp


Index: cfe/trunk/test/SemaCXX/designated-initializers.cpp
===
--- cfe/trunk/test/SemaCXX/designated-initializers.cpp
+++ cfe/trunk/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}}
+}
Index: cfe/trunk/lib/Sema/TreeTransform.h
===
--- cfe/trunk/lib/Sema/TreeTransform.h
+++ cfe/trunk/lib/Sema/TreeTransform.h
@@ -8923,6 +8923,19 @@
   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;
 }
 


Index: cfe/trunk/test/SemaCXX/designated-initializers.cpp
===
--- cfe/trunk/test/SemaCXX/designated-initializers.cpp
+++ cfe/trunk/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}}
+}
Index: cfe/trunk/lib/Sema/TreeTransform.h
===
--- cfe/trunk/lib/Sema/TreeTransform.h
+++ cfe/trunk/lib/Sema/TreeTransform.h
@@ -8923,6 +8923,19 @@
   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;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/

[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-22 Thread John McCall via cfe-commits
rjmccall added a comment.

Thanks, LGTM with a small tweak.




Comment at: lib/Sema/TreeTransform.h:8928
+FieldDecl *Field = dyn_cast_or_null(
+getDerived().TransformDecl(D.getFieldLoc(), D.getField()));
+if (Field != D.getField())

I'm pretty sure that TransformDecl promises to preserve the decl kind, i.e. 
this can be a cast_or_null.


Repository:
  rL LLVM

https://reviews.llvm.org/D25777



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-21 Thread Alex Lorenz via cfe-commits
arphaman updated this revision to Diff 75414.
arphaman added a comment.

The updated patch addresses John's comment by modifying the 
`DesignatedInitExpr` re-creation logic.


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  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}}
+}
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8923,6 +8923,19 @@
   Desig.AddDesignator(Designator::getField(D.getFieldName(),
D.getDotLoc(),
D.getFieldLoc()));
+  if (D.getField()) {
+FieldDecl *Field = dyn_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;
 }
 


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  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}}
+}
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8923,6 +8923,19 @@
   Desig.AddDesignator(Designator::getField(D.getFieldName(),
D.getDotLoc(),
D.getFieldLoc()));
+  if (D.getField()) {
+FieldDecl *Field = dyn_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;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-21 Thread Alex Lorenz via cfe-commits
arphaman added a comment.

In https://reviews.llvm.org/D25777#575564, @rjmccall wrote:

> The fact that this bug only arises when performing a *second* instantiation 
> suggests that there's a deeper bug here, because template instantiation is 
> not supposed to modify the pattern AST.  In this case, the basic problem is 
> that, when the parser processes a designator, it only has an identifier, not 
> a FieldDecl*, because it doesn't know what type is being initialized yet.  
> SemaInit eventually resolves that identifier to a FieldDecl and needs to 
> record that in the AST; typically the AST is treated as immutable, but in 
> this case, instead of cloning the expression, Sema just modifies the field 
> designator in-place.  That's not completely unreasonable, and it's definitely 
> the most space-efficient solution for non-template code-building; but in 
> template code, it does mean that we have to take care to not present the same 
> unresolved field designator to Sema twice.
>
> Fortunately, this is pretty easy: we just need to need to flag the expression 
> as needing rebuilding when there isn't a resolved field in the field 
> designator.  When there *is* a resolved field, we just need to map it using 
> TransformDecl; the expression then only needs to be rebuilt if that fails or 
> returns a different declaration.


You're right, the point that you made about modifying the pattern AST is 
correct. I will update the patch accordingly.


Repository:
  rL LLVM

https://reviews.llvm.org/D25777



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-20 Thread John McCall via cfe-commits
rjmccall added a comment.

The fact that this bug only arises when performing a *second* instantiation 
suggests that there's a deeper bug here, because template instantiation is not 
supposed to modify the pattern AST.  In this case, the basic problem is that, 
when the parser processes a designator, it only has an identifier, not a 
FieldDecl*, because it doesn't know what type is being initialized yet.  
SemaInit eventually resolves that identifier to a FieldDecl and needs to record 
that in the AST; typically the AST is treated as immutable, but in this case, 
instead of cloning the expression, Sema just modifies the field designator 
in-place.  That's not completely unreasonable, and it's definitely the most 
space-efficient solution for non-template code-building; but in template code, 
it does mean that we have to take care to not present the same unresolved field 
designator to Sema twice.

Fortunately, this is pretty easy: we just need to need to flag the expression 
as needing rebuilding when there isn't a resolved field in the field 
designator.  When there *is* a resolved field, we just need to map it using 
TransformDecl; the expression then only needs to be rebuilt if that fails or 
returns a different declaration.


Repository:
  rL LLVM

https://reviews.llvm.org/D25777



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-20 Thread Alex Lorenz via cfe-commits
arphaman updated this revision to Diff 75279.
arphaman marked an inline comment as done.
arphaman added a comment.

The updated patch adds a comment to the modified code as request by Manman.


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  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}}
+}
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8923,6 +8923,12 @@
   Desig.AddDesignator(Designator::getField(D.getFieldName(),
D.getDotLoc(),
D.getFieldLoc()));
+  if (D.getField())
+// Ensure that the designator expression is rebuilt when a field
+// designator was already assigned to a specific FieldDecl because
+// that FieldDecl may be incorrect in the transformed AST if it refers
+// to a FieldDecl that has been transformed as well.
+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  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}}
+}
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8923,6 +8923,12 @@
   Desig.AddDesignator(Designator::getField(D.getFieldName(),
D.getDotLoc(),
D.getFieldLoc()));
+  if (D.getField())
+// Ensure that the designator expression is rebuilt when a field
+// designator was already assigned to a specific FieldDecl because
+// that FieldDecl may be incorrect in the transformed AST if it refers
+// to a FieldDecl that has been transformed as well.
+ExprChanged = true;
   continue;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-19 Thread Manman Ren via cfe-commits
manmanren added a comment.

It makes sense to rebuild the expression when a field designator stores a 
FieldDecl.

Thanks for working on this!
Manman




Comment at: lib/Sema/TreeTransform.h:8926
D.getFieldLoc()));
+  if (D.getField())
+ExprChanged = true;

Please add comment here on why we need to set ExprChanged to true.


Repository:
  rL LLVM

https://reviews.llvm.org/D25777



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25777: [Sema][TreeTransform] Re-create DesignatedInitExpr when it has a field designator with a valid FieldDecl

2016-10-19 Thread Alex Lorenz via cfe-commits
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  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
   .bar2 = 20}; 
}
  };
  
  void foo() {
Foo::Test();
Foo::Test();
  }

The invalid warning is shown because in the second instantiation of 
`Foo::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::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  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}}
+}
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  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}}
+}
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