On 9/22/26 4:13 AM, Jakub Jelinek wrote:
Hi!
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 boolean_false_node
in those cases, it doesn't really matter what exactly we return
as long as we do't crash and ideally have some consistency.
Why not return error_mark_node as usual?
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2026-09-22 Jakub Jelinek <[email protected]>
PR c++/127506
* constexpr.cc (is_within_lifetime): When val is error_mark_node,
return boolean_false_node.
* g++.dg/cpp26/within-lifetime13.C: New test.
--- a/gcc/cp/constexpr.cc 2026-09-15 12:01:51.694090042 +0200
+++ b/gcc/cp/constexpr.cc 2026-09-21 11:58:34.593165383 +0200
@@ -2655,7 +2655,7 @@ is_within_lifetime (location_t loc, cons
return boolean_false_node;
continue;
}
- else if (val == val_uninit)
+ else if (val == val_uninit || val == error_mark_node)
return boolean_false_node;
else
{
@@ -2685,6 +2685,8 @@ is_within_lifetime (location_t loc, cons
}
if (val == val_zero_init || val == val_uninit)
continue;
+ if (val == error_mark_node)
+ return boolean_false_node;
gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
unsigned int j;
tree field, value;
@@ -2718,6 +2720,8 @@ is_within_lifetime (location_t loc, cons
return t;
if (val == val_zero_init || val == val_uninit)
continue;
+ if (val == error_mark_node)
+ return boolean_false_node;
if (TREE_CODE (val) == STRING_CST)
return boolean_true_node;
gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
--- a/gcc/testsuite/g++.dg/cpp26/within-lifetime13.C 2026-09-21
11:56:45.183624691 +0200
+++ b/gcc/testsuite/g++.dg/cpp26/within-lifetime13.C 2026-09-21
11:57:28.325049268 +0200
@@ -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));
+}
Jakub