On 6/9/20 8:41 AM, Eric Botcazou wrote:
Yes, but the problem is that remap_decl isn't getting called.
Right, I can get it to be called by adding a pushdecl to grokdeclarator...
Attaching it to the BIND_EXPR doesn't help walk_tree_1 do the right
thing with the DECL_EXPR.
... but, indeed, this still ICEs. So the key is that the DECL_EXPR_DECL of
the copied DECL_EXPR points to the remapped TYPE_DECL before the type is
copied? If so, then your original patch is probably the way to go, but the
comment would need to be slightly adjusted.
Like this?
In Ada, where we attach the TYPE_DECL to the BIND_EXPR, this will mean that
remap_decl is invoked 3 times per TYPE_DECL: first twice from copy_bind_expr
and then once again for the DECL_EXPR. But probably no big deal in the end.
Yes, we want to remap every occurrence of the decl so they all get replaced.
Jason
commit 7b7c1b07dc32cb3cb6dc9b97d516a7240c825cf9
Author: Jason Merrill <ja...@redhat.com>
Date: Fri Jun 5 16:36:27 2020 -0400
tree-inline: Fix VLA handling [PR95552]
The problem in this testcase comes from cloning the constructor into
complete and base variants. When we clone the body the first time,
walk_tree_1 calls copy_tree_body_r on the type of the artificial TYPE_DECL
we made for the VLA type without calling it on the decl itself, so we
overwrite the type of the TYPE_DECL without copying the decl first.
This has been broken since we started inserting a TYPE_DECL for anonymous
VLAs in r7-457.
This patch fixes walk_tree_1 to call the function on the TYPE_DECL, as we do
for other decls of a DECL_EXPR.
gcc/ChangeLog:
PR c++/95552
* tree.c (walk_tree_1): Call func on the TYPE_DECL of a DECL_EXPR.
gcc/testsuite/ChangeLog:
PR c++/95552
* g++.dg/ext/vla23.C: New test.
diff --git a/gcc/testsuite/g++.dg/ext/vla23.C b/gcc/testsuite/g++.dg/ext/vla23.C
new file mode 100644
index 00000000000..317a824b2f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vla23.C
@@ -0,0 +1,14 @@
+// PR c++/95552
+// Test for VLA and cloned constructor.
+// { dg-additional-options -Wno-vla }
+// { dg-require-effective-target alloca }
+
+struct VB { };
+struct ViewDom: virtual VB
+{
+ ViewDom(int i) { char (*a)[i]; }
+};
+void element( )
+{
+ ViewDom a(2);
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 7197b4720ce..805f669a945 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -12212,6 +12212,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
Note that DECLs get walked as part of processing the BIND_EXPR. */
if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
{
+ /* Call the function for the decl so e.g. copy_tree_body_r can
+ replace it with the remapped one. */
+ result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
+ if (result || !walk_subtrees)
+ return result;
+
tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
if (TREE_CODE (*type_p) == ERROR_MARK)
return NULL_TREE;