Compare commits

...

2 Commits

Author SHA1 Message Date
Iain Sandoe 1e84849cb2 libstdc++: Implement P1494 and P3641 Partial program correctness [PR119060]
This implements the library parts of P1494 as amended by P3641.  For GCC the
compiler itself treats stdio operations as equivalent to the observable
checkpoint and thus it does not appear to be necessary to add calls to those
functions (it will not alter the outcome).

This adds the facility for C++26, although there is no reason, in principle,
that it would not work back to C++11 at least.

	PR c++/119060

libstdc++-v3/ChangeLog:

	* include/bits/version.def: Add observable_checkpoint at present
	allowed from C++26.
	* include/bits/version.h: Regenerate.
	* include/std/utility: Add std::observable_checkpoint().
	* src/c++23/std.cc.in: Add obervable_checkpoint () to utility.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
2025-10-18 23:18:02 +01:00
Iain Sandoe 9056b5faa8 c++: Implement P1494 and P3641 Partial program correctness [PR119060].
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:

	* 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 <iain@sandoe.co.uk>
2025-10-18 23:17:42 +01:00
11 changed files with 153 additions and 71 deletions

View File

@ -8427,6 +8427,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
expand_builtin_unreachable (); expand_builtin_unreachable ();
return const0_rtx; return const0_rtx;
case BUILT_IN_OBSERVABLE_CHKPT:
/* Generate no code. */
return const0_rtx;
CASE_FLT_FN (BUILT_IN_SIGNBIT): CASE_FLT_FN (BUILT_IN_SIGNBIT):
case BUILT_IN_SIGNBITD32: case BUILT_IN_SIGNBITD32:
case BUILT_IN_SIGNBITD64: case BUILT_IN_SIGNBITD64:

View File

@ -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_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_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_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_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_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) DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LEAF_LIST)

View File

@ -952,6 +952,7 @@
<utility>,in_range,1,cxx20 <utility>,in_range,1,cxx20
<utility>,to_underlying,1,cxx23 <utility>,to_underlying,1,cxx23
<utility>,unreachable,1,cxx23 <utility>,unreachable,1,cxx23
<utility>,observable_checkpoint,1,cxx26
<utility>,integer_sequence,1,cxx14 <utility>,integer_sequence,1,cxx14
<utility>,index_sequence,1,cxx14 <utility>,index_sequence,1,cxx14
<utility>,make_integer_sequence,1,cxx14 <utility>,make_integer_sequence,1,cxx14

Can't render this file because it contains an unexpected character in line 35 and column 12.

View File

@ -577,6 +577,7 @@ piecewise_construct, "<utility>", cxx11
piecewise_construct_t, "<utility>", cxx11 piecewise_construct_t, "<utility>", cxx11
to_underlying, "<utility>", cxx23 to_underlying, "<utility>", cxx23
unreachable, "<utility>", cxx23 unreachable, "<utility>", cxx23
observable_checkpoint, "<utility>", cxx26
# <variant> # <variant>
bad_variant_access, "<variant>", cxx17 bad_variant_access, "<variant>", cxx17
holds_alternative, "<variant>", cxx17 holds_alternative, "<variant>", cxx17

View File

@ -135,7 +135,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{ {
enum enum
{ {
TOTAL_KEYWORDS = 487, TOTAL_KEYWORDS = 488,
MIN_WORD_LENGTH = 2, MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 39, MAX_WORD_LENGTH = 39,
MIN_HASH_VALUE = 7, MIN_HASH_VALUE = 7,
@ -178,7 +178,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"print", "<print>", cxx23}, {"print", "<print>", cxx23},
#line 221 "std-name-hint.gperf" #line 221 "std-name-hint.gperf"
{"promise", "<future>", cxx11}, {"promise", "<future>", cxx11},
#line 581 "std-name-hint.gperf" #line 582 "std-name-hint.gperf"
{"bad_variant_access", "<variant>", cxx17}, {"bad_variant_access", "<variant>", cxx17},
#line 328 "std-name-hint.gperf" #line 328 "std-name-hint.gperf"
{"to_address", "<memory>", cxx20}, {"to_address", "<memory>", cxx20},
@ -198,7 +198,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"nounitbuf", "<ios>", cxx98}, {"nounitbuf", "<ios>", cxx98},
#line 433 "std-name-hint.gperf" #line 433 "std-name-hint.gperf"
{"basic_stringbuf", "<sstream>", cxx98}, {"basic_stringbuf", "<sstream>", cxx98},
#line 592 "std-name-hint.gperf" #line 593 "std-name-hint.gperf"
{"vector", "<vector>", cxx98}, {"vector", "<vector>", cxx98},
#line 246 "std-name-hint.gperf" #line 246 "std-name-hint.gperf"
{"noshowbase", "<ios>", cxx98}, {"noshowbase", "<ios>", cxx98},
@ -228,7 +228,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"tuple_element", "<tuple>", cxx11}, {"tuple_element", "<tuple>", cxx11},
#line 519 "std-name-hint.gperf" #line 519 "std-name-hint.gperf"
{"tuple_element_t", "<tuple>", cxx14}, {"tuple_element_t", "<tuple>", cxx14},
#line 584 "std-name-hint.gperf" #line 585 "std-name-hint.gperf"
{"variant", "<variant>", cxx17}, {"variant", "<variant>", cxx17},
#line 386 "std-name-hint.gperf" #line 386 "std-name-hint.gperf"
{"ends", "<ostream>", cxx98}, {"ends", "<ostream>", cxx98},
@ -244,11 +244,11 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"noshowpos", "<ios>", cxx98}, {"noshowpos", "<ios>", cxx98},
#line 388 "std-name-hint.gperf" #line 388 "std-name-hint.gperf"
{"flush_emit", "<ostream>", cxx20}, {"flush_emit", "<ostream>", cxx20},
#line 585 "std-name-hint.gperf" #line 586 "std-name-hint.gperf"
{"variant_alternative", "<variant>", cxx17}, {"variant_alternative", "<variant>", cxx17},
#line 537 "std-name-hint.gperf" #line 537 "std-name-hint.gperf"
{"void_t", "<type_traits>", cxx17}, {"void_t", "<type_traits>", cxx17},
#line 586 "std-name-hint.gperf" #line 587 "std-name-hint.gperf"
{"variant_alternative_t", "<variant>", cxx17}, {"variant_alternative_t", "<variant>", cxx17},
#line 134 "std-name-hint.gperf" #line 134 "std-name-hint.gperf"
{"relation", "<concepts>", cxx20}, {"relation", "<concepts>", cxx20},
@ -338,7 +338,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"basic_streambuf", "<streambuf>", cxx98}, {"basic_streambuf", "<streambuf>", cxx98},
#line 167 "std-name-hint.gperf" #line 167 "std-name-hint.gperf"
{"basic_format_args", "<format>", cxx20}, {"basic_format_args", "<format>", cxx20},
#line 588 "std-name-hint.gperf" #line 589 "std-name-hint.gperf"
{"variant_size", "<variant>", cxx17}, {"variant_size", "<variant>", cxx17},
#line 407 "std-name-hint.gperf" #line 407 "std-name-hint.gperf"
{"multiset", "<set>", cxx98}, {"multiset", "<set>", cxx98},
@ -360,13 +360,13 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"remove_cvref_t", "<type_traits>", cxx20}, {"remove_cvref_t", "<type_traits>", cxx20},
#line 289 "std-name-hint.gperf" #line 289 "std-name-hint.gperf"
{"ostream_iterator", "<iterator>", cxx98}, {"ostream_iterator", "<iterator>", cxx98},
#line 587 "std-name-hint.gperf" #line 588 "std-name-hint.gperf"
{"variant_npos", "<variant>", cxx17}, {"variant_npos", "<variant>", cxx17},
#line 244 "std-name-hint.gperf" #line 244 "std-name-hint.gperf"
{"left", "<ios>", cxx98}, {"left", "<ios>", cxx98},
#line 200 "std-name-hint.gperf" #line 200 "std-name-hint.gperf"
{"fstream", "<fstream>", cxx98}, {"fstream", "<fstream>", cxx98},
#line 590 "std-name-hint.gperf" #line 591 "std-name-hint.gperf"
{"visit", "<variant>", cxx17}, {"visit", "<variant>", cxx17},
#line 208 "std-name-hint.gperf" #line 208 "std-name-hint.gperf"
{"invoke", "<functional>", cxx17}, {"invoke", "<functional>", cxx17},
@ -458,7 +458,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"showpoint", "<ios>", cxx98}, {"showpoint", "<ios>", cxx98},
#line 446 "std-name-hint.gperf" #line 446 "std-name-hint.gperf"
{"stacktrace", "<stacktrace>", cxx23}, {"stacktrace", "<stacktrace>", cxx23},
#line 589 "std-name-hint.gperf" #line 590 "std-name-hint.gperf"
{"variant_size_v", "<variant>", cxx17}, {"variant_size_v", "<variant>", cxx17},
#line 212 "std-name-hint.gperf" #line 212 "std-name-hint.gperf"
{"reference_wrapper", "<functional>", cxx11}, {"reference_wrapper", "<functional>", cxx11},
@ -474,7 +474,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"allocator_traits", "<memory>", cxx11}, {"allocator_traits", "<memory>", cxx11},
#line 183 "std-name-hint.gperf" #line 183 "std-name-hint.gperf"
{"make_wformat_args", "<format>", cxx20}, {"make_wformat_args", "<format>", cxx20},
#line 583 "std-name-hint.gperf" #line 584 "std-name-hint.gperf"
{"monostate", "<variant>", cxx17}, {"monostate", "<variant>", cxx17},
#line 387 "std-name-hint.gperf" #line 387 "std-name-hint.gperf"
{"flush", "<ostream>", cxx98}, {"flush", "<ostream>", cxx98},
@ -582,7 +582,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"stop_source", "<stop_token>", cxx20}, {"stop_source", "<stop_token>", cxx20},
#line 548 "std-name-hint.gperf" #line 548 "std-name-hint.gperf"
{"unordered_set", "<unordered_set>", cxx11}, {"unordered_set", "<unordered_set>", cxx11},
#line 582 "std-name-hint.gperf" #line 583 "std-name-hint.gperf"
{"holds_alternative", "<variant>", cxx17}, {"holds_alternative", "<variant>", cxx17},
#line 514 "std-name-hint.gperf" #line 514 "std-name-hint.gperf"
{"make_tuple", "<tuple>", cxx11}, {"make_tuple", "<tuple>", cxx11},
@ -960,6 +960,8 @@ std_name_hint_lookup::find (const char *str, size_t len)
{"domain_error", "<stdexcept>", cxx98}, {"domain_error", "<stdexcept>", cxx98},
#line 84 "std-name-hint.gperf" #line 84 "std-name-hint.gperf"
{"chrono::steady_clock", "<chrono>", cxx11}, {"chrono::steady_clock", "<chrono>", cxx11},
#line 580 "std-name-hint.gperf"
{"observable_checkpoint", "<utility>", cxx26},
#line 188 "std-name-hint.gperf" #line 188 "std-name-hint.gperf"
{"vformat_to", "<format>", cxx20}, {"vformat_to", "<format>", cxx20},
#line 54 "std-name-hint.gperf" #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, 24, -1, -1, -1, -1,
-1, -1, -1, 25, 26, 27, -1, -1, -1, -1, 25, 26, 27, -1,
-1, -1, 28, 29, -1, -1, 30, -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, 35, -1, 36, -1, -1, -1, -1,
37, -1, 38, -1, -1, -1, -1, 37, -1, 38, -1, -1, -1, -1,
-1, -1, -1, 39, -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, 152, 153, -1, -1, -1, -1,
-1, -1, 154, -1, 155, 156, -1, -1, -1, 154, -1, 155, 156, -1,
-1, -1, 157, -1, -1, 158, -1, -1, -1, 157, -1, -1, 158, -1,
159, 160, -1, -1, -1, -933, -1, 159, 160, -1, -1, -1, -934, -1,
163, 164, -1, 165, -326, -2, -1, 163, 164, -1, 165, -327, -2, -1,
-1, 166, -1, -1, -1, -1, 167, -1, 166, -1, -1, -1, -1, 167,
168, -1, 169, -1, -1, -1, 170, 168, -1, 169, -1, -1, -1, 170,
171, 172, 173, -1, -1, -1, 174, 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, -1, 185, -1, 186, 187, -1, 188,
189, 190, 191, 192, -1, 193, -1, 189, 190, 191, 192, -1, 193, -1,
-1, -1, -1, -1, -1, -1, -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, -2, -1, -1, -1, 197, -1, -1,
198, 199, 200, 201, -1, -1, -1, 198, 199, 200, 201, -1, -1, -1,
202, 203, -1, -1, -1, -1, 204, 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, -1, -1, 208, 209, -1, -1,
-1, 210, -1, -1, -1, 211, -1, -1, 210, -1, -1, -1, 211, -1,
212, -1, -1, 213, -1, -1, 214, 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, 275, 276, -1, 277, -1, -1, -1,
-1, -1, -1, -1, -1, 278, -1, -1, -1, -1, -1, -1, 278, -1,
-1, -1, -1, -1, 279, 280, 281, -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, -1, 285, -1, -1, -1, -1, 286,
287, 288, -1, -1, 289, 290, 291, 287, 288, -1, -1, 289, 290, 291,
-1, -1, -1, -1, 292, -1, -1, -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, 331, -1, 332, -1, -1,
-1, -1, 333, 334, 335, -1, -1, -1, -1, 333, 334, 335, -1, -1,
-1, 336, -1, -1, 337, 338, -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, 341, -1, -1, -1, -1, -1, -1,
342, -1, -1, 343, -1, -1, -1, 342, -1, -1, 343, -1, -1, -1,
-1, 344, 345, -1, 346, -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, -1, -1, -1, -1, -1, -1, 395,
396, 397, -1, -1, 398, 399, -1, 396, 397, -1, -1, 398, 399, -1,
400, 401, 402, 403, 404, 405, 406, 400, 401, 402, 403, 404, 405, 406,
407, -1, 408, -1, -1, 409, 410, 407, 408, 409, -1, -1, 410, 411,
-1, -1, -1, 411, -1, -1, -1, -1, -1, -1, 412, -1, -1, -1,
-1, 412, -1, 413, -1, -1, 414, -1, 413, -1, 414, -1, -1, 415,
-1, -1, -1, -1, -1, -1, -1, -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, -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, -1, -1, -1, -1,
-1, -1, -1, 420, 421, -1, -1, -1, -1, -1, 421, 422, -1, -1,
-1, -1, -1, -1, 422, -1, -1,
-1, -1, -1, -1, 423, -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, 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, -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, -1, -1, -1,
430, -1, -1, -1, -1, -1, 431, -1, -1, -1, -1, 430, -1, -1,
-1, -1, -1, -1, 432, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 433, -1, 431, -1, -1, -1, -1, -1, 432,
-1, -1, -1, 434, -1, -1, 435, -1, -1, -1, -1, 433, -1, -1,
-1, -1, -1, -1, -1, -1, 436, -1, -1, -1, -1, -1, 434, -1,
437, -1, -1, 438, -1, -1, -1, -1, -1, -1, 435, -1, -1, 436,
-1, -1, 439, 440, -1, -1, -1, -1, -1, -1, -1, -1, -1, 437,
441, -1, 442, -1, 443, -1, -1, 438, -1, -1, 439, -1, -1, -1,
444, -1, -1, -1, 445, -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, -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, -1, -1, -1, -1, -1, 447,
-1, 447, -1, -1, -1, -1, -1, -1, 448, -1, -1, -1, -1, -1,
448, -1, -1, -1, -1, -1, -1, 449, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 449, -1, 450, -1, -1, -1, -1, 450, -1, 451, -1,
-1, -1, -1, -1, 451, -1, -1, -1, -1, -1, -1, 452, -1, -1,
-1, -1, -1, 452, -1, -1, -1, -1, -1, -1, 453, -1, -1, -1,
-1, -1, 453, -1, -1, 454, -1, -1, -1, 454, -1, -1, 455, -1,
-1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1,
-1, -1, -1, 457, -1, 458, 459, -1, -1, -1, 458, -1, 459, 460,
-1, -1, -1, -1, -1, -1, 460, -1, -1, -1, -1, -1, -1, 461,
-1, -1, -1, -1, 461, -1, -1, -1, -1, -1, -1, 462, -1, -1,
-1, -1, 462, -1, -1, -1, -1, -1, -1, 463, -1, -1, -1, -1,
-1, -1, -1, -1, 463, -1, -1, -1, -1, -1, -1, 464, -1, -1,
-1, -1, -1, 464, -1, -1, -1,
-1, -1, -1, 465, -1, -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, -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, -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, -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, -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, -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, -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, -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, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 474, -1, -1, -1, -1, -1, -1, 475, -1,
-1, 475, -1, -1, -1, -1, -1, -1, 476, -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,
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, -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, -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, -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, -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, -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, -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, -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, -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, -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, 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, -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) if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)

View File

@ -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 ();
}

View File

@ -10012,7 +10012,7 @@ set_call_expr_flags (tree decl, int flags)
/* Looping const or pure is implied by noreturn. /* Looping const or pure is implied by noreturn.
There is currently no way to declare looping const or looping pure alone. */ There is currently no way to declare looping const or looping pure alone. */
gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE) gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
|| ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE)))); || (flags & (ECF_CONST | ECF_PURE)));
} }
@ -10057,6 +10057,7 @@ build_common_builtin_nodes (void)
if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE) if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
|| !builtin_decl_explicit_p (BUILT_IN_TRAP) || !builtin_decl_explicit_p (BUILT_IN_TRAP)
|| !builtin_decl_explicit_p (BUILT_IN_UNREACHABLE_TRAP) || !builtin_decl_explicit_p (BUILT_IN_UNREACHABLE_TRAP)
|| !builtin_decl_explicit_p (BUILT_IN_OBSERVABLE_CHKPT)
|| !builtin_decl_explicit_p (BUILT_IN_ABORT)) || !builtin_decl_explicit_p (BUILT_IN_ABORT))
{ {
ftype = build_function_type (void_type_node, void_list_node); ftype = build_function_type (void_type_node, void_list_node);
@ -10080,6 +10081,12 @@ build_common_builtin_nodes (void)
local_define_builtin ("__builtin_trap", ftype, BUILT_IN_TRAP, local_define_builtin ("__builtin_trap", ftype, BUILT_IN_TRAP,
"__builtin_trap", "__builtin_trap",
ECF_NORETURN | ECF_NOTHROW | ECF_LEAF | ECF_COLD); 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) if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)

View File

@ -1950,6 +1950,15 @@ ftms = {
}; };
}; };
ftms = {
name = observable_checkpoint;
values = {
v = 202506;
cxxmin = 26;
extra_cond = "__has_builtin(__builtin_observable_checkpoint)";
};
};
ftms = { ftms = {
name = algorithm_default_value_type; name = algorithm_default_value_type;
values = { values = {

View File

@ -2181,6 +2181,16 @@
#endif /* !defined(__cpp_lib_unreachable) */ #endif /* !defined(__cpp_lib_unreachable) */
#undef __glibcxx_want_unreachable #undef __glibcxx_want_unreachable
#if !defined(__cpp_lib_observable_checkpoint)
# if (__cplusplus > 202302L) && (__has_builtin(__builtin_observable_checkpoint))
# define __glibcxx_observable_checkpoint 202506L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_observable_checkpoint)
# define __cpp_lib_observable_checkpoint 202506L
# endif
# endif
#endif /* !defined(__cpp_lib_observable_checkpoint) && defined(__glibcxx_want_observable_checkpoint) */
#undef __glibcxx_want_observable_checkpoint
#if !defined(__cpp_lib_algorithm_default_value_type) #if !defined(__cpp_lib_algorithm_default_value_type)
# if (__cplusplus > 202302L) # if (__cplusplus > 202302L)
# define __glibcxx_algorithm_default_value_type 202403L # define __glibcxx_algorithm_default_value_type 202403L

View File

@ -98,6 +98,7 @@
#define __glibcxx_want_tuple_element_t #define __glibcxx_want_tuple_element_t
#define __glibcxx_want_tuples_by_type #define __glibcxx_want_tuples_by_type
#define __glibcxx_want_unreachable #define __glibcxx_want_unreachable
#define __glibcxx_want_observable_checkpoint
#define __glibcxx_want_tuple_like #define __glibcxx_want_tuple_like
#define __glibcxx_want_constrained_equality #define __glibcxx_want_constrained_equality
#include <bits/version.h> #include <bits/version.h>
@ -234,6 +235,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
#endif #endif
#ifdef __cpp_lib_observable_checkpoint // C++ >= 26
/// Informs the compiler that prior actions are considered observable.
/**
* This may be used to limit the extent to which optimisations based on the
* assumed unreachability of undefined behaviour can propagate to earlier
* code.
*
* @since C++26
*/
[[__gnu__::__always_inline__]]
inline void
observable_checkpoint() noexcept
{
return __builtin_observable_checkpoint();
}
#endif
_GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION
} // namespace } // namespace

View File

@ -3337,6 +3337,9 @@ export namespace std
#if __cpp_lib_unreachable #if __cpp_lib_unreachable
using std::unreachable; using std::unreachable;
#endif #endif
#if __cpp_lib_observable_checkpoint
using std::observable_checkpoint;
#endif
} }
// <valarray> // <valarray>