On Tue, Mar 10, 2026 at 08:06:46AM +0100, Jakub Jelinek wrote: > Hi! > > For -fno-exceptions, we reject throw statements in the source, and a lot > of code in the header has #ifdef __cpp_exceptions guarded stuff and the > FE for !flag_exceptions doesn't emit some parts of the IL needed for > exceptions. For the errors in metafns, we had just a todo to handle it > in the source but no actual implementation, so we allowed throwing > an exception and sometimes it worked to some extent and sometimes > it didn't. > > The following patch fixes it by not throwing an exception if user > asked for -fno-exceptions - instead we just emit an error including > the planned what () (unless ctx->quiet) and make the evaluation > non-constant. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok by me, thanks. > 2026-03-10 Jakub Jelinek <[email protected]> > > PR c++/124417 > * reflect.cc (get_meta_exception_object): Add CTX argument. For > !flag_exceptions emit error unless ctx->quiet, set *non_constant_p > to true and return NULL_TREE instead of throwing an exception. > (throw_exception): Adjust get_meta_exception_object caller. > > * g++.dg/reflect/no-exceptions1.C: New test. > > --- gcc/cp/reflect.cc.jj 2026-03-09 11:41:58.060768044 +0100 > +++ gcc/cp/reflect.cc 2026-03-09 18:09:08.967171309 +0100 > @@ -929,17 +929,31 @@ get_info_vec (location_t loc, const cons > and FROM is the info for from(). */ > > static tree > -get_meta_exception_object (location_t loc, const char *what, tree from, > - bool *non_constant_p) > +get_meta_exception_object (location_t loc, const constexpr_ctx *ctx, > + const char *what, tree from, bool *non_constant_p) > { > /* Don't throw in a template. */ > - // TODO For -fno-exceptions, report an error. > if (processing_template_decl) > { > *non_constant_p = true; > return NULL_TREE; > } > > + /* Don't try to throw exceptions with -fno-exceptions. */ > + if (!flag_exceptions) > + { > + if (!cxx_constexpr_quiet_p (ctx)) > + { > + auto_diagnostic_group d; > + 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"); > + } > + *non_constant_p = true; > + return NULL_TREE; > + } > + > tree type = lookup_qualified_name (std_meta_node, "exception", > LOOK_want::TYPE, /*complain*/true); > if (TREE_CODE (type) != TYPE_DECL || !CLASS_TYPE_P (TREE_TYPE (type))) > @@ -984,7 +998,8 @@ static tree > throw_exception (location_t loc, const constexpr_ctx *ctx, const char *msgid, > tree from, bool *non_constant_p, tree *jump_target) > { > - if (tree obj = get_meta_exception_object (loc, msgid, from, > non_constant_p)) > + if (tree obj = get_meta_exception_object (loc, ctx, msgid, from, > + non_constant_p)) > *jump_target = cxa_allocate_and_throw_exception (loc, ctx, obj); > return NULL_TREE; > } > --- gcc/testsuite/g++.dg/reflect/no-exceptions1.C.jj 2026-03-09 > 18:39:33.749487279 +0100 > +++ gcc/testsuite/g++.dg/reflect/no-exceptions1.C 2026-03-09 > 18:41:50.131194162 +0100 > @@ -0,0 +1,10 @@ > +// PR c++/124417 > +// { dg-do compile { target c++26 } } > +// { dg-additional-options "-freflection -fno-exceptions" } > + > +#include <meta> > + > +auto a = is_enum_type (^^::); > +// { dg-error "call to consteval function > 'std::meta::is_enum_type\\\(\\\^\\\^::\\\)' is not a constant expression" "" > { target *-*-* } .-1 } > +// { dg-error "'consteval bool std::meta::is_enum_type\\\(info\\\)' should > throw 'std::meta::exception'; 'what\\\(\\\)': 'reflection does not represent > a type'" "" { target *-*-* } .-2 } > +// { dg-message "exceptions are disabled, treating as non-constant; use > '-fexceptions' to enable" "" { target *-*-* } .-3 } > > Jakub > Marek
