On Tue, 5 May 2026, Jason Merrill wrote:

> On 5/5/26 3:53 PM, Patrick Palka wrote:
> > On Tue, 5 May 2026, Jason Merrill wrote:
> > > On 5/5/26 1:20 PM, Patrick Palka wrote:
> > > > +/* Recursive workhorse of consteval_only_p.  Returns true if T is
> > > > definitely
> > > > +   consteval-only, false if it's definitely not, and unknown if we saw
> > > > an
> > > > +   incomplete type and therefore don't know.  */
> > > > +
> > > > +tristate
> > > > +consteval_only_p_walker::walk (tree t)
> > > > +{
> > > > +  t = TYPE_MAIN_VARIANT (t);
> > > > +
> > > > +  if (REFLECTION_TYPE_P (t))
> > > > +    return true;
> > > > +  else if (INDIRECT_TYPE_P (t))
> > > > +    return walk (TREE_TYPE (t));
> > > > +  else if (TREE_CODE (t) == ARRAY_TYPE)
> > > > +    return walk (TREE_TYPE (t));
> > > > +  else if (FUNC_OR_METHOD_TYPE_P (t))
> > > > +    {
> > > > +      tristate r = walk (TREE_TYPE (t));
> > > > +      for (tree parm = TYPE_ARG_TYPES (t);
> > > > +          parm != NULL_TREE && parm != void_list_node;
> > > > +          parm = TREE_CHAIN (parm))
> > > > +       {
> > > > +         if (r.is_true ())
> > > > +           break;
> > > > +         r = r || walk (TREE_VALUE (parm));
> > > > +       }
> > > > +      return r;
> > > > +    }
> > > > +  else if (RECORD_OR_UNION_TYPE_P (t))
> > > > +    {
> > > > +      if (tree *slot = hash_map_safe_get (consteval_only_class_cache,
> > > > t))
> > > > +       return *slot == boolean_true_node;
> > > > +
> > > > +      if (class_seen.add (t))
> > > > +       {
> > > > +         /* Optimistically assume this already seen consteval-unknown 
> > > > class
> > > > is
> > > > +            not consteval only, for sake of mutually recursive 
> > > > classes.  */
> > > > +         optimistic_p = true;
> > > > +         return false;
> > > > +       }
> > > > +      class_stack.safe_push (t);
> > > > +
> > > > +      tristate r = COMPLETE_TYPE_P (t) ? false : tristate::unknown ();
> > > > +      for (tree member = TYPE_FIELDS (t); member; member = DECL_CHAIN
> > > > (member))
> > > > +       if (TREE_CODE (member) == FIELD_DECL)
> > > > +         {
> > > > +           r = r || walk (TREE_TYPE (member));
> > > > +           if (r.is_true ())
> > > > +             break;
> > > > +         }
> > > > +
> > > > +      if (!COMPLETE_TYPE_P (t))
> > > > +       /* Until the type is laid out, we can't trust that its 
> > > > TYPE_FIELDS
> > > > +          won't change.  */;
> > > 
> > > We might move the COMPLETE_TYPE check...
> > > 
> > > > +      else if (r.is_true ())
> > > > +       hash_map_safe_put<hm_ggc> (consteval_only_class_cache,
> > > > +                                  t, boolean_true_node);
> > > > +      else if (r.is_false ()
> > > 
> > > ...into another exception for the is_false case, since I don't think the
> > > TYPE_FIELDS can change in a way that would invalidate is_true().
> > 
> > Sadly, it can! prune_lambda_captures can remove consteval-only
> > TYPE_FIELDS (corresponding to folded-away captures) before the closure
> > type has been laid out, so if we'd cache the result now we'd get the
> > wrong answer after pruning.
> > 
> > Without this second COMPLETE_TYPE_P check we'd get a bogus error in
> > reflect/reflect_constant_array6.C due to treating the lambda as
> > consteval even after pruning.
> 
> Ah, lambdas, always keeping us on our toes.  But then we could skip walking
> the fields at all if we're going to return unknown no matter what we see.

In that lambda case, where TYPE_FIELDS is set but TYPE_COMPLETE_P is
false, we won't always return unknonwn, we could return true if one of
its TYPE_FIELDS is consteval-only.

> 
> Jason
> 
> 

Reply via email to