[PATCH] c++: Refrain from using replace_placeholders in constexpr evaluation [PR94205]

Patrick Palka ppalka@redhat.com
Fri Apr 3 20:07:01 GMT 2020


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.



More information about the Gcc-patches mailing list