>> Otherwise, I’m looking for guidance on what’s needed to land this.

> IIRC the paper talks about a call to an unknown function having the desired 
> semantics.  I’ll go with that, making it not throwing, const but looping and 
> leaf.  We can make it stronger if necessary, weakening it after people rely 
> on semantics is less useful IMO.  On RTL we have nothing at all, I’ve heard 
> ,volatile‘ asm is only about missing outputs, not side effects in general.  
> So I’d expand to nothing on RTL, watching what breaks.

with a follow up to a query
>I suggest to remove the assert or replace it with one that checks that if 
>ECF_LOOPING_CONST_OR_PURE is set the function is either ECF_CONST or ECF_PURE.

Done and re-tested on x86_64-darwin24 and powerpc64le-linux, OK for trunk now?
thanks
Iain

--- 8< ---

P1494 provides a mechanism that serves to demarc epochs within the code
preventing UB-based optimisations from 'time traveling' across such
boundaries.  The additional paper, P3641, alters the name of the function
to 'observable_checkpoint' which is the name used here.

This implementation  maintains the observable function call through to
expand, where it produces no code.

        PR c++/119060

gcc/ChangeLog:

        * builtins.cc (expand_builtin): Handle BUILT_IN_OBSERVABLE_CHKPT.
        * builtins.def (BUILT_IN_OBSERVABLE_CHKPT): New.
        * tree.cc (build_common_builtin_nodes): Build observable
        checkpoint builtin.

gcc/cp/ChangeLog:

        * cp-gimplify.cc (cp_fold): Handle std::observable_checkpoint
        specially, lowering it to the builtin.
        * cxxapi-data.csv: Add observable_checkpoint to <utility>.
        * std-name-hint.gperf: Add observable_checkpoint to <utility>.
        * std-name-hint.h: Regenerate.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp26/observable-checkpoint.C: New test.

Signed-off-by: Iain Sandoe <[email protected]>
---
 gcc/builtins.cc                               |   4 +
 gcc/builtins.def                              |   1 +
 gcc/cp/cp-gimplify.cc                         |  16 ++
 gcc/cp/cxxapi-data.csv                        |   1 +
 gcc/cp/std-name-hint.gperf                    |   1 +
 gcc/cp/std-name-hint.h                        | 142 +++++++++---------
 .../g++.dg/cpp26/observable-checkpoint.C      |  25 +++
 gcc/tree.cc                                   |   9 +-
 8 files changed, 128 insertions(+), 71 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp26/observable-checkpoint.C

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 78b561529f5..fb294ce58cd 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -8427,6 +8427,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
machine_mode mode,
       expand_builtin_unreachable ();
       return const0_rtx;
 
+    case BUILT_IN_OBSERVABLE_CHKPT:
+      /* Generate no code.  */
+      return const0_rtx;
+
     CASE_FLT_FN (BUILT_IN_SIGNBIT):
     case BUILT_IN_SIGNBITD32:
     case BUILT_IN_SIGNBITD64:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 3dc2333c6f2..7cd5353bcb1 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -1142,6 +1142,7 @@ DEF_C2Y_BUILTIN        (BUILT_IN_ULABS, "ulabs", 
BT_FN_ULONG_LONG, ATTR_CONST_NO
 DEF_C2Y_BUILTIN        (BUILT_IN_ULLABS, "ullabs", BT_FN_ULONGLONG_LONGLONG, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_UNREACHABLE_TRAP, "unreachable trap", 
BT_FN_VOID, ATTR_CONST_NORETURN_NOTHROW_LEAF_COLD_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, 
ATTR_CONST_NORETURN_NOTHROW_LEAF_COLD_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_OBSERVABLE_CHKPT, "observable_checkpoint", 
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, 
ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", 
BT_FN_VOID_PTR, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_VA_COPY, "va_copy", 
BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LEAF_LIST)
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 1662336e165..483d964bd62 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -3452,6 +3452,22 @@ cp_fold (tree x, fold_flags_t flags)
            break;
          }
 
+       /* We need to convert std::observable_checkpoint () into its equivalent
+          builtin for correctness, but must not rely on middle-end inlining
+          to do this; special-case it here.  */
+
+       if (call_expr_nargs (x) == 0
+           && decl_in_std_namespace_p (callee)
+           && DECL_NAME (callee) != NULL_TREE
+           && id_equal (DECL_NAME (callee), "observable_checkpoint"))
+         {
+           r = builtin_decl_explicit (BUILT_IN_OBSERVABLE_CHKPT);
+           releasing_vec vec;
+           r = finish_call_expr (r, &vec, false, false, tf_warning_or_error);
+           x = cp_fold (r, flags);
+           break;
+         }
+
        int sv = optimize, nw = sv;
 
        /* Some built-in function calls will be evaluated at compile-time in
diff --git a/gcc/cp/cxxapi-data.csv b/gcc/cp/cxxapi-data.csv
index 41f75b0092d..074368f1573 100644
--- a/gcc/cp/cxxapi-data.csv
+++ b/gcc/cp/cxxapi-data.csv
@@ -952,6 +952,7 @@
 <utility>,in_range,1,cxx20
 <utility>,to_underlying,1,cxx23
 <utility>,unreachable,1,cxx23
+<utility>,observable_checkpoint,1,cxx26
 <utility>,integer_sequence,1,cxx14
 <utility>,index_sequence,1,cxx14
 <utility>,make_integer_sequence,1,cxx14
diff --git a/gcc/cp/std-name-hint.gperf b/gcc/cp/std-name-hint.gperf
index 8ff08c0fa7c..3e06e61501d 100644
--- a/gcc/cp/std-name-hint.gperf
+++ b/gcc/cp/std-name-hint.gperf
@@ -577,6 +577,7 @@ piecewise_construct, "<utility>", cxx11
 piecewise_construct_t, "<utility>", cxx11
 to_underlying, "<utility>", cxx23
 unreachable, "<utility>", cxx23
+observable_checkpoint, "<utility>", cxx26
 # <variant>
 bad_variant_access, "<variant>", cxx17
 holds_alternative, "<variant>", cxx17
diff --git a/gcc/cp/std-name-hint.h b/gcc/cp/std-name-hint.h
index c5f800400ea..e354032a229 100644
--- a/gcc/cp/std-name-hint.h
+++ b/gcc/cp/std-name-hint.h
@@ -135,7 +135,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 487,
+      TOTAL_KEYWORDS = 488,
       MIN_WORD_LENGTH = 2,
       MAX_WORD_LENGTH = 39,
       MIN_HASH_VALUE = 7,
@@ -178,7 +178,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"print", "<print>", cxx23},
 #line 221 "std-name-hint.gperf"
       {"promise", "<future>", cxx11},
-#line 581 "std-name-hint.gperf"
+#line 582 "std-name-hint.gperf"
       {"bad_variant_access", "<variant>", cxx17},
 #line 328 "std-name-hint.gperf"
       {"to_address", "<memory>", cxx20},
@@ -198,7 +198,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"nounitbuf", "<ios>", cxx98},
 #line 433 "std-name-hint.gperf"
       {"basic_stringbuf", "<sstream>", cxx98},
-#line 592 "std-name-hint.gperf"
+#line 593 "std-name-hint.gperf"
       {"vector", "<vector>", cxx98},
 #line 246 "std-name-hint.gperf"
       {"noshowbase", "<ios>", cxx98},
@@ -228,7 +228,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"tuple_element", "<tuple>", cxx11},
 #line 519 "std-name-hint.gperf"
       {"tuple_element_t", "<tuple>", cxx14},
-#line 584 "std-name-hint.gperf"
+#line 585 "std-name-hint.gperf"
       {"variant", "<variant>", cxx17},
 #line 386 "std-name-hint.gperf"
       {"ends", "<ostream>", cxx98},
@@ -244,11 +244,11 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"noshowpos", "<ios>", cxx98},
 #line 388 "std-name-hint.gperf"
       {"flush_emit", "<ostream>", cxx20},
-#line 585 "std-name-hint.gperf"
+#line 586 "std-name-hint.gperf"
       {"variant_alternative", "<variant>", cxx17},
 #line 537 "std-name-hint.gperf"
       {"void_t", "<type_traits>", cxx17},
-#line 586 "std-name-hint.gperf"
+#line 587 "std-name-hint.gperf"
       {"variant_alternative_t", "<variant>", cxx17},
 #line 134 "std-name-hint.gperf"
       {"relation", "<concepts>", cxx20},
@@ -338,7 +338,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"basic_streambuf", "<streambuf>", cxx98},
 #line 167 "std-name-hint.gperf"
       {"basic_format_args", "<format>", cxx20},
-#line 588 "std-name-hint.gperf"
+#line 589 "std-name-hint.gperf"
       {"variant_size", "<variant>", cxx17},
 #line 407 "std-name-hint.gperf"
       {"multiset", "<set>", cxx98},
@@ -360,13 +360,13 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"remove_cvref_t", "<type_traits>", cxx20},
 #line 289 "std-name-hint.gperf"
       {"ostream_iterator", "<iterator>", cxx98},
-#line 587 "std-name-hint.gperf"
+#line 588 "std-name-hint.gperf"
       {"variant_npos", "<variant>", cxx17},
 #line 244 "std-name-hint.gperf"
       {"left", "<ios>", cxx98},
 #line 200 "std-name-hint.gperf"
       {"fstream", "<fstream>", cxx98},
-#line 590 "std-name-hint.gperf"
+#line 591 "std-name-hint.gperf"
       {"visit", "<variant>", cxx17},
 #line 208 "std-name-hint.gperf"
       {"invoke", "<functional>", cxx17},
@@ -458,7 +458,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"showpoint", "<ios>", cxx98},
 #line 446 "std-name-hint.gperf"
       {"stacktrace", "<stacktrace>", cxx23},
-#line 589 "std-name-hint.gperf"
+#line 590 "std-name-hint.gperf"
       {"variant_size_v", "<variant>", cxx17},
 #line 212 "std-name-hint.gperf"
       {"reference_wrapper", "<functional>", cxx11},
@@ -474,7 +474,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"allocator_traits", "<memory>", cxx11},
 #line 183 "std-name-hint.gperf"
       {"make_wformat_args", "<format>", cxx20},
-#line 583 "std-name-hint.gperf"
+#line 584 "std-name-hint.gperf"
       {"monostate", "<variant>", cxx17},
 #line 387 "std-name-hint.gperf"
       {"flush", "<ostream>", cxx98},
@@ -582,7 +582,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"stop_source", "<stop_token>", cxx20},
 #line 548 "std-name-hint.gperf"
       {"unordered_set", "<unordered_set>", cxx11},
-#line 582 "std-name-hint.gperf"
+#line 583 "std-name-hint.gperf"
       {"holds_alternative", "<variant>", cxx17},
 #line 514 "std-name-hint.gperf"
       {"make_tuple", "<tuple>", cxx11},
@@ -960,6 +960,8 @@ std_name_hint_lookup::find (const char *str, size_t len)
       {"domain_error", "<stdexcept>", cxx98},
 #line 84 "std-name-hint.gperf"
       {"chrono::steady_clock", "<chrono>", cxx11},
+#line 580 "std-name-hint.gperf"
+      {"observable_checkpoint", "<utility>", cxx26},
 #line 188 "std-name-hint.gperf"
       {"vformat_to", "<format>", cxx20},
 #line 54 "std-name-hint.gperf"
@@ -1142,7 +1144,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,    24,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    25,    26,    27,    -1,
          -1,    -1,    28,    29,    -1,    -1,    30,
-       -629,  -456,    -2,    33,    -1,    34,    -1,
+       -630,  -457,    -2,    33,    -1,    34,    -1,
          35,    -1,    36,    -1,    -1,    -1,    -1,
          37,    -1,    38,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    39,    -1,    -1,    -1,
@@ -1184,8 +1186,8 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,   152,   153,    -1,    -1,    -1,    -1,
          -1,    -1,   154,    -1,   155,   156,    -1,
          -1,    -1,   157,    -1,    -1,   158,    -1,
-        159,   160,    -1,    -1,    -1,  -933,    -1,
-        163,   164,    -1,   165,  -326,    -2,    -1,
+        159,   160,    -1,    -1,    -1,  -934,    -1,
+        163,   164,    -1,   165,  -327,    -2,    -1,
          -1,   166,    -1,    -1,    -1,    -1,   167,
         168,    -1,   169,    -1,    -1,    -1,   170,
         171,   172,   173,    -1,    -1,    -1,   174,
@@ -1195,11 +1197,11 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,   185,    -1,   186,   187,    -1,   188,
         189,   190,   191,   192,    -1,   193,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   194,    -1, -1005,  -292,
+         -1,    -1,    -1,   194,    -1, -1006,  -293,
          -2,    -1,    -1,    -1,   197,    -1,    -1,
         198,   199,   200,   201,    -1,    -1,    -1,
         202,   203,    -1,    -1,    -1,    -1,   204,
-         -1,    -1, -1030,  -282,    -2,    -1,   207,
+         -1,    -1, -1031,  -283,    -2,    -1,   207,
          -1,    -1,    -1,   208,   209,    -1,    -1,
          -1,   210,    -1,    -1,    -1,   211,    -1,
         212,    -1,    -1,   213,    -1,    -1,   214,
@@ -1227,7 +1229,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
         275,   276,    -1,   277,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,   278,    -1,
          -1,    -1,    -1,    -1,   279,   280,   281,
-      -1225,   284,  -205,    -2,    -1,    -1,    -1,
+      -1226,   284,  -206,    -2,    -1,    -1,    -1,
          -1,   285,    -1,    -1,    -1,    -1,   286,
         287,   288,    -1,    -1,   289,   290,   291,
          -1,    -1,    -1,    -1,   292,    -1,    -1,
@@ -1247,7 +1249,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,   331,    -1,   332,    -1,    -1,
          -1,    -1,   333,   334,   335,    -1,    -1,
          -1,   336,    -1,    -1,   337,   338,    -1,
-         -1,    -1,    -1, -1367,  -148,    -2,    -1,
+         -1,    -1,    -1, -1368,  -149,    -2,    -1,
         341,    -1,    -1,    -1,    -1,    -1,    -1,
         342,    -1,    -1,   343,    -1,    -1,    -1,
          -1,   344,   345,    -1,   346,    -1,    -1,
@@ -1282,70 +1284,70 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,    -1,    -1,    -1,    -1,   395,
         396,   397,    -1,    -1,   398,   399,    -1,
         400,   401,   402,   403,   404,   405,   406,
-        407,    -1,   408,    -1,    -1,   409,   410,
-         -1,    -1,    -1,   411,    -1,    -1,    -1,
-         -1,   412,    -1,   413,    -1,    -1,   414,
+        407,   408,   409,    -1,    -1,   410,   411,
+         -1,    -1,    -1,   412,    -1,    -1,    -1,
+         -1,   413,    -1,   414,    -1,    -1,   415,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,   415,    -1,    -1,    -1,   416,    -1,
+         -1,   416,    -1,    -1,    -1,   417,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-        417,    -1,    -1,   418,    -1,    -1,   419,
+        418,    -1,    -1,   419,    -1,    -1,   420,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   420,   421,    -1,    -1,
-         -1,    -1,    -1,    -1,   422,    -1,    -1,
+         -1,    -1,    -1,   421,   422,    -1,    -1,
          -1,    -1,    -1,    -1,   423,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,   424,    -1,    -1,
-         -1,    -1,    -1,    -1, -1704,   -62,    -2,
-         -1,    -1,    -1,    -1,   427,    -1,    -1,
-         -1,    -1,    -1,   428,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,   429,    -1,    -1,
+         -1,    -1,    -1,    -1,   425,    -1,    -1,
+         -1,    -1,    -1,    -1, -1705,   -62,    -2,
+         -1,    -1,    -1,    -1,   428,    -1,    -1,
+         -1,    -1,    -1,   429,    -1,    -1,    -1,
+         -1,    -1,    -1,    -1,    -1,    -1,    -1,
+         -1,    -1,    -1,    -1,   430,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-        430,    -1,    -1,    -1,    -1,    -1,   431,
-         -1,    -1,    -1,    -1,   432,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,   433,    -1,
-         -1,    -1,    -1,   434,    -1,    -1,   435,
-         -1,    -1,    -1,    -1,    -1,    -1,   436,
-        437,    -1,    -1,   438,    -1,    -1,    -1,
-         -1,    -1,   439,   440,    -1,    -1,    -1,
-        441,    -1,   442,    -1,   443,    -1,    -1,
-        444,    -1,    -1,    -1,   445,    -1,    -1,
+        431,    -1,    -1,    -1,    -1,    -1,   432,
+         -1,    -1,    -1,    -1,   433,    -1,    -1,
+         -1,    -1,    -1,    -1,    -1,   434,    -1,
+         -1,    -1,    -1,   435,    -1,    -1,   436,
+         -1,    -1,    -1,    -1,    -1,    -1,   437,
+        438,    -1,    -1,   439,    -1,    -1,    -1,
+         -1,    -1,   440,   441,    -1,    -1,    -1,
+        442,    -1,   443,    -1,   444,    -1,    -1,
+        445,    -1,    -1,    -1,   446,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,    -1,   446,
-         -1,   447,    -1,    -1,    -1,    -1,    -1,
-        448,    -1,    -1,    -1,    -1,    -1,    -1,
+         -1,    -1,    -1,    -1,    -1,    -1,   447,
+         -1,   448,    -1,    -1,    -1,    -1,    -1,
+        449,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   449,    -1,   450,    -1,
-         -1,    -1,    -1,    -1,   451,    -1,    -1,
-         -1,    -1,    -1,   452,    -1,    -1,    -1,
-         -1,    -1,   453,    -1,    -1,   454,    -1,
+         -1,    -1,    -1,   450,    -1,   451,    -1,
+         -1,    -1,    -1,    -1,   452,    -1,    -1,
+         -1,    -1,    -1,   453,    -1,    -1,    -1,
+         -1,    -1,   454,    -1,    -1,   455,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,   455,    -1,    -1,    -1,   456,    -1,
+         -1,   456,    -1,    -1,    -1,   457,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   457,    -1,   458,   459,
-         -1,    -1,    -1,    -1,    -1,    -1,   460,
-         -1,    -1,    -1,    -1,   461,    -1,    -1,
-         -1,    -1,   462,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,   463,    -1,    -1,
-         -1,    -1,    -1,   464,    -1,    -1,    -1,
+         -1,    -1,    -1,   458,    -1,   459,   460,
+         -1,    -1,    -1,    -1,    -1,    -1,   461,
+         -1,    -1,    -1,    -1,   462,    -1,    -1,
+         -1,    -1,   463,    -1,    -1,    -1,    -1,
+         -1,    -1,    -1,    -1,   464,    -1,    -1,
          -1,    -1,    -1,   465,    -1,    -1,    -1,
+         -1,    -1,    -1,   466,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,   466,    -1,    -1,
+         -1,    -1,    -1,    -1,   467,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,   467,    -1,    -1,    -1,   468,
+         -1,    -1,   468,    -1,    -1,    -1,   469,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,    -1,   469,
+         -1,    -1,    -1,    -1,    -1,    -1,   470,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
@@ -1354,22 +1356,22 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,   470,    -1,    -1,    -1,    -1,    -1,
+         -1,   471,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   471,    -1,   472,    -1,
+         -1,    -1,    -1,   472,    -1,   473,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,   473,    -1,    -1,    -1,    -1,
+         -1,    -1,   474,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,   474,    -1,
-         -1,   475,    -1,    -1,    -1,    -1,    -1,
+         -1,    -1,    -1,    -1,    -1,   475,    -1,
+         -1,   476,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-        476,    -1,    -1,    -1,    -1,    -1,    -1,
+        477,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
@@ -1380,14 +1382,14 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,   477,    -1,    -1,
+         -1,    -1,    -1,    -1,   478,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   478,   479,   480,    -1,
+         -1,    -1,    -1,   479,   480,   481,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,   481,    -1,
+         -1,    -1,    -1,    -1,    -1,   482,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
@@ -1402,12 +1404,12 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,   482,    -1,    -1,    -1,    -1,    -1,
+         -1,   483,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,   483,    -1,    -1,    -1,
+         -1,    -1,    -1,   484,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
@@ -1415,12 +1417,12 @@ std_name_hint_lookup::find (const char *str, size_t len)
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-         -1,    -1,    -1,    -1,    -1,   484,    -1,
          -1,    -1,    -1,    -1,    -1,   485,    -1,
+         -1,    -1,    -1,    -1,    -1,   486,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
          -1,    -1,    -1,    -1,    -1,    -1,    -1,
-        486
+        487
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/gcc/testsuite/g++.dg/cpp26/observable-checkpoint.C 
b/gcc/testsuite/g++.dg/cpp26/observable-checkpoint.C
new file mode 100644
index 00000000000..d5a86ce1c6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/observable-checkpoint.C
@@ -0,0 +1,25 @@
+// P1494R5+P3641R0 - Partial program correctness.
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fdump-tree-optimized -Wno-return-type -O" }
+// { dg-final { scan-tree-dump  {\+\s42} "optimized" } }
+// { dg-final { scan-tree-dump  {__builtin_observable_checkpoint} "optimized" 
} }
+
+extern int x;
+
+int
+here_b_ub ()
+{
+  // missing return triggers UB (we must ignore the warning for this test). 
+}
+
+int
+main ()
+{
+  x = 0;
+  __builtin_printf (" start \n");
+  x += 42;
+  // Without this checkpoint the addition above is elided (along with the rest
+  // of main).
+  __builtin_observable_checkpoint ();
+  here_b_ub ();
+}
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 966da8052a4..421d48005a7 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -10003,7 +10003,7 @@ set_call_expr_flags (tree decl, int flags)
   /* Looping const or pure is implied by noreturn.
      There is currently no way to declare looping const or looping pure alone. 
 */
   gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
-             || ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE))));
+             || (flags & (ECF_CONST | ECF_PURE)));
 }
 
 
@@ -10048,6 +10048,7 @@ build_common_builtin_nodes (void)
   if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
       || !builtin_decl_explicit_p (BUILT_IN_TRAP)
       || !builtin_decl_explicit_p (BUILT_IN_UNREACHABLE_TRAP)
+      || !builtin_decl_explicit_p (BUILT_IN_OBSERVABLE_CHKPT)
       || !builtin_decl_explicit_p (BUILT_IN_ABORT))
     {
       ftype = build_function_type (void_type_node, void_list_node);
@@ -10071,6 +10072,12 @@ build_common_builtin_nodes (void)
        local_define_builtin ("__builtin_trap", ftype, BUILT_IN_TRAP,
                              "__builtin_trap",
                              ECF_NORETURN | ECF_NOTHROW | ECF_LEAF | ECF_COLD);
+      if (!builtin_decl_explicit_p (BUILT_IN_OBSERVABLE_CHKPT))
+       local_define_builtin ("__builtin_observable_checkpoint", ftype,
+                             BUILT_IN_OBSERVABLE_CHKPT,
+                             "__builtin_observable_checkpoint",
+                             ECF_NOTHROW | ECF_LEAF | ECF_CONST
+                             | ECF_LOOPING_CONST_OR_PURE);
     }
 
   if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
-- 
2.39.5 (Apple Git-154)

Reply via email to