On Tue, Jun 03, 2025 at 11:02:30AM -0400, Jason Merrill wrote:
> > On the potential_constant_expression_1 side, important change was to
> > set *jump_target conservatively on calls that could throw for C++26 (the
> > patch uses magic void_node for potential_constant_expression* instead of
> > VAR_DECL, so that we don't have to create new VAR_DECLs there uselessly).
> > Without that change, several methods in libstdc++ wouldn't work correctly.
> > I'm not sure what exactly potential_constant_expression_1 maps to in the
> > C++26 standard wording now and whether doing that is ok, because basically
> > after the first call to non-noexcept function it stops checking stuff.
> 
> I would expect that we could do better since for constexpr we need to be
> able to see the definitions of all the functions and know whether or not
> they can actually throw.

You mean also check TREE_NOTHROW (fndecl) which we currently propagate
conservatively (if we can prove something never throws, we set it)
or something else?
If TREE_NOTHROW, that would be twice
+          tree callee_fn = cp_get_fndecl_from_callee (callee, false);
           if (!flag_enforce_eh_specs
               || type_dependent_expression_p (callee)
               || !POINTER_TYPE_P (TREE_TYPE (callee))
-              || !type_noexcept_p (TREE_TYPE (TREE_TYPE (callee))))
+              || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee)))
+                  && (callee_fn == NULL_TREE
+                      || !TREE_NOTHROW (callee_fn))))
             *jump_target = void_node;
or so.

> But that's not necessary if it's difficult; at this point
> potential_constant_expression is just a conservative early filter to avoid
> later trying to evaluate thigs that can't possibly succeed.
> 
> > And, in some spots where I know potential_constant_expression_1 didn't
> > check some subexpressions (e.g. the EH only cleanups or TRY_BLOCK handlers)
> > I've added *potential_constant_expression* calls during cxx_eval_constant*,
> > not sure if I need to do that because potential_constant_expression_1 is
> > very conservative and just doesn't recurse on subexpressions in many cases.
> 
> I think that shouldn't be necessary.

Ok, I can remove those then.
It is
+               /* potential_constant_expression_1 doesn't recurse into
+                  TRY_BLOCK handlers, so call it now.  */
+               if (!ctx->quiet
+                   ? !require_potential_constant_expression (HANDLER_BODY (h))
+                   : !potential_constant_expression (HANDLER_BODY (h)))
+                 *non_constant_p = true;
+               else
hunk and
+         if (CLEANUP_EH_ONLY (t)
+             && (!ctx->quiet
+                 ? !require_potential_constant_expression (CLEANUP_EXPR (t))
+                 : !potential_constant_expression (CLEANUP_EXPR (t))))
+           *non_constant_p = true;
+         else
hunk (plus reindent the else parts of those).

        Jakub

Reply via email to