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

Reply via email to