]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Emit error if not quiet and set *non_constant_p for -fno-exceptions metafn error...
authorJakub Jelinek <jakub@redhat.com>
Wed, 11 Mar 2026 06:54:36 +0000 (07:54 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 11 Mar 2026 06:54:36 +0000 (07:54 +0100)
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.

2026-03-11  Jakub Jelinek  <jakub@redhat.com>

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.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/reflect.cc
gcc/testsuite/g++.dg/reflect/no-exceptions1.C [new file with mode: 0644]

index 4064b7456b7bec6637ab122ba564a99a5a8580bb..52c667f779f42b1500051ed417c85c64e1ae5683 100644 (file)
@@ -929,17 +929,30 @@ get_info_vec (location_t loc, const constexpr_ctx *ctx, tree call, int n,
    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");
+       }
+      *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 +997,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;
 }
diff --git a/gcc/testsuite/g++.dg/reflect/no-exceptions1.C b/gcc/testsuite/g++.dg/reflect/no-exceptions1.C
new file mode 100644 (file)
index 0000000..73b7023
--- /dev/null
@@ -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" "" { target *-*-* } .-3 }