On Mon, 17 Nov 2025, 00:14 Iain Sandoe, <[email protected]> wrote: > What we need to do here (and, of course, in the code synthesis > that produces the objects) needs to be interoperable with other > platforms that share ABI. For the present, this means Itanium > and to interoperate with clang and libc++. > > The model we have followed in the development is essentially the > same as the model used for the C++2a edition. However there is some > concern that the read-only data footprint of this is potentially > high and alternate schemes are in discussion with the clang folks. > > Since the layout of the violation object is ABI let's leave this > in experimental until an agreed solution is fixed. > > Remove the cxx2a support at the same time, GCC no longer supports > this mode. > > libstdc++-v3/ChangeLog: > > * include/Makefile.am: Add contract include. > * include/Makefile.in: Regenerate. > * include/std/source_location: Befriend the contract_violation > class so that we can initialise a source_location from an > existing __impl *. > * src/experimental/Makefile.am: Add new contract violation > implementation, remove the old one. > * src/experimental/Makefile.in: Regenerate. > * include/experimental/contract: Removed. > * src/experimental/contract.cc: Removed. > * include/std/contracts: New file. > * src/experimental/contract26.cc: New file. > * testsuite/18_support/contracts/invoke_default_cvh.cc: New test. > * testsuite/18_support/contracts/invoke_default_cvh2.cc: New test. >
Should this define __cpp_lib_contracts and gate the contents of <contracts> behind a preprocessor check for that feature test macro? As written here, including <contracts> in C++98 more will just cause errors (for e.g. 'enum class'). The new test cases are run for c++2a and later, should that be c++26 instead? > Co-Authored-by: Nina Ranns <[email protected]> > Co-Authored-by: Ville Voutilainen <[email protected]> > Signed-off-by: Iain Sandoe <[email protected]> > --- > libstdc++-v3/include/Makefile.am | 2 +- > libstdc++-v3/include/Makefile.in | 2 +- > libstdc++-v3/include/experimental/contract | 83 ---------- > libstdc++-v3/include/std/contracts | 111 +++++++++++++ > libstdc++-v3/include/std/source_location | 10 ++ > libstdc++-v3/src/experimental/Makefile.am | 4 +- > libstdc++-v3/src/experimental/Makefile.in | 6 +- > libstdc++-v3/src/experimental/contract.cc | 78 --------- > libstdc++-v3/src/experimental/contract26.cc | 154 ++++++++++++++++++ > .../contracts/invoke_default_cvh.cc | 40 +++++ > .../contracts/invoke_default_cvh2.cc | 72 ++++++++ > 11 files changed, 394 insertions(+), 168 deletions(-) > delete mode 100644 libstdc++-v3/include/experimental/contract > create mode 100644 libstdc++-v3/include/std/contracts > delete mode 100644 libstdc++-v3/src/experimental/contract.cc > create mode 100644 libstdc++-v3/src/experimental/contract26.cc > create mode 100644 > libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh.cc > create mode 100644 > libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh2.cc > > diff --git a/libstdc++-v3/include/Makefile.am > b/libstdc++-v3/include/Makefile.am > index ae7a7ca9073..7fb238d7a0d 100644 > --- a/libstdc++-v3/include/Makefile.am > +++ b/libstdc++-v3/include/Makefile.am > @@ -32,6 +32,7 @@ std_freestanding = \ > ${std_srcdir}/bit \ > ${std_srcdir}/bitset \ > ${std_srcdir}/concepts \ > + ${std_srcdir}/contracts \ > ${std_srcdir}/coroutine \ > ${std_srcdir}/expected \ > ${std_srcdir}/functional \ > @@ -793,7 +794,6 @@ experimental_headers = \ > ${experimental_srcdir}/array \ > ${experimental_srcdir}/buffer \ > ${experimental_srcdir}/chrono \ > - ${experimental_srcdir}/contract \ > ${experimental_srcdir}/deque \ > ${experimental_srcdir}/executor \ > ${experimental_srcdir}/forward_list \ > diff --git a/libstdc++-v3/include/Makefile.in > b/libstdc++-v3/include/Makefile.in > index f07e2326816..f60f555c690 100644 > --- a/libstdc++-v3/include/Makefile.in > +++ b/libstdc++-v3/include/Makefile.in > @@ -393,6 +393,7 @@ std_freestanding = \ > ${std_srcdir}/bit \ > ${std_srcdir}/bitset \ > ${std_srcdir}/concepts \ > + ${std_srcdir}/contracts \ > ${std_srcdir}/coroutine \ > ${std_srcdir}/expected \ > ${std_srcdir}/functional \ > @@ -1142,7 +1143,6 @@ experimental_headers = \ > ${experimental_srcdir}/array \ > ${experimental_srcdir}/buffer \ > ${experimental_srcdir}/chrono \ > - ${experimental_srcdir}/contract \ > ${experimental_srcdir}/deque \ > ${experimental_srcdir}/executor \ > ${experimental_srcdir}/forward_list \ > diff --git a/libstdc++-v3/include/experimental/contract > b/libstdc++-v3/include/experimental/contract > deleted file mode 100644 > index 8b1be86db57..00000000000 > --- a/libstdc++-v3/include/experimental/contract > +++ /dev/null > @@ -1,83 +0,0 @@ > -// Contracts support header for -*- C++ -*- > - > -// Copyright (C) 2019-2025 Free Software Foundation, Inc. > -// > -// This file is part of GCC. > -// > -// GCC is free software; you can redistribute it and/or modify > -// it under the terms of the GNU General Public License as published by > -// the Free Software Foundation; either version 3, or (at your option) > -// any later version. > -// > -// GCC is distributed in the hope that it will be useful, > -// but WITHOUT ANY WARRANTY; without even the implied warranty of > -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > -// GNU General Public License for more details. > -// > -// Under Section 7 of GPL version 3, you are granted additional > -// permissions described in the GCC Runtime Library Exception, version > -// 3.1, as published by the Free Software Foundation. > - > -// You should have received a copy of the GNU General Public License and > -// a copy of the GCC Runtime Library Exception along with this program; > -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > -// <http://www.gnu.org/licenses/>. > - > -/** @file contract > - * This is a Standard C++ Library header. > - */ > - > -#ifndef _GLIBCXX_CONTRACT > -#define _GLIBCXX_CONTRACT 1 > - > -#ifdef _GLIBCXX_SYSHDR > -#pragma GCC system_header > -#endif > - > -#if __cplusplus >= 201703L > - > -#include <string_view> > -#include <cstdint> > - > -namespace std _GLIBCXX_VISIBILITY(default) > -{ > -_GLIBCXX_BEGIN_NAMESPACE_VERSION > - > -namespace experimental > -{ > - // From P1332 > - enum class contract_violation_continuation_mode { > - never_continue, maybe_continue > - }; > - > - class contract_violation { > - const char* _M_file; > - const char* _M_function; > - const char* _M_comment; > - const char* _M_level; > - const char* _M_role; > - uint_least32_t _M_line; > - signed char _M_continue; > - public: > - // From N4820 > - uint_least32_t line_number() const noexcept { return _M_line; } > - string_view file_name() const noexcept { return _M_file; } > - string_view function_name() const noexcept { return _M_function; } > - string_view comment() const noexcept { return _M_comment; } > - string_view assertion_level() const noexcept { return _M_level; } > - // From P1332 > - string_view assertion_role() const noexcept { return _M_role; } > - contract_violation_continuation_mode continuation_mode() const > noexcept > - { return > static_cast<contract_violation_continuation_mode>(_M_continue); } > - }; > - > -} // namespace experimental > - > -_GLIBCXX_END_NAMESPACE_VERSION > -} // namespace std > - > -// To override the contract violation handler, define > -//void ::handle_contract_violation (const > std::experimental::contract_violation &); > - > -#endif // C++17 > -#endif // _GLIBCXX_CONTRACT > diff --git a/libstdc++-v3/include/std/contracts > b/libstdc++-v3/include/std/contracts > new file mode 100644 > index 00000000000..b528cf3169e > --- /dev/null > +++ b/libstdc++-v3/include/std/contracts > @@ -0,0 +1,111 @@ > +// Contracts support header for -*- C++ -*- > + > +// Copyright (C) 2019-2024 Free Software Foundation, Inc. > 2025 +// > +// This file is part of GCC. > +// > +// GCC is free software; you can redistribute it and/or modify > +// it under the terms of the GNU General Public License as published by > +// the Free Software Foundation; either version 3, or (at your option) > +// any later version. > +// > +// GCC is distributed in the hope that it will be useful, > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +// GNU General Public License for more details. > +// > +// Under Section 7 of GPL version 3, you are granted additional > +// permissions described in the GCC Runtime Library Exception, version > +// 3.1, as published by the Free Software Foundation. > + > +// You should have received a copy of the GNU General Public License and > +// a copy of the GCC Runtime Library Exception along with this program; > +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +// <http://www.gnu.org/licenses/>. > + > +/** @file contracts > + * This is a Standard C++ Library header. > + */ > + > +#ifndef _GLIBCXX_CONTRACTS > +#define _GLIBCXX_CONTRACTS 1 > + > +#pragma GCC system_header > + > +#include <source_location> > +#include <cstdint> > +#include <bits/exception_ptr.h> > + > +namespace std _GLIBCXX_VISIBILITY(default) > +{ > +_GLIBCXX_BEGIN_NAMESPACE_VERSION > + > +namespace contracts +{ > + // From P2900R14 + D3290R3 > + > + enum class assertion_kind : uint16_t { > + pre = 1, > + post = 2, > + assert = 3, > + // From D3290R3 > + manual = 4, > + cassert = 5, > + > + /* Implementation−defined values should have a minimum value of 1000. > */ > + }; > + > + enum class evaluation_semantic : uint16_t { > + ignore = 1, > + observe = 2, > + enforce = 3, > + quick_enforce = 4, > + > + /* Implementation−defined values should have a minimum value of > 1000. */ > + }; > + > + enum class detection_mode : uint16_t { > + unspecified = 0, // From D3290R3 > + predicate_false = 1, > + evaluation_exception = 2, > + > + /* Implementation−defined values should have a minimum value of 1000. > */ > + }; > + > + using __vendor_ext = void; > + > + class contract_violation { > + uint16_t _M_version; > + assertion_kind _M_assertion_kind; > + evaluation_semantic _M_evaluation_semantic; > + detection_mode _M_detection_mode; > + const char* _M_comment; > + const void* _M_src_loc_ptr; > + __vendor_ext* _M_ext; > + > + public: > + // cannot be copied or moved or assigned to > + contract_violation(const contract_violation&) = delete; > + contract_violation& operator=(const contract_violation&) = delete; > + > + assertion_kind kind() const noexcept { return _M_assertion_kind; } > + evaluation_semantic semantic() const noexcept { return > _M_evaluation_semantic; } > + detection_mode mode() const noexcept { return _M_detection_mode; } > + const char* comment() const noexcept { return _M_comment; } > + std::source_location location() const noexcept { > + return std::source_location (_M_src_loc_ptr); > + } > + bool is_terminating () const noexcept { > + return _M_evaluation_semantic == > std::contracts::evaluation_semantic::enforce > + || _M_evaluation_semantic == > std::contracts::evaluation_semantic::quick_enforce; > + } > + }; > + > + void invoke_default_contract_violation_handler(const > contract_violation&) noexcept; > + > +} // namespace contracts > + > +_GLIBCXX_END_NAMESPACE_VERSION > +} // namespace std > + > +#endif // _GLIBCXX_CONTRACTS > diff --git a/libstdc++-v3/include/std/source_location > b/libstdc++-v3/include/std/source_location > index 16df9382fa5..eace9de006e 100644 > --- a/libstdc++-v3/include/std/source_location > +++ b/libstdc++-v3/include/std/source_location > @@ -38,6 +38,10 @@ > namespace std > { > _GLIBCXX_BEGIN_NAMESPACE_VERSION > + namespace contracts > + { > + class contract_violation; > This is not a reserved word before C++26 so should only be declared for C++26 and later. + } > > /// A class that describes a location in source code. > struct source_location > @@ -85,6 +89,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > private: > const __impl* _M_impl = nullptr; > + > + constexpr source_location (const void *__t) > + : _M_impl (static_cast <const __impl*>(__t)) {} > + > + /* To enable use of the source __impl*. */ > + friend class std::contracts::contract_violation; > Likewise. }; > > _GLIBCXX_END_NAMESPACE_VERSION > diff --git a/libstdc++-v3/src/experimental/Makefile.am > b/libstdc++-v3/src/experimental/Makefile.am > index 3ecb76e1cc1..ff4ed46998f 100644 > --- a/libstdc++-v3/src/experimental/Makefile.am > +++ b/libstdc++-v3/src/experimental/Makefile.am > @@ -39,7 +39,7 @@ endif > headers = > > sources = \ > - contract.cc > + contract26.cc > > # vpath % $(top_srcdir)/src/experimental > > @@ -61,7 +61,7 @@ libstdc__exp_la_DEPENDENCIES = \ > # OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden > # as the occasion calls for it. > AM_CXXFLAGS = \ > - -std=gnu++17 -nostdinc++ \ > + -std=gnu++20 -nostdinc++ \ > $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \ > $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \ > $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \ > diff --git a/libstdc++-v3/src/experimental/Makefile.in > b/libstdc++-v3/src/experimental/Makefile.in > index 8cb0acd4e68..ab5c2cc829a 100644 > --- a/libstdc++-v3/src/experimental/Makefile.in > +++ b/libstdc++-v3/src/experimental/Makefile.in > @@ -152,7 +152,7 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" > LTLIBRARIES = $(toolexeclib_LTLIBRARIES) > @ENABLE_FILESYSTEM_TS_TRUE@am__DEPENDENCIES_1 = > $(top_builddir)/src/filesystem/libstdc++fsconvenience.la > @ENABLE_BACKTRACE_TRUE@am__DEPENDENCIES_2 = > $(top_builddir)/src/libbacktrace/libstdc++_libbacktrace.la > -am__objects_1 = contract.lo > +am__objects_1 = contract26.lo > am_libstdc__exp_la_OBJECTS = $(am__objects_1) > libstdc__exp_la_OBJECTS = $(am_libstdc__exp_la_OBJECTS) > AM_V_lt = $(am__v_lt_@AM_V@) > @@ -458,7 +458,7 @@ toolexeclib_LTLIBRARIES = libstdc++exp.la > @ENABLE_BACKTRACE_TRUE@backtrace_lib = > $(top_builddir)/src/libbacktrace/libstdc++_libbacktrace.la > headers = > sources = \ > - contract.cc > + contract26.cc > > > # vpath % $(top_srcdir)/src/experimental > @@ -480,7 +480,7 @@ libstdc__exp_la_DEPENDENCIES = \ > # OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden > # as the occasion calls for it. > AM_CXXFLAGS = \ > - -std=gnu++17 -nostdinc++ \ > + -std=gnu++20 -nostdinc++ \ > $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \ > $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \ > $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \ > diff --git a/libstdc++-v3/src/experimental/contract.cc > b/libstdc++-v3/src/experimental/contract.cc > deleted file mode 100644 > index 06c19df6558..00000000000 > --- a/libstdc++-v3/src/experimental/contract.cc > +++ /dev/null > @@ -1,78 +0,0 @@ > -// -*- C++ -*- std::experimental::contract_violation and friends > - > -// Copyright (C) 2019-2025 Free Software Foundation, Inc. > -// > -// This file is part of GCC. > -// > -// GCC is free software; you can redistribute it and/or modify > -// it under the terms of the GNU General Public License as published by > -// the Free Software Foundation; either version 3, or (at your option) > -// any later version. > -// > -// GCC is distributed in the hope that it will be useful, > -// but WITHOUT ANY WARRANTY; without even the implied warranty of > -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > -// GNU General Public License for more details. > -// > -// Under Section 7 of GPL version 3, you are granted additional > -// permissions described in the GCC Runtime Library Exception, version > -// 3.1, as published by the Free Software Foundation. > - > -// You should have received a copy of the GNU General Public License and > -// a copy of the GCC Runtime Library Exception along with this program; > -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > -// <http://www.gnu.org/licenses/>. > - > -#include <experimental/contract> > -#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE > -# include <iostream> > -#endif > - > -__attribute__ ((weak)) void > -handle_contract_violation (const std::experimental::contract_violation > &violation) > -{ > -#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE > - bool level_default_p = violation.assertion_level() == "default"; > - bool role_default_p = violation.assertion_role() == "default"; > - bool cont_mode_default_p = violation.continuation_mode() > - == > std::experimental::contract_violation_continuation_mode::never_continue; > - > - const char* modes[]{ "off", "on" }; // Must match enumerators in header. > - std::cerr << "contract violation in function " << > violation.function_name() > - << " at " << violation.file_name() << ':' << violation.line_number() > - << ": " << violation.comment(); > - > - const char* delimiter = "\n["; > - > - if (!level_default_p) > - { > - std::cerr << delimiter << "level:" << violation.assertion_level(); > - delimiter = ", "; > - } > - if (!role_default_p) > - { > - std::cerr << delimiter << "role:" << violation.assertion_role(); > - delimiter = ", "; > - } > - if (!cont_mode_default_p) > - { > - std::cerr << delimiter << "continue:" > - << modes[(int)violation.continuation_mode() & 1]; > - delimiter = ", "; > - } > - > - if (delimiter[0] == ',') > - std::cerr << ']'; > - > - std::cerr << std::endl; > -#endif > -} > - > -#if _GLIBCXX_INLINE_VERSION > -// The compiler expects the contract_violation class to be in an > unversioned > -// namespace, so provide a forwarding function with the expected symbol > name. > -extern "C" void > -_Z25handle_contract_violationRKNSt12experimental18contract_violationE > -(const std::experimental::contract_violation &violation) > -{ handle_contract_violation(violation); } > -#endif > diff --git a/libstdc++-v3/src/experimental/contract26.cc > b/libstdc++-v3/src/experimental/contract26.cc > new file mode 100644 > index 00000000000..806cf01a234 > --- /dev/null > +++ b/libstdc++-v3/src/experimental/contract26.cc > @@ -0,0 +1,154 @@ > +// -*- C++ -*- std::experimental::contract_violation and friends > + > +// Copyright (C) 2019-2024 Free Software Foundation, Inc. > 2025 +// > +// This file is part of GCC. > +// > +// GCC is free software; you can redistribute it and/or modify > +// it under the terms of the GNU General Public License as published by > +// the Free Software Foundation; either version 3, or (at your option) > +// any later version. > +// > +// GCC is distributed in the hope that it will be useful, > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +// GNU General Public License for more details. > +// > +// Under Section 7 of GPL version 3, you are granted additional > +// permissions described in the GCC Runtime Library Exception, version > +// 3.1, as published by the Free Software Foundation. > + > +// You should have received a copy of the GNU General Public License and > +// a copy of the GCC Runtime Library Exception along with this program; > +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +// <http://www.gnu.org/licenses/>. > + > +#include <contracts> > +#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE > +# include <iostream> > +# include <cxxabi.h> > +#endif > + > +void __handle_contract_violation(const std::contracts::contract_violation > &violation) noexcept > +{ > +#if _GLIBCXX_HOSTED && _GLIBCXX_VERBOSE > + > + std::cerr << "contract violation in function " << > violation.location().function_name() > + << " at " << violation.location().file_name() << ':' << > violation.location().line() > + << ": " << violation.comment(); > + > + const char* delimiter = "\n["; > + > + std::cerr << delimiter << "assertion_kind:"; > + switch (violation.kind()) > + { > + case std::contracts::assertion_kind::pre: > + std::cerr << " pre"; > + break; > + case std::contracts::assertion_kind::post: > + std::cerr << " post"; > + break; > + case std::contracts::assertion_kind::assert: > + std::cerr << " assert"; > + break; > + default: > + std::cerr << " unknown" << (int) violation.semantic(); > + } > + delimiter = ", "; > + > + std::cerr << delimiter << "semantic:"; > + switch (violation.semantic()) > + { > + case std::contracts::evaluation_semantic::enforce: > + std::cerr << " enforce"; > + break; > + case std::contracts::evaluation_semantic::observe: > + std::cerr << " observe"; > + break; > + default: > + std::cerr << " unknown" << (int) violation.semantic(); > + } > + delimiter = ", "; > + > + std::cerr << delimiter << "mode:"; > + switch (violation.mode()) > + { > + case std::contracts::detection_mode::predicate_false: > + std::cerr << " predicate_false"; > + break; > + case std::contracts::detection_mode::evaluation_exception: > + std::cerr << " evaluation_exception"; > + break; > + default: > + std::cerr << "unknown"; > + } > + delimiter = ", "; > + > + if (violation.mode() == > std::contracts::detection_mode::evaluation_exception) > + { > + /* Based on the impl. in vterminate.cc. */ > + std::type_info *t = __cxxabiv1::__cxa_current_exception_type(); > + if (t) > + { > + int status = -1; > + char *dem = 0; > + // Note that "name" is the mangled name. > + char const *name = t->name(); > + dem = __cxxabiv1::__cxa_demangle(name, 0, 0, &status); > + std::cerr << ": threw an instance of '"; > + std::cerr << ( status == 0 ? dem : name) << "'"; > + } > + else > + std::cerr << ": threw an unknown type"; > + } > + > + std::cerr << delimiter << "terminating:" > + << (violation.is_terminating () ? " yes" : " no"); > + > + if (delimiter[0] == ',') > + std::cerr << ']'; > + > + std::cerr << std::endl; > +#endif > +} > + > +namespace std _GLIBCXX_VISIBILITY(default) > +{ > +_GLIBCXX_BEGIN_NAMESPACE_VERSION > + > +namespace contracts > +{ > + > +void invoke_default_contract_violation_handler(const > std::contracts::contract_violation& violation) noexcept > +{ > + return __handle_contract_violation(violation); > +} > + > +} > +} > + > +__attribute__ ((weak)) void > +handle_contract_violation (const std::contracts::contract_violation > &violation) > +{ > + return __handle_contract_violation(violation); > +} > + > +#if _GLIBCXX_INLINE_VERSION > +// The compiler expects the contract_violation class to be in an > unversioned > +// namespace, so provide a forwarding function with the expected symbol > name. > +extern "C" void > +_Z25handle_contract_violationRKNSt9contracts18contract_violationE > +(const std::contracts::contract_violation &violation) > +{ handle_contract_violation(violation); } > + > +extern "C" void > +_Z27__handle_contract_violationRKNSt9contracts18contract_violationE > +(const std::contracts::contract_violation &violation) > +{ __handle_contract_violation(violation); } > + > +extern "C" void > > +_Z41invoke_default_contract_violation_handlerRKNSt9contracts18contract_violationE > +(const std::contracts::contract_violation &violation) > +{ invoke_default_contract_violation_handler(violation); } > + > +#endif > diff --git > a/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh.cc > b/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh.cc > new file mode 100644 > index 00000000000..5f1f0e6f645 > --- /dev/null > +++ b/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh.cc > @@ -0,0 +1,40 @@ > +// Copyright (C) 2020-2025 Free Software Foundation, Inc. > +// > +// This file is part of the GNU ISO C++ Library. This library is free > +// software; you can redistribute it and/or modify it under the > +// terms of the GNU General Public License as published by the > +// Free Software Foundation; either version 3, or (at your option) > +// any later version. > + > +// This library is distributed in the hope that it will be useful, > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +// GNU General Public License for more details. > + > +// You should have received a copy of the GNU General Public License along > +// with this library; see the file COPYING3. If not see > +// <http://www.gnu.org/licenses/>. > + > +// { dg-options "-fcontracts -fcontract-evaluation-semantic=observe" } > +// { dg-do run { target c++2a } } + > +#include <contracts> > +#include <testsuite_hooks.h> > + > +bool custom_called = false; > + > + > +void handle_contract_violation(const std::contracts::contract_violation& > v) > +{ > + invoke_default_contract_violation_handler(v); > + custom_called = true; > +} > + > +void f(int i) pre (i>10) {}; > + > +int main() > +{ > + f(0); > + VERIFY(custom_called); > +} > +// { dg-output "contract violation in function void f.int. at > .*(\n|\r\n|\r)" } > diff --git > a/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh2.cc > b/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh2.cc > new file mode 100644 > index 00000000000..9e5c289b71e > --- /dev/null > +++ b/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh2.cc > @@ -0,0 +1,72 @@ > +// Copyright (C) 2025 Free Software Foundation, Inc. > +// > +// This file is part of the GNU ISO C++ Library. This library is free > +// software; you can redistribute it and/or modify it under the > +// terms of the GNU General Public License as published by the > +// Free Software Foundation; either version 3, or (at your option) > +// any later version. > + > +// This library is distributed in the hope that it will be useful, > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +// GNU General Public License for more details. > + > +// You should have received a copy of the GNU General Public License along > +// with this library; see the file COPYING3. If not see > +// <http://www.gnu.org/licenses/>. > + > +// check that default contract violation is not invoked if not explicitly > invoked > +// { dg-options "-fcontracts -fcontract-evaluation-semantic=observe" } > +// { dg-do run { target c++2a } } > + > +#include <contracts> > +#include <testsuite_hooks.h> > +#include <iostream> > +#include <sstream> > + > + > +struct checking_buf > + : public std::streambuf > +{ > + bool written = false; > + > + checking_buf() = default; > + > + virtual int_type > + overflow(int_type) > + { > + written = true; > + return int_type(); > + } > + > + std::streamsize xsputn(const char* s, std::streamsize count) > + { > + written = true; > + return count; > + } > + > +}; > + > + > +bool custom_called = false; > + > + > +void handle_contract_violation(const std::contracts::contract_violation& > v) > +{ > + custom_called = true; > +} > + > +void f(int i) pre (i>10) {}; > + > +int main() > +{ > + auto save_buf = std::cerr.rdbuf(); > + checking_buf buf; > + std::cerr.rdbuf(&buf); > + > + f(0); > + std::cerr.rdbuf(save_buf); > + VERIFY(!buf.written); > + return 0; > +} > + > -- > 2.39.5 (Apple Git-154) > >
