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" }
+}

Reply via email to