Re: [PATCH] c++: Emit error if not quiet and set *non_constant_p for -fno-exceptions metafn error cases [PR124417]
On 3/10/26 3:53 PM, Jakub Jelinek wrote:
On Tue, Mar 10, 2026 at 03:42:51PM -0400, Jason Merrill wrote:
On 3/10/26 8:38 AM, Marek Polacek wrote:
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
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.jj2026-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; %: %qs",
+ from, "std::meta::exception", _(what));
+ inform (loc, "exceptions are disabled, treating as non-constant; "
+ "use %qs to enable", "-fexceptions");
Hmm, I don't think suggesting -fexceptions is useful here; presumably they
are disabled by -fno-exceptions, and removing that (perhaps after a project
policy discussion) would be better than having -fno-exceptions -fexceptions.
That was just following the error we emit on throw stmt when using
-fno-exceptions:
a.C: In function ‘void foo()’:
a.C:4:9: error: exception handling disabled, use ‘-fexceptions’ to enable
Ah, from doing_eh.
That seems similarly unnecessary, I wonder if it dates back to before
-fexceptions was the default? It certainly dates back to the beginning
of git history. I wouldn't bother changing this message, but let's not
copy it.
4 | throw 1;
| ^
But if you think the ; and following part is useless, I can certainly drop
that.
Please. OK with that change.
Jason
Re: [PATCH] c++: Emit error if not quiet and set *non_constant_p for -fno-exceptions metafn error cases [PR124417]
On Tue, Mar 10, 2026 at 03:42:51PM -0400, Jason Merrill wrote:
> On 3/10/26 8:38 AM, Marek Polacek wrote:
> > > 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
> > >
> > > 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; %: %qs",
> > > + from, "std::meta::exception", _(what));
> > > + inform (loc, "exceptions are disabled, treating as non-constant; "
> > > +"use %qs to enable", "-fexceptions");
>
> Hmm, I don't think suggesting -fexceptions is useful here; presumably they
> are disabled by -fno-exceptions, and removing that (perhaps after a project
> policy discussion) would be better than having -fno-exceptions -fexceptions.
That was just following the error we emit on throw stmt when using
-fno-exceptions:
a.C: In function ‘void foo()’:
a.C:4:9: error: exception handling disabled, use ‘-fexceptions’ to enable
4 | throw 1;
| ^
But if you think the ; and following part is useless, I can certainly drop
that.
Jakub
Re: [PATCH] c++: Emit error if not quiet and set *non_constant_p for -fno-exceptions metafn error cases [PR124417]
On 3/10/26 8:38 AM, Marek Polacek wrote:
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
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.jj2026-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; %: %qs",
+ from, "std::meta::exception", _(what));
+ inform (loc, "exceptions are disabled, treating as non-constant; "
+ "use %qs to enable", "-fexceptions");
Hmm, I don't think suggesting -fexceptions is useful here; presumably
they are disabled by -fno-exceptions, and removing that (perhaps after a
project policy discussion) would be better than having -fno-exceptions
-fexceptions.
Jason
Re: [PATCH] c++: Emit error if not quiet and set *non_constant_p for -fno-exceptions metafn error cases [PR124417]
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
>
> 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; %: %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
> +
> +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
