On Tue, 10 Mar 2026 at 10:22, Jakub Jelinek <[email protected]> wrote:
>
> On Tue, Mar 10, 2026 at 09:39:05AM +0000, Jonathan Wakely wrote:
> > > +#if __has_builtin(__builtin_constexpr_diag)
> > > +         __builtin_constexpr_diag (2, "",
> > > +                                   "std::meta::exception::via argument "
> >
> > s/exception/access_context/
>
> Oops.
>
> > > +                                   "other than null or complete class 
> > > type "
> > > +                                   "reflection and exceptions disabled");
> >
> > I think the "and exceptions disabled" part is a bit confusing, it
> > reads like it's part of the "argument other than ..." clause.
> >
> > You could put it in parens "... (and exceptions disabled)" or maybe
> > just leave that part off completely? Users probably know when they're
> > compiling with -fno-exceptions and so shouldn't be surprised they
> > don't get an exception here.
>
> The FE emits
> error: exception handling disabled, use ‘-fexceptions’ to enable
> for throw 1; with -fno-exceptions and
> +         error_at (loc, "%qD should throw %qs; %<what()%>: %qs",
> +                   from, "std::meta::exception", _(what));
> +         inform (loc, "exceptions are disabled, treating as non-constant; "
> +                      "use %qs to enable", "-fexceptions");
> in the proposed metafn error patch with -fno-exceptions yesterday, so I
> wanted to mention it too.

Ah yes, I see. Maybe the library could also use something similar,
i.e. follow the error with a separate note about why it's not an
exception:

         __builtin_constexpr_diag (2, "",
                                   "std::meta::access_context::via argument "
                                   "other than null or complete class type "
                                   "reflection");
         __builtin_constexpr_diag (0, "", "use -fexceptions to turn
this into an exception");

Or "throwing meta::exception disabled by -fno-exception" or something.
But it's probably too early to settle on a perfect form of constexpr
diagnostics for now - we'll get more experience with them as people
start using this code.


> But no big deal, so removed that part now.
>
> Here is an updated patch, tested on x86_64-linux (on reflect/*).

OK, thanks.


>
> 2026-03-10  Jakub Jelinek  <[email protected]>
>
>         * include/std/meta (std::meta::exception::what()): Use
>         __builtin_constexpr_diag instead of __asm__("") if supported.
>         (std::meta::access_context::via(info)): Don't call is_class_type
>         if __cls is not a type.  Use __builtin_constexpr_diag instead of
>         __asm__("") if supported for -fno-exceptions.
>
>         * g++.dg/reflect/eh8.C: Expect different diagnostics.
>         * g++.dg/reflect/no-exceptions2.C: New test.
>
> --- libstdc++-v3/include/std/meta.jj    2026-03-10 08:14:28.100322627 +0100
> +++ libstdc++-v3/include/std/meta       2026-03-10 10:03:33.295442677 +0100
> @@ -120,7 +120,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>         // from UTF-8 to ordinary literal encoding failed.
>         // In that case what() should be non-constant.
>         if (_M_what.size() == 0 && _M_u8what.size() != 0)
> +#if __has_builtin(__builtin_constexpr_diag)
> +         __builtin_constexpr_diag (2, "",
> +                                   "std::meta::exception message could not "
> +                                   "be successfully transcoded from UTF-8 to 
> "
> +                                   "ordinary literal encoding");
> +#else
>           __asm__("");
> +#endif
>         return _M_what.c_str();
>        }
>        consteval u8string_view u8what() const noexcept { return _M_u8what; }
> @@ -591,7 +598,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      access_context::via(info __cls) const
>      {
>        if (__cls != info {}
> -         && (!std::meta::is_class_type(__cls)
> +         && (!std::meta::is_type(__cls)
> +             || !std::meta::is_class_type(__cls)
>               || !std::meta::is_complete_type(__cls)))
>         {
>  #if __cpp_exceptions
> @@ -599,7 +607,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>                                        "or complete class type reflection",
>                                      ^^access_context::via);
>  #else
> +#if __has_builtin(__builtin_constexpr_diag)
> +         __builtin_constexpr_diag (2, "",
> +                                   "std::meta::access_context::via argument "
> +                                   "other than null or complete class type "
> +                                   "reflection");
> +#else
>           __asm__("");
> +#endif
>           return *this;
>  #endif
>         }
> --- gcc/testsuite/g++.dg/reflect/eh8.C.jj       2026-01-15 16:33:47.007097959 
> +0100
> +++ gcc/testsuite/g++.dg/reflect/eh8.C  2026-03-10 09:57:15.887817046 +0100
> @@ -24,7 +24,7 @@ bar ()
>  {
>    exception a (u8"\N{GRINNING FACE}\N{GRINNING FACE WITH SMILING 
> EYES}\N{LEFT SPEECH BUBBLE}", ^^foo);
>    const char *b = a.what ();   // { dg-message "in 'constexpr' expansion of 
> 'a.std::meta::exception::what\\\(\\\)" }
> -  return true;                 // { dg-error "inline assembly is not a 
> constant expression" "" { target *-*-* } 0 }
> +  return true;                 // { dg-error "constexpr message: 
> std::meta::exception message could not be successfully transcoded from UTF-8 
> to ordinary literal encoding" "" { target *-*-* } 0 }
>  }
>
>  static_assert (foo ());
> --- gcc/testsuite/g++.dg/reflect/no-exceptions2.C.jj    2026-03-10 
> 09:49:10.810013159 +0100
> +++ gcc/testsuite/g++.dg/reflect/no-exceptions2.C       2026-03-10 
> 10:07:44.471200349 +0100
> @@ -0,0 +1,15 @@
> +// { dg-do compile { target c++26 } }
> +// { dg-additional-options "-freflection -fno-exceptions" }
> +
> +#include <meta>
> +
> +consteval bool
> +foo ()
> +{
> +  auto ctx = std::meta::access_context::unchecked ();
> +  auto ctx2 = ctx.via (^^::);  // { dg-message "in 'constexpr' expansion of 
> 'ctx.std::meta::access_context::via\\\(\\\^\\\^::\\\)'" }
> +  return true;
> +}
> +
> +auto b = foo ();               // { dg-message "in 'constexpr' expansion of 
> 'foo\\\(\\\)'" }
> +// { dg-error "constexpr message: std::meta::access_context::via argument 
> other than null or complete class type reflection" "" { target *-*-* } 0 }
>
>
>         Jakub
>

Reply via email to