From: Jakub Jelinek Date: Thu, 23 Jul 2026 13:42:10 +0000 (+0200) Subject: c++: Diagnose return from [[noreturn]] function during constant evaluation [PR126354] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=571aae1dc596ec58bca11534800a857109dce498;p=thirdparty%2Fgcc.git c++: Diagnose return from [[noreturn]] function during constant evaluation [PR126354] This PR complains about g++ not diagnosing return from [[noreturn]] function (which is UB) during constant evaluation. This patch diagnoses that. I haven't included the [[noreturn]] function name in the diagnostics as it is printed in the context: /home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp1y/pr126354.C:18:24: in 'constexpr' expansion of 'bar()' /home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp1y/pr126354.C:15:7: in 'constexpr' expansion of 'foo(false)' /home/jakub/src/gcc/gcc/testsuite/g++.dg/cpp1y/pr126354.C:15:7: error: '[[noreturn]]' call returns But if you think it is better to emit error ("%<[[noreturn]]%> %qD call returns", fun); instead, I can certainly do that. 2026-07-23 Jakub Jelinek PR c++/126354 * constexpr.cc (cxx_eval_call_expression): Diagnose return from [[noreturn]] function. * g++.dg/cpp1y/pr126354.C: New test. * g++.dg/cpp26/pr126354.C: New test. Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index fe2c417bed7..b4db9fd2bae 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -4572,6 +4572,13 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, cacheable = false; *jump_target = jmp_target; } + else if (!*non_constant_p && TREE_THIS_VOLATILE (fun)) + { + /* Return from a [[noreturn]] function. */ + if (!ctx->quiet) + error ("%<[[noreturn]]%> call returns"); + *non_constant_p = true; + } else if (DECL_CONSTRUCTOR_P (fun)) /* This can be null for a subobject constructor call, in which case what we care about is the initialization diff --git a/gcc/testsuite/g++.dg/cpp1y/pr126354.C b/gcc/testsuite/g++.dg/cpp1y/pr126354.C new file mode 100644 index 00000000000..9ea9fb83766 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr126354.C @@ -0,0 +1,18 @@ +// PR c++/126354 +// { dg-do compile { target c++14 } } + +[[noreturn]] constexpr void +foo (bool x) +{ + if (x) + for (;;) + ; +} + +constexpr bool +bar () +{ + foo (false); // { dg-error "'\\\[\\\[noreturn\\\]\\\]' call returns" } +} + +constexpr bool a = bar (); diff --git a/gcc/testsuite/g++.dg/cpp26/pr126354.C b/gcc/testsuite/g++.dg/cpp26/pr126354.C new file mode 100644 index 00000000000..3261df67562 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/pr126354.C @@ -0,0 +1,28 @@ +// PR c++/126354 +// { dg-do compile { target c++26 } } + +[[noreturn]] constexpr void +foo (bool x) +{ + if (x) + throw 42; +} + +consteval { + try + { + foo (true); + throw nullptr; + } + catch (int x) + { + if (x != 42) + throw nullptr; + return; + } + throw nullptr; +} + +consteval { + foo (false); // { dg-error "'\\\[\\\[noreturn\\\]\\\]' call returns" } +}