On Tue, Nov 21, 2023 at 04:44:01PM -0500, Jason Merrill wrote:
> > Or do you want to just use
> >       error_at (location, "%<static_assert%> message must be a "
> >                           "unevaluated string literal or object with "
> >                           "%<size%> and %<data%> members");
> > wording (even when it is in C++26 term) regardless of the -std= level?
> 
> No, I think "unevaluated string literal" will be confusing to users.  I
> guess it's fine as it is, let's just print the type (as commented inline
> below).

Ok.

> > +     error_at (location, "%<static_assert%> message must be a string "
> > +                         "literal or object with %<size%> and "
> > +                         "%<data%> members");
> 
> Let's print the type of the message as well.

so add " while it has type %qT", TREE_TYPE (message) or something else?

> > +      releasing_vec size_args, data_args;
> > +      message_sz = finish_call_expr (message_sz, &size_args, false, false,
> > +                                tf_warning_or_error);
> > +      message_data = finish_call_expr (message_data, &data_args, false, 
> > false,
> > +                                  tf_warning_or_error);
> > +      if (message_sz == error_mark_node || message_data == error_mark_node)
> > +   return;
> > +      if (tree s
> > +     = cp_get_callee_fndecl_nofold (extract_call_expr (message_sz)))
> > +   if (!DECL_DECLARED_CONSTEXPR_P (s))
> > +     warning_at (location, 0, "%qD used in %<static_assert%> message "
> > +                              "is not %<constexpr%>", s);
> 
> I don't think we need this check, it should be covered by the later
> constant-expression checks.

If the static_assert condition is true, we won't diagnose anything then.
clang++ there incorrectly errors, but I thought a warning could be useful
to users.  Perhaps it could warn only if the condition is true?

> > +     error_at (location, "%<static_assert%> message %<size()%> "
> > +                         "must be implicitly convertible to "
> > +                         "%<std::size_t%>");
> 
> Let's also print the type of size().

" while it has type %qT" ?

> > @@ -11485,9 +11544,96 @@ finish_static_assert (tree condition, tr
> >       if (processing_template_decl)
> >         goto defer;
> > -     int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
> > -                                (TREE_TYPE (TREE_TYPE (message))));
> > -     int len = TREE_STRING_LENGTH (message) / sz - 1;
> > +     int len;
> > +     const char *msg = NULL;
> > +     char *buf = NULL;
> > +     if (message_sz && message_data)
> > +       {
> > +         tree msz
> > +           = fold_non_dependent_expr (message_sz, complain,
> > +                                      /*manifestly_const_eval=*/true);
> 
> We can call cxx_constant_value here instead of fold_non_dependent_expr,
> since we don't get here in a template.

Ok.

> > +                 t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
> > +                 tree t2
> > +                   = fold_non_dependent_expr (t, complain,
> > +                                              /*manifestly_const_eval=*/
> > +                                              true);
> 
> This can also be cxx_constant_value.
> 
> > +                 if (!tree_fits_shwi_p (t2))
> > +                   {
> > +                     cxx_constant_value (t);

But in that case I don't have to call it again, right?

> Let's add a comment here about how you're using (data(), 0) to test
> core-constant.

Ok.

        Jakub

Reply via email to