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);