${std_srcdir}/bit \
${std_srcdir}/bitset \
${std_srcdir}/concepts \
+ ${std_srcdir}/contracts \
${std_srcdir}/coroutine \
${std_srcdir}/expected \
${std_srcdir}/functional \
${experimental_srcdir}/array \
${experimental_srcdir}/buffer \
${experimental_srcdir}/chrono \
- ${experimental_srcdir}/contract \
${experimental_srcdir}/deque \
${experimental_srcdir}/executor \
${experimental_srcdir}/forward_list \
${std_srcdir}/bit \
${std_srcdir}/bitset \
${std_srcdir}/concepts \
+ ${std_srcdir}/contracts \
${std_srcdir}/coroutine \
${std_srcdir}/expected \
${std_srcdir}/functional \
${experimental_srcdir}/array \
${experimental_srcdir}/buffer \
${experimental_srcdir}/chrono \
- ${experimental_srcdir}/contract \
${experimental_srcdir}/deque \
${experimental_srcdir}/executor \
${experimental_srcdir}/forward_list \
};
};
+ftms = {
+ name = contracts;
+ values = {
+ v = 202502;
+ cxxmin = 26;
+ extra_cond = "__cpp_contracts >= 202502L";
+ };
+};
+
// Standard test specifications.
stds[97] = ">= 199711L";
stds[03] = ">= 199711L";
#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
+++ /dev/null
-// 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
#endif
#if __cplusplus > 202302L
+#include <contracts>
#include <debugging>
#include <inplace_vector>
#include <meta>
--- /dev/null
+// Contracts support header for -*- C++ -*-
+
+// 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 <bits/exception_ptr.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace contracts
+{
+ // From P2900R14
+
+ enum class assertion_kind : __UINT16_TYPE__ {
+ pre = 1,
+ post = 2,
+ assert = 3,
+
+ /* Implementation−defined values should have a minimum value of 1000. */
+ };
+
+ enum class evaluation_semantic : __UINT16_TYPE__ {
+ ignore = 1,
+ observe = 2,
+ enforce = 3,
+ quick_enforce = 4,
+
+ /* Implementation−defined values should have a minimum value of 1000. */
+ };
+
+ enum class detection_mode : __UINT16_TYPE__ {
+ predicate_false = 1,
+ evaluation_exception = 2,
+
+ /* Implementation−defined values should have a minimum value of 1000. */
+ };
+
+ using __vendor_ext = void;
+
+ class contract_violation {
+ __UINT16_TYPE__ _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
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
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
}
#endif
+// 17.10.1 <contracts>
+#if __cpp_lib_contracts
+export namespace std::contracts
+{
+ using std::contracts::assertion_kind;
+ using std::contracts::evaluation_semantic;
+ using std::contracts::detection_mode;
+ using std::contracts::contract_violation;
+ using std::contracts::invoke_default_violation_handler;
+}
+#endif // __cpp_lib_contracts
+
// 17.12.2 <coroutine>
#if __cpp_lib_coroutine
export namespace std
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 = \
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@)
@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 \
# 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) \
.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:
+++ /dev/null
-// -*- 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
--- /dev/null
+// -*- C++ -*- std::contracts::contract_violation and friends
+
+// 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/>.
+
+#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
--- /dev/null
+// { 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)" }
--- /dev/null
+// 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;
+}
+