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.

But no big deal, so removed that part now.

Here is an updated patch, tested on x86_64-linux (on reflect/*).

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