https://gcc.gnu.org/g:5b0a952ca720ba661baa20cd72becfeb9532633f
commit r17-4596-g5b0a952ca720ba661baa20cd72becfeb9532633f Author: Jakub Jelinek <[email protected]> Date: Wed Sep 23 09:31:07 2026 +0200 c++: Fix __builtin_is_within_lifetime error recovery [PR127506] As the following testcase shows, error_mark_node can appear anywhere in the ctors, and with the asserts we ICE on those during error recovery. The following patch just returns error_mark_node in those cases. 2026-09-23 Jakub Jelinek <[email protected]> PR c++/127506 * constexpr.cc (is_within_lifetime): When val is error_mark_node, return it. * g++.dg/cpp26/within-lifetime13.C: New test. Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/constexpr.cc | 6 ++++++ gcc/testsuite/g++.dg/cpp26/within-lifetime13.C | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index e285582e4c02..e90ca1018a7d 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -2665,6 +2665,8 @@ is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun, } else if (val == val_uninit) return boolean_false_node; + else if (val == error_mark_node) + return val; else { gcc_assert (TREE_CODE (val) == CONSTRUCTOR); @@ -2693,6 +2695,8 @@ is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun, } if (val == val_zero_init || val == val_uninit) continue; + if (val == error_mark_node) + return val; gcc_assert (TREE_CODE (val) == CONSTRUCTOR); unsigned int j; tree field, value; @@ -2726,6 +2730,8 @@ is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun, return t; if (val == val_zero_init || val == val_uninit) continue; + if (val == error_mark_node) + return val; if (TREE_CODE (val) == STRING_CST) return boolean_true_node; gcc_assert (TREE_CODE (val) == CONSTRUCTOR); diff --git a/gcc/testsuite/g++.dg/cpp26/within-lifetime13.C b/gcc/testsuite/g++.dg/cpp26/within-lifetime13.C new file mode 100644 index 000000000000..9d7f644bdc5d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/within-lifetime13.C @@ -0,0 +1,20 @@ +// PR c++/127506 +// { dg-do compile { target c++20 } } + +namespace std { + template <class T> + consteval bool + is_within_lifetime (const T *p) noexcept + { + return __builtin_is_within_lifetime (p); + } +} + +struct S { char a; }; +constexpr S s = { int b; }; // { dg-error "expected" } + +bool +bar () +{ + return (!std::is_within_lifetime (&s.a)); // { dg-error "is not a constant expression" } +}
