[RFA] libstdc++: add experimental Contracts support

Message ID 20221103195750.2113734-1-jason@redhat.com
State Committed
Headers
Series [RFA] libstdc++: add experimental Contracts support |

Commit Message

Jason Merrill Nov. 3, 2022, 7:57 p.m. UTC
  Tested x86_64-pc-linux-gnu.  OK for trunk?

-- >8 --

This patch adds the library support for the experimental C++ Contracts
implementation.  This now consists only of a default definition of the
violation handler, which users can override through defining their own
version.  To avoid ABI stability problems with libstdc++.so this is added to
a separate -lstdc++exp static library, which the driver knows to add when it
sees -fcontracts.

libstdc++-v3/ChangeLog:

	* acinclude.m4 (glibcxx_SUBDIRS): Add src/experimental.
	* include/Makefile.am (experimental_headers): Add contract.
	* include/Makefile.in: Regenerate.
	* src/Makefile.am (SUBDIRS): Add experimental.
	* src/Makefile.in: Regenerate.
	* configure: Regenerate.
	* src/experimental/contract.cc: New file.
	* src/experimental/Makefile.am: New file.
	* src/experimental/Makefile.in: New file.
	* include/experimental/contract: New file.
---
 libstdc++-v3/src/experimental/contract.cc  |  41 ++
 libstdc++-v3/acinclude.m4                  |   2 +-
 libstdc++-v3/include/Makefile.am           |   1 +
 libstdc++-v3/include/Makefile.in           |   1 +
 libstdc++-v3/src/Makefile.am               |   3 +-
 libstdc++-v3/src/Makefile.in               |   6 +-
 libstdc++-v3/src/experimental/Makefile.am  |  96 +++
 libstdc++-v3/src/experimental/Makefile.in  | 796 +++++++++++++++++++++
 libstdc++-v3/include/experimental/contract |  84 +++
 9 files changed, 1026 insertions(+), 4 deletions(-)
 create mode 100644 libstdc++-v3/src/experimental/contract.cc
 create mode 100644 libstdc++-v3/src/experimental/Makefile.am
 create mode 100644 libstdc++-v3/src/experimental/Makefile.in
 create mode 100644 libstdc++-v3/include/experimental/contract


base-commit: a4cd2389276a30c39034a83d640ce68fa407bac1
prerequisite-patch-id: 329bc16a88dc9a3b13cd3fcecb3678826cc592dc
  

Comments

Jonathan Wakely Nov. 18, 2022, 6:17 p.m. UTC | #1
On 03/11/22 15:57 -0400, Jason Merrill wrote:
>Tested x86_64-pc-linux-gnu.  OK for trunk?
>
>-- >8 --
>
>This patch adds the library support for the experimental C++ Contracts
>implementation.  This now consists only of a default definition of the
>violation handler, which users can override through defining their own
>version.  To avoid ABI stability problems with libstdc++.so this is added to
>a separate -lstdc++exp static library, which the driver knows to add when it
>sees -fcontracts.
>
>libstdc++-v3/ChangeLog:
>
>	* acinclude.m4 (glibcxx_SUBDIRS): Add src/experimental.
>	* include/Makefile.am (experimental_headers): Add contract.
>	* include/Makefile.in: Regenerate.
>	* src/Makefile.am (SUBDIRS): Add experimental.
>	* src/Makefile.in: Regenerate.
>	* configure: Regenerate.
>	* src/experimental/contract.cc: New file.
>	* src/experimental/Makefile.am: New file.
>	* src/experimental/Makefile.in: New file.
>	* include/experimental/contract: New file.
>---
> libstdc++-v3/src/experimental/contract.cc  |  41 ++
> libstdc++-v3/acinclude.m4                  |   2 +-
> libstdc++-v3/include/Makefile.am           |   1 +
> libstdc++-v3/include/Makefile.in           |   1 +
> libstdc++-v3/src/Makefile.am               |   3 +-
> libstdc++-v3/src/Makefile.in               |   6 +-
> libstdc++-v3/src/experimental/Makefile.am  |  96 +++
> libstdc++-v3/src/experimental/Makefile.in  | 796 +++++++++++++++++++++
> libstdc++-v3/include/experimental/contract |  84 +++
> 9 files changed, 1026 insertions(+), 4 deletions(-)
> create mode 100644 libstdc++-v3/src/experimental/contract.cc
> create mode 100644 libstdc++-v3/src/experimental/Makefile.am
> create mode 100644 libstdc++-v3/src/experimental/Makefile.in
> create mode 100644 libstdc++-v3/include/experimental/contract
>
>
>base-commit: a4cd2389276a30c39034a83d640ce68fa407bac1
>prerequisite-patch-id: 329bc16a88dc9a3b13cd3fcecb3678826cc592dc
>
>diff --git a/libstdc++-v3/src/experimental/contract.cc b/libstdc++-v3/src/experimental/contract.cc
>new file mode 100644
>index 00000000000..b9b72cd7df0
>--- /dev/null
>+++ b/libstdc++-v3/src/experimental/contract.cc
>@@ -0,0 +1,41 @@
>+// -*- C++ -*- std::experimental::contract_violation and friends
>+// Copyright (C) 1994-2022 Free Software Foundation, Inc.

Copy&paste from an old file? I don't think this uses anything
existing, should be just 2022.

>+//
>+// 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>
>+#include <iostream>
>+
>+__attribute__ ((weak)) void
>+handle_contract_violation (const std::experimental::contract_violation &violation)
>+{
>+  std::cerr << "default std::handle_contract_violation called: " << std::endl

No need for flushing with endl here, just \n please.

>+    << " " << violation.file_name()
>+    << " " << violation.line_number()
>+    << " " << violation.function_name()
>+    << " " << violation.comment()
>+    << " " << violation.assertion_level()
>+    << " " << violation.assertion_role()
>+    << " " << (int)violation.continuation_mode()
>+    << std::endl;

And this will flush too, which typically isn't needed for stderr
because it's unbuffered. But somebody could have fiddled with cerr, so
doing this final flush seems OK.

>+}
>+
>diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
>index 6f672924a73..baf01913a90 100644
>--- a/libstdc++-v3/acinclude.m4
>+++ b/libstdc++-v3/acinclude.m4
>@@ -49,7 +49,7 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [
>   # Keep these sync'd with the list in Makefile.am.  The first provides an
>   # expandable list at autoconf time; the second provides an expandable list
>   # (i.e., shell variable) at configure time.
>-  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 src/c++17 src/c++20 src/filesystem src/libbacktrace doc po testsuite python])
>+  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 src/c++17 src/c++20 src/filesystem src/libbacktrace src/experimental doc po testsuite python])
>   SUBDIRS='glibcxx_SUBDIRS'
>
>   # These need to be absolute paths, yet at the same time need to
>diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
>index 96137a6621a..a6f9912cb9b 100644
>--- a/libstdc++-v3/include/Makefile.am
>+++ b/libstdc++-v3/include/Makefile.am
>@@ -769,6 +769,7 @@ 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/src/Makefile.am b/libstdc++-v3/src/Makefile.am
>index b83c222d51d..6f08068326d 100644
>--- a/libstdc++-v3/src/Makefile.am
>+++ b/libstdc++-v3/src/Makefile.am
>@@ -37,7 +37,7 @@ backtrace_supported_h =
> endif
>
> ## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
>-SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir)
>+SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) experimental
>
> # Cross compiler support.
> if VTV_CYGMIN
>@@ -75,6 +75,7 @@ endif
> if ENABLE_BACKTRACE
> vpath % $(top_srcdir)/src/libbacktrace
> endif
>+vpath % $(top_srcdir)/src/experimental
>
> if GLIBCXX_LDBL_COMPAT
> ldbl_compat_sources = compatibility-ldbl.cc
>diff --git a/libstdc++-v3/src/experimental/Makefile.am b/libstdc++-v3/src/experimental/Makefile.am
>new file mode 100644
>index 00000000000..a1c2f62a518
>--- /dev/null
>+++ b/libstdc++-v3/src/experimental/Makefile.am
>@@ -0,0 +1,96 @@
>+## Makefile for experimental additions to the GNU C++ Standard library.
>+##
>+## Copyright (C) 2014-2022 Free Software Foundation, Inc.
>+##
>+## Process this file with automake to produce Makefile.in.
>+##
>+## 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.
>+##
>+## You should have received a copy of the GNU General Public License
>+## along with GCC; see the file COPYING3.  If not see
>+## <http://www.gnu.org/licenses/>.
>+
>+include $(top_srcdir)/fragment.am
>+
>+toolexeclib_LTLIBRARIES = libstdc++exp.la
>+
>+headers =
>+
>+sources = \
>+	contract.cc
>+
>+# vpath % $(top_srcdir)/src/experimental
>+
>+libstdc__exp_la_SOURCES = $(sources)
>+
>+# AM_CXXFLAGS needs to be in each subdirectory so that it can be
>+# modified in a per-library or per-sub-library way.  Need to manually
>+# set this option because CONFIG_CXXFLAGS has to be after
>+# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
>+# as the occasion calls for it.
>+AM_CXXFLAGS = \
>+	-std=gnu++17 -nostdinc++ \
>+	$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
>+	$(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
>+	$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \
>+	-fimplicit-templates
>+
>+AM_MAKEFLAGS = \
>+	"gxx_include_dir=$(gxx_include_dir)"
>+
>+# Libtool notes
>+
>+# 1) In general, libtool expects an argument such as `--tag=CXX' when
>+# using the C++ compiler, because that will enable the settings
>+# detected when C++ support was being configured.  However, when no
>+# such flag is given in the command line, libtool attempts to figure
>+# it out by matching the compiler name in each configuration section
>+# against a prefix of the command line.  The problem is that, if the
>+# compiler name and its initial flags stored in the libtool
>+# configuration file don't match those in the command line, libtool
>+# can't decide which configuration to use, and it gives up.  The
>+# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
>+# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
>+# attempt to infer which configuration to use.
>+#
>+# The second tag argument, `--tag disable-shared` means that libtool
>+# only compiles each source once, for static objects. In actuality,
>+# glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
>+# the libtool command that is used create the object, which is
>+# suitable for shared libraries.  The `--tag disable-shared` must be
>+# placed after --tag CXX lest things CXX undo the affect of
>+# disable-shared.
>+
>+# 2) Need to explicitly set LTCXXCOMPILE so that EXTRA_CXX_FLAGS is
>+# last. (That way, things like -O2 passed down from the toplevel can
>+# be overridden by --enable-debug.)
>+LTCXXCOMPILE = \
>+	$(LIBTOOL) --tag CXX --tag disable-shared \
>+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
>+	--mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
>+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(EXTRA_CXX_FLAGS)
>+
>+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
>+
>+# 3) We'd have a problem when building the shared libstdc++ object if
>+# the rules automake generates would be used.  We cannot allow g++ to
>+# be used since this would add -lstdc++ to the link line which of
>+# course is problematic at this point.  So, we get the top-level
>+# directory to configure libstdc++-v3 to use gcc as the C++
>+# compilation driver.
>+CXXLINK = \
>+	$(LIBTOOL) --tag CXX --tag disable-shared \
>+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
>+	--mode=link $(CXX) \
>+	$(VTV_CXXLINKFLAGS) \
>+	$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
>diff --git a/libstdc++-v3/include/experimental/contract b/libstdc++-v3/include/experimental/contract
>new file mode 100644
>index 00000000000..16f3fd5fd5a
>--- /dev/null
>+++ b/libstdc++-v3/include/experimental/contract
>@@ -0,0 +1,82 @@
>+// Contracts support header for -*- C++ -*-
>+
>+// Copyright (C) 1995-2022 Free Software Foundation, Inc.

Just 2022 again (or earlier if this is based on Lock3 code contributed
earilier? but not 1995 I think!)

>+// 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
>+
>+#pragma GCC system_header
>+
>+#if __cplusplus >= 201703L
>+
>+#include <bits/c++config.h>

This is included by <string_view> so not needed here.

OK for trunk with those tweaks, thanks.



>+#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
  
Jason Merrill Nov. 19, 2022, 2:40 a.m. UTC | #2
On 11/18/22 13:17, Jonathan Wakely wrote:
> On 03/11/22 15:57 -0400, Jason Merrill wrote:
>> Tested x86_64-pc-linux-gnu.  OK for trunk?
>>
>> -- >8 --
>>
>> This patch adds the library support for the experimental C++ Contracts
>> implementation.  This now consists only of a default definition of the
>> violation handler, which users can override through defining their own
>> version.  To avoid ABI stability problems with libstdc++.so this is 
>> added to
>> a separate -lstdc++exp static library, which the driver knows to add 
>> when it
>> sees -fcontracts.
>>
>> libstdc++-v3/ChangeLog:
>>
>>     * acinclude.m4 (glibcxx_SUBDIRS): Add src/experimental.
>>     * include/Makefile.am (experimental_headers): Add contract.
>>     * include/Makefile.in: Regenerate.
>>     * src/Makefile.am (SUBDIRS): Add experimental.
>>     * src/Makefile.in: Regenerate.
>>     * configure: Regenerate.
>>     * src/experimental/contract.cc: New file.
>>     * src/experimental/Makefile.am: New file.
>>     * src/experimental/Makefile.in: New file.
>>     * include/experimental/contract: New file.
>> ---
>> libstdc++-v3/src/experimental/contract.cc  |  41 ++
>> libstdc++-v3/acinclude.m4                  |   2 +-
>> libstdc++-v3/include/Makefile.am           |   1 +
>> libstdc++-v3/include/Makefile.in           |   1 +
>> libstdc++-v3/src/Makefile.am               |   3 +-
>> libstdc++-v3/src/Makefile.in               |   6 +-
>> libstdc++-v3/src/experimental/Makefile.am  |  96 +++
>> libstdc++-v3/src/experimental/Makefile.in  | 796 +++++++++++++++++++++
>> libstdc++-v3/include/experimental/contract |  84 +++
>> 9 files changed, 1026 insertions(+), 4 deletions(-)
>> create mode 100644 libstdc++-v3/src/experimental/contract.cc
>> create mode 100644 libstdc++-v3/src/experimental/Makefile.am
>> create mode 100644 libstdc++-v3/src/experimental/Makefile.in
>> create mode 100644 libstdc++-v3/include/experimental/contract
>>
>>
>> base-commit: a4cd2389276a30c39034a83d640ce68fa407bac1
>> prerequisite-patch-id: 329bc16a88dc9a3b13cd3fcecb3678826cc592dc
>>
>> diff --git a/libstdc++-v3/src/experimental/contract.cc 
>> b/libstdc++-v3/src/experimental/contract.cc
>> new file mode 100644
>> index 00000000000..b9b72cd7df0
>> --- /dev/null
>> +++ b/libstdc++-v3/src/experimental/contract.cc
>> @@ -0,0 +1,41 @@
>> +// -*- C++ -*- std::experimental::contract_violation and friends
>> +// Copyright (C) 1994-2022 Free Software Foundation, Inc.
> 
> Copy&paste from an old file? I don't think this uses anything
> existing, should be just 2022.
> 
>> +//
>> +// 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>
>> +#include <iostream>
>> +
>> +__attribute__ ((weak)) void
>> +handle_contract_violation (const 
>> std::experimental::contract_violation &violation)
>> +{
>> +  std::cerr << "default std::handle_contract_violation called: " << 
>> std::endl
> 
> No need for flushing with endl here, just \n please.
> 
>> +    << " " << violation.file_name()
>> +    << " " << violation.line_number()
>> +    << " " << violation.function_name()
>> +    << " " << violation.comment()
>> +    << " " << violation.assertion_level()
>> +    << " " << violation.assertion_role()
>> +    << " " << (int)violation.continuation_mode()
>> +    << std::endl;
> 
> And this will flush too, which typically isn't needed for stderr
> because it's unbuffered. But somebody could have fiddled with cerr, so
> doing this final flush seems OK.
> 
>> +}
>> +
>> diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
>> index 6f672924a73..baf01913a90 100644
>> --- a/libstdc++-v3/acinclude.m4
>> +++ b/libstdc++-v3/acinclude.m4
>> @@ -49,7 +49,7 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [
>>   # Keep these sync'd with the list in Makefile.am.  The first 
>> provides an
>>   # expandable list at autoconf time; the second provides an 
>> expandable list
>>   # (i.e., shell variable) at configure time.
>> -  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 
>> src/c++11 src/c++17 src/c++20 src/filesystem src/libbacktrace doc po 
>> testsuite python])
>> +  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 
>> src/c++11 src/c++17 src/c++20 src/filesystem src/libbacktrace 
>> src/experimental doc po testsuite python])
>>   SUBDIRS='glibcxx_SUBDIRS'
>>
>>   # These need to be absolute paths, yet at the same time need to
>> diff --git a/libstdc++-v3/include/Makefile.am 
>> b/libstdc++-v3/include/Makefile.am
>> index 96137a6621a..a6f9912cb9b 100644
>> --- a/libstdc++-v3/include/Makefile.am
>> +++ b/libstdc++-v3/include/Makefile.am
>> @@ -769,6 +769,7 @@ 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/src/Makefile.am b/libstdc++-v3/src/Makefile.am
>> index b83c222d51d..6f08068326d 100644
>> --- a/libstdc++-v3/src/Makefile.am
>> +++ b/libstdc++-v3/src/Makefile.am
>> @@ -37,7 +37,7 @@ backtrace_supported_h =
>> endif
>>
>> ## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
>> -SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir)
>> +SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) 
>> experimental
>>
>> # Cross compiler support.
>> if VTV_CYGMIN
>> @@ -75,6 +75,7 @@ endif
>> if ENABLE_BACKTRACE
>> vpath % $(top_srcdir)/src/libbacktrace
>> endif
>> +vpath % $(top_srcdir)/src/experimental
>>
>> if GLIBCXX_LDBL_COMPAT
>> ldbl_compat_sources = compatibility-ldbl.cc
>> diff --git a/libstdc++-v3/src/experimental/Makefile.am 
>> b/libstdc++-v3/src/experimental/Makefile.am
>> new file mode 100644
>> index 00000000000..a1c2f62a518
>> --- /dev/null
>> +++ b/libstdc++-v3/src/experimental/Makefile.am
>> @@ -0,0 +1,96 @@
>> +## Makefile for experimental additions to the GNU C++ Standard library.
>> +##
>> +## Copyright (C) 2014-2022 Free Software Foundation, Inc.
>> +##
>> +## Process this file with automake to produce Makefile.in.
>> +##
>> +## 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.
>> +##
>> +## You should have received a copy of the GNU General Public License
>> +## along with GCC; see the file COPYING3.  If not see
>> +## <http://www.gnu.org/licenses/>.
>> +
>> +include $(top_srcdir)/fragment.am
>> +
>> +toolexeclib_LTLIBRARIES = libstdc++exp.la
>> +
>> +headers =
>> +
>> +sources = \
>> +    contract.cc
>> +
>> +# vpath % $(top_srcdir)/src/experimental
>> +
>> +libstdc__exp_la_SOURCES = $(sources)
>> +
>> +# AM_CXXFLAGS needs to be in each subdirectory so that it can be
>> +# modified in a per-library or per-sub-library way.  Need to manually
>> +# set this option because CONFIG_CXXFLAGS has to be after
>> +# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
>> +# as the occasion calls for it.
>> +AM_CXXFLAGS = \
>> +    -std=gnu++17 -nostdinc++ \
>> +    $(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
>> +    $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
>> +    $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \
>> +    -fimplicit-templates
>> +
>> +AM_MAKEFLAGS = \
>> +    "gxx_include_dir=$(gxx_include_dir)"
>> +
>> +# Libtool notes
>> +
>> +# 1) In general, libtool expects an argument such as `--tag=CXX' when
>> +# using the C++ compiler, because that will enable the settings
>> +# detected when C++ support was being configured.  However, when no
>> +# such flag is given in the command line, libtool attempts to figure
>> +# it out by matching the compiler name in each configuration section
>> +# against a prefix of the command line.  The problem is that, if the
>> +# compiler name and its initial flags stored in the libtool
>> +# configuration file don't match those in the command line, libtool
>> +# can't decide which configuration to use, and it gives up.  The
>> +# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
>> +# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
>> +# attempt to infer which configuration to use.
>> +#
>> +# The second tag argument, `--tag disable-shared` means that libtool
>> +# only compiles each source once, for static objects. In actuality,
>> +# glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
>> +# the libtool command that is used create the object, which is
>> +# suitable for shared libraries.  The `--tag disable-shared` must be
>> +# placed after --tag CXX lest things CXX undo the affect of
>> +# disable-shared.
>> +
>> +# 2) Need to explicitly set LTCXXCOMPILE so that EXTRA_CXX_FLAGS is
>> +# last. (That way, things like -O2 passed down from the toplevel can
>> +# be overridden by --enable-debug.)
>> +LTCXXCOMPILE = \
>> +    $(LIBTOOL) --tag CXX --tag disable-shared \
>> +    $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
>> +    --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
>> +    $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 
>> $(EXTRA_CXX_FLAGS)
>> +
>> +LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags 
>> $(LDFLAGS))
>> +
>> +# 3) We'd have a problem when building the shared libstdc++ object if
>> +# the rules automake generates would be used.  We cannot allow g++ to
>> +# be used since this would add -lstdc++ to the link line which of
>> +# course is problematic at this point.  So, we get the top-level
>> +# directory to configure libstdc++-v3 to use gcc as the C++
>> +# compilation driver.
>> +CXXLINK = \
>> +    $(LIBTOOL) --tag CXX --tag disable-shared \
>> +    $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
>> +    --mode=link $(CXX) \
>> +    $(VTV_CXXLINKFLAGS) \
>> +    $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
>> diff --git a/libstdc++-v3/include/experimental/contract 
>> b/libstdc++-v3/include/experimental/contract
>> new file mode 100644
>> index 00000000000..16f3fd5fd5a
>> --- /dev/null
>> +++ b/libstdc++-v3/include/experimental/contract
>> @@ -0,0 +1,82 @@
>> +// Contracts support header for -*- C++ -*-
>> +
>> +// Copyright (C) 1995-2022 Free Software Foundation, Inc.
> 
> Just 2022 again (or earlier if this is based on Lock3 code contributed
> earilier? but not 1995 I think!)
> 
>> +// 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
>> +
>> +#pragma GCC system_header
>> +
>> +#if __cplusplus >= 201703L
>> +
>> +#include <bits/c++config.h>
> 
> This is included by <string_view> so not needed here.
> 
> OK for trunk with those tweaks, thanks.

Thanks, this is what I'm pushing:
  
Jonathan Wakely Nov. 19, 2022, 12:50 p.m. UTC | #3
On Sat, 19 Nov 2022 at 02:40, Jason Merrill <jason@redhat.com> wrote:

>
> Thanks, this is what I'm pushing:
>

Great.

I wonder if we should move the contents of libstdc++fs.a and
libstdc++_libbacktrace.a into libstdc++exp.a and make the former libraries
into linker scripts that point to libstdc++exp.a

It would be easier to only have one lib for unstable things.
  

Patch

diff --git a/libstdc++-v3/src/experimental/contract.cc b/libstdc++-v3/src/experimental/contract.cc
new file mode 100644
index 00000000000..b9b72cd7df0
--- /dev/null
+++ b/libstdc++-v3/src/experimental/contract.cc
@@ -0,0 +1,41 @@ 
+// -*- C++ -*- std::experimental::contract_violation and friends
+// Copyright (C) 1994-2022 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>
+#include <iostream>
+
+__attribute__ ((weak)) void
+handle_contract_violation (const std::experimental::contract_violation &violation)
+{
+  std::cerr << "default std::handle_contract_violation called: " << std::endl
+    << " " << violation.file_name()
+    << " " << violation.line_number()
+    << " " << violation.function_name()
+    << " " << violation.comment()
+    << " " << violation.assertion_level()
+    << " " << violation.assertion_role()
+    << " " << (int)violation.continuation_mode()
+    << std::endl;
+}
+
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 6f672924a73..baf01913a90 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -49,7 +49,7 @@  AC_DEFUN([GLIBCXX_CONFIGURE], [
   # Keep these sync'd with the list in Makefile.am.  The first provides an
   # expandable list at autoconf time; the second provides an expandable list
   # (i.e., shell variable) at configure time.
-  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 src/c++17 src/c++20 src/filesystem src/libbacktrace doc po testsuite python])
+  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 src/c++17 src/c++20 src/filesystem src/libbacktrace src/experimental doc po testsuite python])
   SUBDIRS='glibcxx_SUBDIRS'
 
   # These need to be absolute paths, yet at the same time need to
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 96137a6621a..a6f9912cb9b 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -769,6 +769,7 @@  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/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index b83c222d51d..6f08068326d 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -37,7 +37,7 @@  backtrace_supported_h =
 endif
 
 ## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
-SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir)
+SUBDIRS = c++98 c++11 c++17 c++20 $(filesystem_dir) $(backtrace_dir) experimental
 
 # Cross compiler support.
 if VTV_CYGMIN
@@ -75,6 +75,7 @@  endif
 if ENABLE_BACKTRACE
 vpath % $(top_srcdir)/src/libbacktrace
 endif
+vpath % $(top_srcdir)/src/experimental
 
 if GLIBCXX_LDBL_COMPAT
 ldbl_compat_sources = compatibility-ldbl.cc
diff --git a/libstdc++-v3/src/experimental/Makefile.am b/libstdc++-v3/src/experimental/Makefile.am
new file mode 100644
index 00000000000..a1c2f62a518
--- /dev/null
+++ b/libstdc++-v3/src/experimental/Makefile.am
@@ -0,0 +1,96 @@ 
+## Makefile for experimental additions to the GNU C++ Standard library.
+##
+## Copyright (C) 2014-2022 Free Software Foundation, Inc.
+##
+## Process this file with automake to produce Makefile.in.
+##
+## 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with GCC; see the file COPYING3.  If not see
+## <http://www.gnu.org/licenses/>.
+
+include $(top_srcdir)/fragment.am
+
+toolexeclib_LTLIBRARIES = libstdc++exp.la
+
+headers =
+
+sources = \
+	contract.cc
+
+# vpath % $(top_srcdir)/src/experimental
+
+libstdc__exp_la_SOURCES = $(sources)
+
+# AM_CXXFLAGS needs to be in each subdirectory so that it can be
+# modified in a per-library or per-sub-library way.  Need to manually
+# set this option because CONFIG_CXXFLAGS has to be after
+# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
+# as the occasion calls for it.
+AM_CXXFLAGS = \
+	-std=gnu++17 -nostdinc++ \
+	$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
+	$(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
+	$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS) \
+	-fimplicit-templates
+
+AM_MAKEFLAGS = \
+	"gxx_include_dir=$(gxx_include_dir)"
+
+# Libtool notes
+
+# 1) In general, libtool expects an argument such as `--tag=CXX' when
+# using the C++ compiler, because that will enable the settings
+# detected when C++ support was being configured.  However, when no
+# such flag is given in the command line, libtool attempts to figure
+# it out by matching the compiler name in each configuration section
+# against a prefix of the command line.  The problem is that, if the
+# compiler name and its initial flags stored in the libtool
+# configuration file don't match those in the command line, libtool
+# can't decide which configuration to use, and it gives up.  The
+# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
+# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
+# attempt to infer which configuration to use.
+#
+# The second tag argument, `--tag disable-shared` means that libtool
+# only compiles each source once, for static objects. In actuality,
+# glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
+# the libtool command that is used create the object, which is
+# suitable for shared libraries.  The `--tag disable-shared` must be
+# placed after --tag CXX lest things CXX undo the affect of
+# disable-shared.
+
+# 2) Need to explicitly set LTCXXCOMPILE so that EXTRA_CXX_FLAGS is
+# last. (That way, things like -O2 passed down from the toplevel can
+# be overridden by --enable-debug.)
+LTCXXCOMPILE = \
+	$(LIBTOOL) --tag CXX --tag disable-shared \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(EXTRA_CXX_FLAGS)
+
+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
+
+# 3) We'd have a problem when building the shared libstdc++ object if
+# the rules automake generates would be used.  We cannot allow g++ to
+# be used since this would add -lstdc++ to the link line which of
+# course is problematic at this point.  So, we get the top-level
+# directory to configure libstdc++-v3 to use gcc as the C++
+# compilation driver.
+CXXLINK = \
+	$(LIBTOOL) --tag CXX --tag disable-shared \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CXX) \
+	$(VTV_CXXLINKFLAGS) \
+	$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
diff --git a/libstdc++-v3/include/experimental/contract b/libstdc++-v3/include/experimental/contract
new file mode 100644
index 00000000000..16f3fd5fd5a
--- /dev/null
+++ b/libstdc++-v3/include/experimental/contract
@@ -0,0 +1,82 @@ 
+// Contracts support header for -*- C++ -*-
+
+// Copyright (C) 1995-2022 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
+
+#pragma GCC system_header
+
+#if __cplusplus >= 201703L
+
+#include <bits/c++config.h>
+#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