On Tue, 27 Jan 2026 at 00:33 +0000, Iain Sandoe wrote:
From: Nina Ranns <[email protected]>

Changes since v3

- rebased onto r16-7033-gfb6a2e3f1fa842 (includes reflection changes).

Changes since v2

- rebased onto r16-6757-g460edeb8bea11e (includes new year (c) change).

Changes since v1
- addressed Jonathan's review comments
- fixed a merge error in the removal of C++2a code.
- rebased onto r16-5785-g3b30d09ac7bbf8 (includes change to default to
  C++20).

--- 8< ---

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/bits/version.def: Add ftm for contracts.
        * include/bits/version.h: 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.

Co-Authored-by: Iain Sandoe <[email protected]>
Co-Authored-by: Ville Voutilainen <[email protected]>
Signed-off-by: Nina Ranns <[email protected]>
---
libstdc++-v3/include/Makefile.am              |   2 +-
libstdc++-v3/include/Makefile.in              |   2 +-
libstdc++-v3/include/bits/version.def         |   9 +
libstdc++-v3/include/bits/version.h           |  10 ++
libstdc++-v3/include/experimental/contract    |  83 ---------
libstdc++-v3/include/std/contracts            | 116 +++++++++++++
libstdc++-v3/include/std/source_location      |  14 ++
libstdc++-v3/src/experimental/Makefile.am     |   8 +-
libstdc++-v3/src/experimental/Makefile.in     |  15 +-
libstdc++-v3/src/experimental/contract.cc     |  78 ---------
libstdc++-v3/src/experimental/contract26.cc   | 157 ++++++++++++++++++
.../contracts/invoke_default_cvh.cc           |  40 +++++
.../contracts/invoke_default_cvh2.cc          |  72 ++++++++
13 files changed, 437 insertions(+), 169 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 dd1cc1ceb2f4..e6ac312ac7a4 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 \
@@ -801,7 +802,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 1dfb40385f5d..b2e40c4d313f 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 \
@@ -1150,7 +1151,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/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 8bb3e8d185f3..a1672b6be49f 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -2272,6 +2272,15 @@ ftms = {
  };
};

+ftms = {
+  name = contracts;
+  values = {
+    v = 202502;
+    cxxmin = 26;
+    extra_cond = "__cpp_contracts >= 202502L";
+  };
+};
+
// Standard test specifications.
stds[97] = ">= 199711L";
stds[03] = ">= 199711L";
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 107b19002d7a..dccc2a6c0df6 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2546,4 +2546,14 @@
#endif /* !defined(__cpp_lib_is_implicit_lifetime) */
#undef __glibcxx_want_is_implicit_lifetime

+#if !defined(__cpp_lib_contracts)
+# if (__cplusplus >  202302L) && (__cpp_contracts >= 202502L)
+#  define __glibcxx_contracts 202502L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_contracts)
+#   define __cpp_lib_contracts 202502L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_contracts) */
+#undef __glibcxx_want_contracts
+
#undef __glibcxx_want_all
diff --git a/libstdc++-v3/include/experimental/contract 
b/libstdc++-v3/include/experimental/contract
deleted file mode 100644
index 697045e0a2ba..000000000000
--- a/libstdc++-v3/include/experimental/contract
+++ /dev/null
@@ -1,83 +0,0 @@
-// Contracts support header for -*- C++ -*-
-
-// Copyright (C) 2019-2026 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 000000000000..3ca56481f1f9
--- /dev/null
+++ b/libstdc++-v3/include/std/contracts
@@ -0,0 +1,116 @@
+// Contracts support header for -*- C++ -*-
+
+// Copyright (C) 2025 Free Software Foundation, Inc.

As discussed in chat, this should be:

// Copyright The GNU Toolchain Authors.

+//
+// 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
+
+#define __glibcxx_want_contracts
+#include <bits/version.h>
+
+#ifdef __cpp_lib_contracts
+#include <source_location>
+#include <cstdint>

We usually try to avoid including <cstdint> and use __UINT16_TYPE__
instead, so that we don't pollute the global namespace with C
declarations.

But I'm starting to wonder if that's causing unnecessary pain, because
*nobody* ever remembers to include <cstdint> or <stdint.h>, and if
they do, they include the wrong one (i.e. include <cstdint> then don't
use std:: qualification).

+#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 {

assertion_kind and the other public names in this file should be
exported from the 'std' modules, which is done by adding them to
src/c++23/std.cc.in -- and for that to work we need to include
<contracts> in include/precompiled/stdc++.h (at the bottom with other
C++26 headers).

+    pre = 1,
+    post = 2,
+    assert = 3,
+    // From D3290R3
+    manual = 4,
+    cassert = 5,

What's the status of this paper? It's not part of C++26 so do we want
to use '__manual' and '__cassert# for now, or put these enumerators
behind #ifndef __STRICT_ANSI__?

(We can't guard them with #if __cplusplus > 202400L because there's no
-std=c++29 yet, so they'd be unusable).


+
+    /* 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

Same question here.

+    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 // __cpp_lib_contracts
+#endif // _GLIBCXX_CONTRACTS
diff --git a/libstdc++-v3/include/std/source_location 
b/libstdc++-v3/include/std/source_location
index ca09e980e172..3a631c31c1e3 100644
--- a/libstdc++-v3/include/std/source_location
+++ b/libstdc++-v3/include/std/source_location
@@ -38,6 +38,12 @@
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+#ifdef __cpp_lib_contracts
+  namespace contracts
+  {
+    class contract_violation;
+  }
+#endif // __cpp_lib_contracts

  /// A class that describes a location in source code.
  struct source_location
@@ -85,6 +91,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION

  private:
    const __impl* _M_impl = nullptr;
+
+    constexpr source_location (const void *__t)
+      : _M_impl (static_cast <const __impl*>(__t)) {}
+
+#ifdef __cpp_lib_contracts
+    /* To enable use of the source __impl*.  */
+    friend class std::contracts::contract_violation;
+#endif // __cpp_lib_contracts
  };

_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/src/experimental/Makefile.am 
b/libstdc++-v3/src/experimental/Makefile.am
index e6d41cf66eb2..e428aef23c04 100644
--- a/libstdc++-v3/src/experimental/Makefile.am
+++ b/libstdc++-v3/src/experimental/Makefile.am
@@ -39,10 +39,16 @@ endif
headers =

sources = \
-       contract.cc
+       contract26.cc

# vpath % $(top_srcdir)/src/experimental

+
+contract26.lo: contract26.cc
+       $(LTCXXCOMPILE) -std=gnu++26 -fcontracts -c $<
+contract26.o: contract26.cc
+       $(CXXCOMPILE) -std=gnu++26 -fcontracts -c $<
+
libstdc__exp_la_SOURCES = $(sources)

libstdc__exp_la_LIBADD = \
diff --git a/libstdc++-v3/src/experimental/Makefile.in 
b/libstdc++-v3/src/experimental/Makefile.in
index 8cb0acd4e68b..a9248197f8c7 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,10 +458,8 @@ 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
libstdc__exp_la_SOURCES = $(sources)
libstdc__exp_la_LIBADD = \
        $(top_builddir)/src/c++23/libc++23convenience.la \
@@ -480,7 +478,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) \
@@ -808,6 +806,13 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES
.PRECIOUS: Makefile


+# vpath % $(top_srcdir)/src/experimental
+
+contract26.lo: contract26.cc
+       $(LTCXXCOMPILE) -std=gnu++26 -fcontracts -c $<
+contract26.o: contract26.cc
+       $(CXXCOMPILE) -std=gnu++26 -fcontracts -c $<
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/libstdc++-v3/src/experimental/contract.cc 
b/libstdc++-v3/src/experimental/contract.cc
deleted file mode 100644
index 35ae7148234d..000000000000
--- a/libstdc++-v3/src/experimental/contract.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// -*- C++ -*- std::experimental::contract_violation and friends
-
-// Copyright (C) 2019-2026 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 000000000000..b96e40b66efb
--- /dev/null
+++ b/libstdc++-v3/src/experimental/contract26.cc
@@ -0,0 +1,157 @@
+// -*- C++ -*- std::experimental::contract_violation and friends

s/experimental/contracts/

+
+// Copyright (C) 2025 Free Software Foundation, Inc.

Same change as to the header.

+//
+// 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>
+
+#ifdef __cpp_lib_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
+#endif // __cpp_lib_contracts
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 000000000000..373f6b77542e
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/contracts/invoke_default_cvh.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.

As per
https://gcc.gnu.org/onlinedocs/libstdc++/manual/test.html#test.new_tests
we don't bother with copyright and licence notices in new libstdc++
tests, they're rarely interesting or legally significant.

+//
+// 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++26 } }
+
+#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 000000000000..f2c7fb29fb3d
--- /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++26 } }
+
+#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.50.1 (Apple Git-155)



Reply via email to