On Fri, 3 Apr 2020, Jason Merrill wrote: > On 4/2/20 7:40 PM, Patrick Palka wrote: > > + /* Prefer the outermost matching object, but don't cross > > + CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors. */ > > + if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor)) > > + if (tree parent_ob = lookup_placeholder (ctx->parent, lval, type)) > > + return parent_ob; > > Instead of recursing here, would it work to replace the loop at the end with > tail recursion?
Do you mean something like the following? static tree lookup_placeholder (const constexpr_ctx *ctx, bool lval, tree type) { if (!ctx) return NULL_TREE; tree ob = ctx->object; if (ob && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type)) return obj; else if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor)) return lookup_placeholder (ctx->parent, lval, type); else return NULL_TREE; } I think we would need to set ctx->parent in more places in order for this to work, so that each node in the path to the innermost suboject is represented by a constexpr_ctx. Besides that, using tail recursion would, IIUC, mean that we would return the innermost matching object, but I think we want to return the outermost matching object (without crossing CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors) when there might be more than one matching object. For if a PLACEHOLDER_EXPR really was meant to refer to an object other than this outermost object, then presumably the CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag would have already been set on some suboject constructor and so we wouldn't have recursed to this outermost object in the first place, if I'm understanding the flag correctly.