>> 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)