On 6/8/20 4:19 PM, Jason Merrill wrote:
On 6/8/20 5:46 AM, Eric Botcazou wrote:
The only case handled specially is TYPE_DECL; other DECL_EXPRs fall
through to the default case, where we WALK_SUBTREE over all the operands
of the expression, which for DECL_EXPR is the decl.

It seems hard to believe that the inliner relies on this to copy DECLs though,

I agree!  I imagine the actual inliner is unaffected because that happens in GIMPLE now, so this only affects FE cloning.  I don't know if any other front ends use a walk_tree callback like copy_tree_body_r that would replace a type in the same way.

see the calls to remap_decl[s].

Which ones?

And note that remap_decl has had a special
handling for DECL_ORIGINAL_TYPE of TYPE_DECLs since 2003.
Yes, but the problem is that remap_decl isn't getting called.

Are you sure the
problem is not that the TYPE_DECL is not attached to the enclosing BIND_EXPR?

Attaching it to the BIND_EXPR doesn't help walk_tree_1 do the right thing with the DECL_EXPR.

We could also work around this in copy_tree_body_r as follows, but I imagined that other tree walking functions might also be affected by the missing call for the TYPE_DECL of a DECL_EXPR.

Jason
commit 4320af50f15c11f6d6a7ddcf0fac51e752c0906f
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Jun 5 22:51:18 2020 -0400

    copy-body

diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 3160ca3f88a..2899bcf13e3 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1434,6 +1434,12 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
 	  TREE_SET_BLOCK (*tp, new_block);
 	}
 
+      if (TREE_CODE (*tp) == DECL_EXPR
+	  && TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
+	/* walk_tree_1 walks the type of a type DECL_EXPR but not the decl, so
+	   we clobber the type of the source decl unless we remap it now.  */
+	DECL_EXPR_DECL (*tp) = remap_decl (DECL_EXPR_DECL (*tp), id);
+
       if (TREE_CODE (*tp) != OMP_CLAUSE)
 	TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
 

Reply via email to