Re: [PATCH] [11/12/13/14 Regression] ABI break in _Hash_node_value_base since GCC 11 [PR 111050]

2023-09-28 Thread Jonathan Wakely
On Wed, 27 Sept 2023 at 05:44, François Dumont  wrote:
>
> Still no chance to get feedback from TC ? Maybe I can commit the below
> then ?

I've heard back from Tim now. Please use "Tim Song
" as the author.

You can change the commit again using git commit --amend --author "Tim
Song "

OK for trunk with that change - thanks for waiting.


>
> AFAICS on gcc mailing list several gcc releases were done recently, too
> late.

There have been no releases this month, so the delay hasn't caused any problems.


>
>
> On 14/09/2023 06:46, François Dumont wrote:
> > Author: TC 
> > Date:   Wed Sep 6 19:31:55 2023 +0200
> >
> > libstdc++: Force _Hash_node_value_base methods inline to fix abi
> > (PR111050)
> >
> > https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1b6f0476837205932613ddb2b3429a55c26c409d
> >
> > changed _Hash_node_value_base to no longer derive from
> > _Hash_node_base, which means
> > that its member functions expect _M_storage to be at a different
> > offset. So explosions
> > result if an out-of-line definition is emitted for any of the
> > member functions (say,
> > in a non-optimized build) and the resulting object file is then
> > linked with code built
> > using older version of GCC/libstdc++.
> >
> > libstdc++-v3/ChangeLog:
> >
> > PR libstdc++/111050
> > * include/bits/hashtable_policy.h
> >     (_Hash_node_value_base<>::_M_valptr(),
> > _Hash_node_value_base<>::_M_v())
> >     Add [[__gnu__::__always_inline__]].
> >
> > Ok to commit ?
> >
> > On 12/09/2023 18:09, Jonathan Wakely wrote:
> >> On Mon, 11 Sept 2023 at 18:19, François Dumont 
> >> wrote:
> >>>
> >>> On 11/09/2023 13:51, Jonathan Wakely wrote:
> >>>> On Sun, 10 Sept 2023 at 14:57, François Dumont via Libstdc++
> >>>>  wrote:
> >>>>> Following confirmation of the fix by TC here is the patch where I'm
> >>>>> simply adding a 'constexpr' on _M_next().
> >>>>>
> >>>>> Please let me know this ChangeLog entry is correct. I would prefer
> >>>>> this
> >>>>> patch to be assigned to 'TC' with me as co-author but I don't know
> >>>>> how
> >>>>> to do such a thing. Unless I need to change my user git identity
> >>>>> to do so ?
> >>>> Sam already explained that, but please check with Tim how he wants to
> >>>> be credited, if at all. He doesn't have a copyright assignment, and
> >>>> hasn't added a DCO sign-off to the patch, but it's small enough to not
> >>>> need it as this is the first contribution credited to him.
> >>>>
> >>>>
> >>>>>libstdc++: Add constexpr qualification to
> >>>>> _Hash_node::_M_next()
> >>>> What has this constexpr addition got to do with the ABI change and the
> >>>> always_inline attributes?
> >>>>
> >>>> It certainly doesn't seem like it should be the summary line of the
> >>>> git commit message.
> >>> Oops, sorry, that's what I had started to do before Tim submitted
> >>> anything.
> >>>
> >>> Here is latest version:
> >> No patch attached, and the ChangeLog below still mentions the constexpr.
> >>
> >> I've pinged Tim via another channel to ask him about the author
> >> attribution.
> >>
> >>
> >>> Author: TC 
> >>> Date:   Wed Sep 6 19:31:55 2023 +0200
> >>>
> >>>   libstdc++: Force inline on _Hash_node_value_base methods to
> >>> fix abi
> >>> (PR111050)
> >>>
> >>> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1b6f0476837205932613ddb2b3429a55c26c409d
> >>>
> >>>   changed _Hash_node_value_base to no longer derive from
> >>> _Hash_node_base, which means
> >>>   that its member functions expect _M_storage to be at a different
> >>> offset. So explosions
> >>>   result if an out-of-line definition is emitted for any of the
> >>> member functions (say,
> >>>   in a non-optimized build) and the resulting object file is then
> >>> linked with code built
> >>>   using older version of GCC/libstdc++.
> >>>
> >>>   libstdc++-v3/ChangeLog:
> >>>
> >>>   PR libstdc++/111050
> >>>   * include/bits/hashtable_policy.h
> >>>   (_Hash_node_value_base<>::_M_valptr(),
> >>> _Hash_node_value_base<>::_M_v())
> >>>   Add [[__gnu__::__always_inline__]].
> >>>   (_Hash_node<>::_M_next()): Add constexpr.
> >>>
> >>>   Co-authored-by: François Dumont 
> >>>
> >>> Ok for you TC (Tim ?) ?
> >>>
> >>>
>



Re: [committed] libstdc++: Add GDB printers for types

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:37 Tom Tromey,  wrote:

> Jonathan> The changes made by black seem reasonable, though I prefer it
> Jonathan> with -S to disable string-normalization. It also needs an
> Jonathan> option to use 79 as the maximum line length.
>
> I've got some patches I'm about to send.
>
> I made a pyproject.toml to auto-configure black (and isort), and this
> works fine, but it also makes a bunch of edits.  So I'd rather send that
> separately, after the current batch of patches is handled.
>
> flake8 still isn't really happy, I guess because there are strings that
> cause lines over 79, and black doesn't split those.  But meh, maybe
> suppressing some flake8 errors is the way to go.
>


I was about to push some changes to split those strings up.



> Tom
>


Re: [PATCH 1/7] libstdc++: Show full Python stack on error

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:48 Tom Tromey via Libstdc++, 
wrote:

> This changes the libstdc++ test suite to arrange for gdb to show the
> full Python stack if any sort of Python exception occurs.  This makes
> debugging the printers a little simpler.
>

Oh I wish I'd known about this sooner.

OK for trunk, thanks.


> libstdc++-v3/ChangeLog:
>
> * testsuite/lib/gdb-test.exp (gdb-test): Enable Python
> stack traces from gdb.
> ---
>  libstdc++-v3/testsuite/lib/gdb-test.exp | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp
> b/libstdc++-v3/testsuite/lib/gdb-test.exp
> index d8e572ef7b3..af7d970d388 100644
> --- a/libstdc++-v3/testsuite/lib/gdb-test.exp
> +++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
> @@ -141,6 +141,8 @@ proc gdb-test { marker {selector {}} {load_xmethods 0}
> } {
>  puts $fd "set auto-load no"
>  # Now that we've disabled auto-load, it's safe to set the target file
>  puts $fd "file ./$output_file"
> +# See the full backtrace of any failures.
> +puts $fd "set python print-stack full"
>  # Load & register *our* copy of the pretty-printers
>  puts $fd "source $printer_code"
>  puts $fd "python register_libstdcxx_printers(None)"
> --
> 2.40.1
>
>


Re: [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:50 Tom Tromey via Libstdc++, 
wrote:

> flake8 pointed out that some regexes in the pretty-printers are
> missing a backslash.  This patch fixes these.
>

I already have a patch to use r'...' for these, so we only need the single
backslash.

I'm also refactoring all those re.match calls in xmethods.exp to use a
common function.

So please don't commit this one, I think it will be unnecessary in a couple
of hours.



> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py
> (StdExpAnyPrinter.__init__, StdExpOptionalPrinter.__init__):
> Add missing backslash.
> * python/libstdcxx/v6/xmethods.py
> (ArrayMethodsMatcher.match, DequeMethodsMatcher.match)
> (ForwardListMethodsMatcher.match, ListMethodsMatcher.match)
> (VectorMethodsMatcher.match)
> (AssociativeContainerMethodsMatcher.match)
> (UniquePtrGetWorker.__call__, UniquePtrMethodsMatcher.match)
> (SharedPtrSubscriptWorker.__call__)
> (SharedPtrMethodsMatcher.match): Add missing backslash.
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py |  6 +++---
>  libstdc++-v3/python/libstdcxx/v6/xmethods.py | 22 ++--
>  2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 94ac9232da7..d125236b777 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -1344,7 +1344,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
>  def __init__(self, typename, val):
>  self._typename = strip_versioned_namespace(typename)
>  self._typename = re.sub(
> -'^std::experimental::fundamentals_v\d::',
> 'std::experimental::', self._typename, 1)
> +'^std::experimental::fundamentals_v\\d::',
> 'std::experimental::', self._typename, 1)
>  self._val = val
>  self._contained_type = None
>  contained_value = None
> @@ -1377,7 +1377,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
>  mgrtypes = []
>  for s in strings:
>  try:
> -x = re.sub("std::string(?!\w)", s, m.group(1))
> +x = re.sub("std::string(?!\\w)", s, m.group(1))
>  # The following lookup might raise gdb.error if
> the
>  # manager function was never instantiated for 's'
> in the
>  # program, because there will be no such type.
> @@ -1425,7 +1425,7 @@ class
> StdExpOptionalPrinter(SingleObjContainerPrinter):
>  def __init__(self, typename, val):
>  typename = strip_versioned_namespace(typename)
>  self._typename = re.sub(
> -'^std::(experimental::|)(fundamentals_v\d::|)(.*)',
> r'std::\1\3', typename, 1)
> +'^std::(experimental::|)(fundamentals_v\\d::|)(.*)',
> r'std::\1\3', typename, 1)
>  payload = val['_M_payload']
>  if self._typename.startswith('std::experimental'):
>  engaged = val['_M_engaged']
> diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> index 025b1b86ed0..eafecbb148e 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> @@ -159,7 +159,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
>  self.methods = [self._method_dict[m] for m in self._method_dict]
>
>  def match(self, class_type, method_name):
> -if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
> +if not re.match('^std::(__\\d+::)?array<.*>$', class_type.tag):
>  return None
>  method = self._method_dict.get(method_name)
>  if method is None or not method.enabled:
> @@ -284,7 +284,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
>  self.methods = [self._method_dict[m] for m in self._method_dict]
>
>  def match(self, class_type, method_name):
> -if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
> +if not re.match('^std::(__\\d+::)?deque<.*>$', class_type.tag):
>  return None
>  method = self._method_dict.get(method_name)
>  if method is None or not method.enabled:
> @@ -332,7 +332,7 @@ class
> ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
>  self.methods = [self._method_dict[m] for m in self._method_dict]
>
>  def match(self, class_type, method_name):
> -if not re.match('^std::(__\d+::)?forward_list<.*>$',
> class_type.tag):
> +if not re.match('^std::(__\\d+::)?forward_list<.*>$',
> class_type.tag):
>  return None
>  method = self._method_dict.get(method_name)
>  if method is None or not method.enabled:
> @@ -419,7 +419,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
>  self.m

Re: [PATCH 7/7] libstdc++: Use Python "not in" operator

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:54 Tom Tromey via Libstdc++, 
wrote:

> flake8 warns about code like
>
> not something in "whatever"
>
> Ordinarily in Python this should be written as:
>
> something not in "whatever"
>
> This patch makes this change.
>

OK, thanks.



> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py (Printer.add_version)
> (add_one_template_type_printer)
> (FilteringTypePrinter.add_one_type_printer): Use Python
> "not in" operator.
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d125236b777..380426cd41e 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -2321,7 +2321,7 @@ class Printer(object):
>  # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
>  def add_version(self, base, name, function):
>  self.add(base + name, function)
> -if _versioned_namespace and not '__cxx11' in base:
> +if _versioned_namespace and '__cxx11' not in base:
>  vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
> _versioned_namespace, base)
>  self.add(vbase + name, function)
> @@ -2494,7 +2494,7 @@ def add_one_template_type_printer(obj, name,
> defargs):
>  printer = TemplateTypePrinter('std::__debug::'+name, defargs)
>  gdb.types.register_type_printer(obj, printer)
>
> -if _versioned_namespace and not '__cxx11' in name:
> +if _versioned_namespace and '__cxx11' not in name:
>  # Add second type printer for same type in versioned namespace:
>  ns = 'std::' + _versioned_namespace
>  # PR 86112 Cannot use dict comprehension here:
> @@ -2589,7 +2589,7 @@ class FilteringTypePrinter(object):
>  def add_one_type_printer(obj, template, name, targ1=None):
>  printer = FilteringTypePrinter('std::' + template, 'std::' + name,
> targ1)
>  gdb.types.register_type_printer(obj, printer)
> -if _versioned_namespace and not '__cxx11' in template:
> +if _versioned_namespace and '__cxx11' not in template:
>  ns = 'std::' + _versioned_namespace
>  printer = FilteringTypePrinter(ns + template, ns + name, targ1)
>  gdb.types.register_type_printer(obj, printer)
> --
> 2.40.1
>
>


Re: [PATCH 4/7] libstdc++: Remove unused locals from printers.py

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:50 Tom Tromey via Libstdc++, 
wrote:

> flake8 pointed out some unused local variables in the libstdc++
> pretty-printers.  This removes them.
>

OK, thanks.



> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py
> (StdExpOptionalPrinter.__init__, lookup_node_type):
> Remove unused variables.
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 8d44244afb0..6bf4fe891fd 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -169,7 +169,7 @@ def lookup_node_type(nodename, containertype):
>  valtype = valtype.strip_typedefs()
>  try:
>  return lookup_templ_spec(nodename, valtype)
> -except gdb.error as e:
> +except gdb.error:
>  # For debug mode containers the node is in std::__cxx1998.
>  if is_member_of_namespace(nodename, 'std'):
>  if is_member_of_namespace(containertype, 'std::__cxx1998',
> @@ -1423,7 +1423,6 @@ class
> StdExpOptionalPrinter(SingleObjContainerPrinter):
>  "Print a std::optional or std::experimental::optional"
>
>  def __init__(self, typename, val):
> -valtype = self._recognize(val.type.template_argument(0))
>  typename = strip_versioned_namespace(typename)
>  self._typename = re.sub(
>  '^std::(experimental::|)(fundamentals_v\d::|)(.*)',
> r'std::\1\3', typename, 1)
> --
> 2.40.1
>
>


Re: [PATCH 3/7] libstdc++: Remove unused Python imports

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:50 Tom Tromey via Libstdc++, 
wrote:

> flake8 pointed out some unused imports.
>

OK, thanks.



> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py: Don't import 'os'.
> * python/libstdcxx/v6/__init__.py: Don't import 'gdb'.
> ---
>  libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 --
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 1 -
>  2 files changed, 3 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py
> b/libstdc++-v3/python/libstdcxx/v6/__init__.py
> index df654acd0c2..8b2cbc60a1b 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/__init__.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py
> @@ -13,8 +13,6 @@
>  # You should have received a copy of the GNU General Public License
>  # along with this program.  If not, see .
>
> -import gdb
> -
>  # Load the xmethods if GDB supports them.
>  def gdb_has_xmethods():
>  try:
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index bbc4375541f..8d44244afb0 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -19,7 +19,6 @@ import gdb
>  import itertools
>  import re
>  import sys
> -import os
>  import errno
>  import datetime
>
> --
> 2.40.1
>
>


Re: [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 18:55 Tom Tromey via Libstdc++, 
wrote:

> This removes the std_ratio_t_tuple function from the Python
> pretty-printer code.  It is not used.  Apparently the relevant parts
> were moved to StdChronoDurationPrinter._ratio at some point in the
> past.
>

I think I added it at the same time as that printer, rather than moving it
there later. I don't remember if I wanted to replace the _ratio method with
that function, or vice versa, but it looks like I never finished whatever I
meant to do. Either way, we don't need to keep the unused function.

OK, thanks.





> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py (std_ratio_t_tuple):
> Remove.
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 8 
>  1 file changed, 8 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 6bf4fe891fd..94ac9232da7 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -1985,14 +1985,6 @@ class StdFormatArgsPrinter(printer_base):
>  return "%s with %d arguments" % (typ, size)
>
>
> -def std_ratio_t_tuple(ratio_type):
> -# TODO use reduced period i.e. duration::period
> -period = self._val.type.template_argument(1)
> -num = period.template_argument(0)
> -den = period.template_argument(1)
> -return (num, den)
> -
> -
>  class StdChronoDurationPrinter(printer_base):
>  "Print a std::chrono::duration"
>
> --
> 2.40.1
>
>


[committed] libstdc++: Format Python docstrings according to PEP 357

2023-09-28 Thread Jonathan Wakely
Tested x86_64-linux (GDB 13.2, Python 3.11). Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py: Format docstrings according
to PEP 257.
* python/libstdcxx/v6/xmethods.py: Likewise.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 177 ++-
 libstdc++-v3/python/libstdcxx/v6/xmethods.py |  32 ++--
 2 files changed, 112 insertions(+), 97 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d60c8003a63..7889235ce1c 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -69,7 +69,7 @@ else:
 
 # Python 2 does not provide the datetime.UTC singleton.
 class UTC(datetime.tzinfo):
-"""Concrete tzinfo class representing the UTC time zone"""
+"""Concrete tzinfo class representing the UTC time zone."""
 
 def utcoffset(self, dt):
 return datetime.timedelta(0)
@@ -126,7 +126,7 @@ _versioned_namespace = '__8::'
 
 def lookup_templ_spec(templ, *args):
 """
-Lookup template specialization templ
+Lookup template specialization templ.
 """
 t = '{}<{}>'.format(templ, ', '.join([str(a) for a in args]))
 try:
@@ -146,17 +146,23 @@ def lookup_templ_spec(templ, *args):
 # Use this to find container node types instead of find_type,
 # see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91997 for details.
 
-
 def lookup_node_type(nodename, containertype):
 """
-Lookup specialization of template NODENAME corresponding to CONTAINERTYPE.
-e.g. if NODENAME is '_List_node' and CONTAINERTYPE is std::list
-then return the type std::_List_node.
-Returns None if not found.
+Lookup specialization of template nodename corresponding to containertype.
+
+nodename - The name of a class template, as a String
+containertype - The container, as a gdb.Type
+
+Return a gdb.Type for the corresponding specialization of nodename,
+or None if the type cannot be found.
+
+e.g. lookup_node_type('_List_node', gdb.lookup_type('std::list'))
+will return a gdb.Type for the type std::_List_node.
 """
 # If nodename is unqualified, assume it's in namespace std.
 if '::' not in nodename:
 nodename = 'std::' + nodename
+# Use either containertype's value_type or its first template argument.
 try:
 valtype = find_type(containertype, 'value_type')
 except:
@@ -214,7 +220,7 @@ def strip_versioned_namespace(typename):
 
 
 def strip_inline_namespaces(type_str):
-"Remove known inline namespaces from the canonical name of a type."
+"""Remove known inline namespaces from the canonical name of a type."""
 type_str = strip_versioned_namespace(type_str)
 type_str = type_str.replace('std::__cxx11::', 'std::')
 expt_ns = 'std::experimental::'
@@ -226,7 +232,7 @@ def strip_inline_namespaces(type_str):
 
 
 def get_template_arg_list(type_obj):
-"Return a type's template arguments as a list"
+"""Return a type's template arguments as a list."""
 n = 0
 template_args = []
 while True:
@@ -238,7 +244,7 @@ def get_template_arg_list(type_obj):
 
 
 class SmartPtrIterator(Iterator):
-"An iterator for smart pointer types with a single 'child' value"
+"""An iterator for smart pointer types with a single 'child' value."""
 
 def __init__(self, val):
 self.val = val
@@ -254,7 +260,9 @@ class SmartPtrIterator(Iterator):
 
 
 class SharedPointerPrinter:
-"Print a shared_ptr, weak_ptr, atomic, or atomic"
+"""
+Print a shared_ptr, weak_ptr, atomic, or atomic.
+"""
 
 def __init__(self, typename, val):
 self.typename = strip_versioned_namespace(typename)
@@ -292,7 +300,7 @@ class SharedPointerPrinter:
 
 
 def _tuple_impl_get(val):
-"Return the tuple element stored in a _Tuple_impl base class."
+"""Return the tuple element stored in a _Tuple_impl base class."""
 bases = val.type.fields()
 if not bases[-1].is_base_class:
 raise ValueError(
@@ -316,7 +324,7 @@ def _tuple_impl_get(val):
 
 
 def tuple_get(n, val):
-"Return the result of std::get(val) on a std::tuple"
+"""Return the result of std::get(val) on a std::tuple."""
 tuple_size = len(get_template_arg_list(val.type))
 if n > tuple_size:
 raise ValueError("Out of range index for std::get on std::tuple")
@@ -330,7 +338,7 @@ def tuple_get(n, val):
 
 
 def unique_ptr_get(val):
-"Return the result of val.get() on a std::unique_ptr"
+"""Return the result of val.get() on a std::unique_ptr."""
 # std::unique_ptr contains a std::tuple,
 # either as a direct data member _M_t (the old implementation)
 # or within a data member of type __uniq_ptr_data.
@@ -348,7 +356,7 @@ def unique_ptr_get(val):
 
 
 class UniquePointerPrinter:
-"Print a unique_ptr"
+"""Print a unique_ptr."""
 
 def __init__(self, typename, val):
 self

[committed] libstdc++: Reformat Python code

2023-09-28 Thread Jonathan Wakely
Tested x86_64-linux (GDB 13.2, Python 3.11). Pushed to trunk.

-- >8 --

Some of these changes were suggested by autopep8's --aggressive
option, others are for readability.

Break long lines by splitting strings across multiple lines, or
introducing local variables to hold results.

Use raw strings for regular expressions, so that backslashes don't need
to be escaped.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py: Break long lines. Use raw
strings for regular expressions. Add whitespace around
operators.
(is_member_of_namespace): Use isinstance to check type.
(is_specialization_of): Likewise. Adjust template_name
for versioned namespace instead of duplicating the re.match
call.
(StdExpAnyPrinter._string_types): New static method.
(StdExpAnyPrinter.to_string): Use _string_types.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 122 ---
 1 file changed, 75 insertions(+), 47 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 7889235ce1c..3f22ba23452 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -145,7 +145,6 @@ def lookup_templ_spec(templ, *args):
 
 # Use this to find container node types instead of find_type,
 # see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91997 for details.
-
 def lookup_node_type(nodename, containertype):
 """
 Lookup specialization of template nodename corresponding to containertype.
@@ -188,7 +187,7 @@ def is_member_of_namespace(typ, *namespaces):
 Test whether a type is a member of one of the specified namespaces.
 The type can be specified as a string or a gdb.Type object.
 """
-if type(typ) is gdb.Type:
+if isinstance(typ, gdb.Type):
 typ = str(typ)
 typ = strip_versioned_namespace(typ)
 for namespace in namespaces:
@@ -205,10 +204,10 @@ def is_specialization_of(x, template_name):
 without any 'std' qualification.
 """
 global _versioned_namespace
-if type(x) is gdb.Type:
+if isinstance(x, gdb.Type):
 x = x.tag
 if _versioned_namespace:
-return re.match('^std::(%s)?%s<.*>$' % (_versioned_namespace, 
template_name), x) is not None
+template_name = '(%s)?%s' % (_versioned_namespace, template_name)
 return re.match('^std::%s<.*>$' % template_name, x) is not None
 
 
@@ -225,9 +224,9 @@ def strip_inline_namespaces(type_str):
 type_str = type_str.replace('std::__cxx11::', 'std::')
 expt_ns = 'std::experimental::'
 for lfts_ns in ('fundamentals_v1', 'fundamentals_v2'):
-type_str = type_str.replace(expt_ns+lfts_ns+'::', expt_ns)
+type_str = type_str.replace(expt_ns + lfts_ns + '::', expt_ns)
 fs_ns = expt_ns + 'filesystem::'
-type_str = type_str.replace(fs_ns+'v1::', fs_ns)
+type_str = type_str.replace(fs_ns + 'v1::', fs_ns)
 return type_str
 
 
@@ -365,7 +364,8 @@ class UniquePointerPrinter:
 return SmartPtrIterator(unique_ptr_get(self.val))
 
 def to_string(self):
-return ('std::unique_ptr<%s>' % 
(str(self.val.type.template_argument(0
+t = self.val.type.template_argument(0)
+return 'std::unique_ptr<{}>'.format(str(t))
 
 
 def get_value_from_aligned_membuf(buf, valtype):
@@ -597,7 +597,8 @@ class StdBitIteratorPrinter:
 def to_string(self):
 if not self.val['_M_p']:
 return 'non-dereferenceable iterator for std::vector'
-return bool(self.val['_M_p'].dereference() & (1 << 
self.val['_M_offset']))
+return bool(self.val['_M_p'].dereference()
+& (1 << self.val['_M_offset']))
 
 
 class StdBitReferencePrinter:
@@ -1087,9 +1088,10 @@ class StdStringStreamPrinter:
 self.val = val
 self.typename = typename
 
-# Check if the stream was redirected:
-# This is essentially: val['_M_streambuf'] == 
val['_M_stringbuf'].address
-# However, GDB can't resolve the virtual inheritance, so we do that 
manually
+# Check if the stream was redirected. This is essentially:
+# val['_M_streambuf'] != val['_M_stringbuf'].address
+# However, GDB can't resolve the virtual inheritance, so we do that
+# manually.
 basetype = [f.type for f in val.type.fields() if f.is_base_class][0]
 gdb.set_convenience_variable('__stream', val.cast(basetype).address)
 self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
@@ -1097,7 +1099,8 @@ class StdStringStreamPrinter:
 
 def to_string(self):
 if self.was_redirected:
-return "%s redirected to %s" % (self.typename, 
self.streambuf.dereference())
+return "%s redirected to %s" % (
+self.typename, self.streambuf.dereference())
 return self.val['_M_stringbuf']
 
 def display_hint(self):
@@ -1309,8 +1312,9 @@ class SingleObjContainerPrinter(object

[committed] libstdc++: Refactor Python Xmethods to use is_specialization_of

2023-09-28 Thread Jonathan Wakely
Tested x86_64-linux (GDB 13.2, Python 3.11). Pushed to trunk.

-- >8 --

This copies the is_specialization_of function from printers.py (with
slight modification for versioned namespace handling) and reuses it in
xmethods.py to replace repetitive re.match calls in every class.

This fixes the problem that the regular expressions used \d without
escaping the backslash properly.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/xmethods.py (is_specialization_of): Define
new function.
(ArrayMethodsMatcher, DequeMethodsMatcher)
(ForwardListMethodsMatcher, ListMethodsMatcher)
(VectorMethodsMatcher, AssociativeContainerMethodsMatcher)
(UniquePtrGetWorker, UniquePtrMethodsMatcher)
(SharedPtrSubscriptWorker, SharedPtrMethodsMatcher): Use
is_specialization_of instead of re.match.
---
 libstdc++-v3/python/libstdcxx/v6/xmethods.py | 36 +---
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py 
b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index ef0a6e3cef3..844c8a2105a 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -25,10 +25,21 @@ matcher_name_prefix = 'libstdc++::'
 def get_bool_type():
 return gdb.lookup_type('bool')
 
-
 def get_std_size_type():
 return gdb.lookup_type('std::size_t')
 
+def is_specialization_of(x, template_name):
+"""
+Test whether a type is a specialization of the named class template.
+The type can be specified as a string or a gdb.Type object.
+The template should be the name of a class template as a string,
+without any 'std' qualification.
+"""
+if isinstance(x, gdb.Type):
+x = x.tag
+if _versioned_namespace:
+template_name = '(%s)?%s' % (_versioned_namespace, template_name)
+return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None
 
 class LibStdCxxXMethod(gdb.xmethod.XMethod):
 def __init__(self, name, worker_class):
@@ -159,7 +170,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
+if not is_specialization_of(class_type, 'array'):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -171,6 +182,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
 return None
 return method.worker_class(value_type, size)
 
+
 # Xmethods for std::deque
 
 
@@ -284,7 +296,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
+if not is_specialization_of(class_type, 'deque'):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -332,7 +344,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag):
+if not is_specialization_of(class_type, 'forward_list'):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -419,7 +431,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', 
class_type.tag):
+if not is_specialization_of(class_type, '(__cxx11::)?list'):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -542,7 +554,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag):
+if not is_specialization_of(class_type, 'vector'):
 return None
 method = self._method_dict.get(method_name)
 if method is None or not method.enabled:
@@ -595,7 +607,7 @@ class 
AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
 self.methods = [self._method_dict[m] for m in self._method_dict]
 
 def match(self, class_type, method_name):
-if not re.match('^std::(__\d+::)?%s<.*>$' % self._name, 
class_type.tag):
+if not is_specialization_of(class_type, self._name):
 return None
 method = self._method_dict.get(method_nam

Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023 at 18:50, Tom Tromey via Libstdc++
 wrote:
>
> GDB 14 will add a new ValuePrinter tag class that will be used to
> signal that pretty-printers will agree to the "extension protocol" --
> essentially that they will follow some simple namespace rules, so that
> GDB can add new methods over time.
>
> A couple new methods have already been added to GDB, to support DAP.
> While I haven't implemented these for any libstdc++ printers yet, this
> patch makes the basic conversion: printers derive from
> gdb.ValuePrinter if it is available, and all "non-standard" (that is,
> not specified by GDB) members of the various value-printing classes
> are renamed to have a leading underscore.

OK, thanks.

I've pushed the changes I wanted to make, so you'll have to rebase
your patches now, sorry.


> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +-
>  1 file changed, 605 insertions(+), 596 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d60c8003a63..bbc4375541f 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -97,6 +97,12 @@ try:
>  except ImportError:
>  pass
>
> +# Use the base class if available.
> +if hasattr(gdb, 'ValuePrinter'):
> +printer_base = gdb.ValuePrinter
> +else:
> +printer_base = object
> +
>  # Starting with the type ORIG, search for the member type NAME.  This
>  # handles searching upward through superclasses.  This is needed to
>  # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
> @@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator):
>  "An iterator for smart pointer types with a single 'child' value"
>
>  def __init__(self, val):
> -self.val = val
> +self._val = val
>
>  def __iter__(self):
>  return self
>
>  def __next__(self):
> -if self.val is None:
> +if self._val is None:
>  raise StopIteration
> -self.val, val = None, self.val
> +self._val, val = None, self._val
>  return ('get()', val)
>
>
> -class SharedPointerPrinter:
> +class SharedPointerPrinter(printer_base):
>  "Print a shared_ptr, weak_ptr, atomic, or atomic"
>
>  def __init__(self, typename, val):
> -self.typename = strip_versioned_namespace(typename)
> -self.val = val
> -self.pointer = val['_M_ptr']
> +self._typename = strip_versioned_namespace(typename)
> +self._val = val
> +self._pointer = val['_M_ptr']
>
>  def children(self):
> -return SmartPtrIterator(self.pointer)
> +return SmartPtrIterator(self._pointer)
>
>  # Return the _Sp_counted_base<>* that holds the refcounts.
>  def _get_refcounts(self):
> -if self.typename == 'std::atomic':
> +if self._typename == 'std::atomic':
>  # A tagged pointer is stored as uintptr_t.
> -ptr_val = self.val['_M_refcount']['_M_val']['_M_i']
> +ptr_val = self._val['_M_refcount']['_M_val']['_M_i']
>  ptr_val = ptr_val - (ptr_val % 2)  # clear lock bit
> -ptr_type = find_type(self.val['_M_refcount'].type, 'pointer')
> +ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
>  return ptr_val.cast(ptr_type)
> -return self.val['_M_refcount']['_M_pi']
> +return self._val['_M_refcount']['_M_pi']
>
>  def to_string(self):
>  state = 'empty'
>  refcounts = self._get_refcounts()
> -targ = self.val.type.template_argument(0)
> +targ = self._val.type.template_argument(0)
>  targ = strip_versioned_namespace(str(targ))
>
>  if refcounts != 0:
> @@ -288,7 +294,7 @@ class SharedPointerPrinter:
>  else:
>  state = 'use count %d, weak count %d' % (
>  usecount, weakcount - 1)
> -return '%s<%s> (%s)' % (self.typename, targ, state)
> +return '%s<%s> (%s)' % (self._typename, targ, state)
>
>
>  def _tuple_impl_get(val):
> @@ -347,17 +353,17 @@ def unique_ptr_get(val):
>  return tuple_get(0, tuple_member)
>
>
> -class UniquePointerPrinter:
> +class UniquePointerPrinter(printer_base):
>  "Print a unique_ptr"
>
>  def __init__(self, typename, val):
> -self.val = val
> +self._val = val
>
>  def children(self):
> -return SmartPtrIterator(unique_ptr_get(self.val))
> +return SmartPtrIterator(unique_ptr_get(self._val))
>
>  def to_string(self):
> -return ('std::unique_ptr<%s>' % 
> (str(self.val.type.template_argument(0
> +return ('std::unique_ptr<%s>' % 
> (str(self._val.type.template_argument(0
>
>
>  def get_value_from_aligned_membuf(buf, valtype):
> @@ -381,55 +387,56 @@ def get_value_from_list_node(node):
>  raise ValueError("Unsupported implementation for %s" % str(node.type))
>
>
> -class StdListPrinter:

Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class

2023-09-28 Thread Jonathan Wakely
On Thu, 28 Sept 2023, 21:38 Tom Tromey,  wrote:

> Jonathan> I've pushed the changes I wanted to make, so you'll have to
> rebase
> Jonathan> your patches now, sorry.
>
> No problem.  I rebased & re-tested them.
> I can send a v2 if you want to double-check (only this large patch
> required any changes), or just go ahead.  Let me know.
>

Just go ahead, the changes are all straightforward so if the tests still
pass, you can push it.


I may not be able to push until Monday.
>
> Tom
>


Re: [PATCH] libstdc++: Ensure active union member is correctly set

2023-09-29 Thread Jonathan Wakely
On Fri, 29 Sept 2023 at 00:25, Nathaniel Shead
 wrote:
>
> On Wed, Sep 27, 2023 at 03:13:35PM +0100, Jonathan Wakely wrote:
> > On Sat, 23 Sept 2023 at 08:30, Nathaniel Shead via Libstdc++
> >  wrote:
> > >
> > > On Sat, Sep 23, 2023 at 07:40:48AM +0100, Jonathan Wakely wrote:
> > > > On Sat, 23 Sept 2023, 01:39 Nathaniel Shead via Libstdc++, <
> > > > libstd...@gcc.gnu.org> wrote:
> > > >
> > > > > Now that bootstrap has finished, I have gotten regressions in the
> > > > > following libstdc++ tests:
> > > > >
> > > > > Running libstdc++:libstdc++-dg/conformance.exp ...
> > > > > FAIL: 20_util/bitset/access/constexpr.cc -std=gnu++23 (test for excess
> > > > > errors)
> > > > > FAIL: 20_util/bitset/access/constexpr.cc -std=gnu++26 (test for excess
> > > > > errors)
> > > > > FAIL: 20_util/variant/constexpr.cc -std=gnu++20 (test for excess 
> > > > > errors)
> > > > > FAIL: 20_util/variant/constexpr.cc -std=gnu++26 (test for excess 
> > > > > errors)
> > > > > FAIL: 21_strings/basic_string/cons/char/constexpr.cc -std=gnu++20 
> > > > > (test
> > > > > for excess errors)
> > > > > FAIL: 21_strings/basic_string/cons/char/constexpr.cc -std=gnu++26 
> > > > > (test
> > > > > for excess errors)
> > > > > FAIL: 21_strings/basic_string/cons/wchar_t/constexpr.cc -std=gnu++20 
> > > > > (test
> > > > > for excess errors)
> > > > > FAIL: 21_strings/basic_string/cons/wchar_t/constexpr.cc -std=gnu++26 
> > > > > (test
> > > > > for excess errors)
> > > > > FAIL: 21_strings/basic_string/modifiers/swap/constexpr-wchar_t.cc
> > > > > -std=gnu++20 (test for excess errors)
> > > > > FAIL: 21_strings/basic_string/modifiers/swap/constexpr-wchar_t.cc
> > > > > -std=gnu++26 (test for excess errors)
> > > > > FAIL: 21_strings/basic_string/modifiers/swap/constexpr.cc -std=gnu++20
> > > > > (test for excess errors)
> > > > > FAIL: 21_strings/basic_string/modifiers/swap/constexpr.cc -std=gnu++26
> > > > > (test for excess errors)
> > > > > FAIL: std/ranges/adaptors/join_with/1.cc -std=gnu++23 (test for excess
> > > > > errors)
> > > > > UNRESOLVED: std/ranges/adaptors/join_with/1.cc -std=gnu++23 
> > > > > compilation
> > > > > failed to produce executable
> > > > > FAIL: std/ranges/adaptors/join_with/1.cc -std=gnu++26 (test for excess
> > > > > errors)
> > > > > UNRESOLVED: std/ranges/adaptors/join_with/1.cc -std=gnu++26 
> > > > > compilation
> > > > > failed to produce executable
> > > > >
> > > > > On investigation though it looks like the issue might be with 
> > > > > libstdc++
> > > > > rather than the patch itself; running the failing tests using clang 
> > > > > with
> > > > > libstdc++ also produces similar errors, and my reading of the code
> > > > > suggests that this is correct.
> > > > >
> > > > > What's the way forward here? Should I look at creating a patch to fix
> > > > > the libstdc++ issues before resubmitting this patch for the C++
> > > > > frontend? Or should I submit a version of this patch without the
> > > > > `std::construct_at` changes and wait till libstdc++ gets fixed for 
> > > > > that?
> > > > >
> > > >
> > > > I think we should fix libstdc++. There are probably only a few places 
> > > > that
> > > > need a fix, which cause all those failures.
> > > >
> > > > I can help with those fixes. I'll look into it after the weekend.
> > > >
> > >
> > > Thanks. I did end up getting a chance to look at it earlier today, and
> > > with the following patch I had no regressions when applying the frontend
> > > changes. Bootstrapped and regtested on x86_64-pc-linux-gnu.
> > >
> > > -- >8 --
> > >
> > > This patch ensures that the union members for std::string and
> > > std::variant are always properly set when a change occurs.
> > >
> > > libstdc++-v3/ChangeLog:
> > >
> > > * include/bits/basic_string.h: (basic_string(basic_string&&)):
> > > Activate _M_local_buf

Re: [PATCH] [11/12/13/14 Regression] ABI break in _Hash_node_value_base since GCC 11 [PR 111050]

2023-09-29 Thread Jonathan Wakely
On Thu, 28 Sept 2023 at 18:25, François Dumont  wrote:
>
>
> On 28/09/2023 18:18, Jonathan Wakely wrote:
> > On Wed, 27 Sept 2023 at 05:44, François Dumont  wrote:
> >> Still no chance to get feedback from TC ? Maybe I can commit the below
> >> then ?
> > I've heard back from Tim now. Please use "Tim Song
> > " as the author.
> >
> > You can change the commit again using git commit --amend --author "Tim
> > Song "
>
> Sure :-)
>
> >
> > OK for trunk with that change - thanks for waiting.
>
> Committed to trunk, let me know for backports.

Please wait a few days in case of problems on the trunk (although I
don't expect any) and then OK for 11/12/13 too - thanks!


>
> >> AFAICS on gcc mailing list several gcc releases were done recently, too
> >> late.
> > There have been no releases this month, so the delay hasn't caused any 
> > problems.
>
> I was confused by emails like this one:
>
> https://gcc.gnu.org/pipermail/gcc/2023-September/242429.html
>
> I just subscribed to gcc mailing list, I had no idea there were regular
> snapshots like this.
>



Re: [PATCH] vec.h, v3: Make some ops work with non-trivially copy constructible and/or destructible types

2023-09-29 Thread Jonathan Wakely
On Thu, 28 Sept 2023 at 10:17, Jakub Jelinek  wrote:
>
> Hi!
>
> On Wed, Sep 27, 2023 at 12:46:45PM +0200, Jakub Jelinek wrote:
> > On Wed, Sep 27, 2023 at 07:17:22AM +, Richard Biener wrote:
> > > OK I guess.  Can you summarize the limitations for non-POD types
> > > in the big comment at the start of vec.h?
> >
> > Still haven't done that, but will do after we flesh out the details
> > below.
> >
> > > (can we put in static_asserts
> > > in the places that obviously do not work?)
> >
> > I've tried to do this though, I think the static_asserts will allow
> > making sure we only use what is supportable and will serve better than
> > any kind of comment.
>
> The following patch adds the file comment, as discussed on IRC adds an
> exception for qsort/sort/stablesort such that std::pair of 2 trivially
> copyable types is also allowed, and fixes some of the grow vs. grow_cleared
> issues (on top of the bitmap_head_pod patch far more), but still not all
> yet, so I've kept that static_assert for now commented out.  Richard
> Sandiford said he's playing with poly_int_pod vs. poly_int and I'll resolve
> the remaining stuff incrementally afterwards plus enable the assert.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2023-09-28  Jakub Jelinek  
> Jonathan Wakely  
>
> * vec.h: Mention in file comment limited support for non-POD types
> in some operations.
> (vec_destruct): New function template.
> (release): Use it for non-trivially destructible T.
> (truncate): Likewise.
> (quick_push): Perform a placement new into slot
> instead of assignment.
> (pop): For non-trivially destructible T return void
> rather than T & and destruct the popped element.
> (quick_insert, ordered_remove): Note that they aren't suitable
> for non-trivially copyable types.  Add static_asserts for that.
> (block_remove): Assert T is trivially copyable.
> (vec_detail::is_trivially_copyable_or_pair): New trait.
> (qsort, sort, stablesort): Assert T is trivially copyable or
> std::pair with both trivally copyable types.
> (quick_grow): Add assert T is trivially default constructible,
> for now commented out.
> (quick_grow_cleared): Don't call quick_grow, instead inline it
> by hand except for the new static_assert.
> (gt_ggc_mx): Assert T is trivially destructable.
> (auto_vec::operator=): Formatting fixes.
> (auto_vec::auto_vec): Likewise.
> (vec_safe_grow_cleared): Don't call vec_safe_grow, instead inline
> it manually and call quick_grow_cleared method rather than quick_grow.
> (safe_grow_cleared): Likewise.
> * edit-context.cc (class line_event): Move definition earlier.
> * tree-ssa-loop-im.cc (seq_entry::seq_entry): Make default ctor
> defaulted.
> * ipa-fnsummary.cc (evaluate_properties_for_edge): Use
> safe_grow_cleared instead of safe_grow followed by placement new
> constructing the elements.
>
> --- gcc/vec.h.jj2023-09-27 10:38:50.635845540 +0200
> +++ gcc/vec.h   2023-09-28 11:05:14.776215137 +0200
> @@ -111,6 +111,24 @@ extern void *ggc_realloc (void *, size_t
> the 'space' predicate will tell you whether there is spare capacity
> in the vector.  You will not normally need to use these two functions.
>
> +   Not all vector operations support non-POD types and such restrictions
> +   are enforced through static assertions.  Some operations which often use
> +   memmove to move elements around like quick_insert, safe_insert,
> +   ordered_remove, unordered_remove, block_remove etc. require trivially
> +   copyable types.  Sorting operations, qsort, sort and stablesort, require
> +   those too but as an extension allow also std::pair of 2 trivially copyable
> +   types which happens to work even when std::pair itself isn't trivially
> +   copyable.  The quick_grow and safe_grow operations require trivially
> +   default constructible types.  One can use quick_grow_cleared or
> +   safe_grow_cleared for non-trivially default constructible types if needed
> +   (but of course such operation is more expensive then).  The pop operation
> +   returns reference to the last element only for trivially destructible
> +   types, for non-trivially destructible types one should use last operation
> +   followed by pop which in that case returns void.
> +   And finally, the GC and GC atomic vectors should always be used with
> +   trivially destructible types, as nothing will in

Re: Fix compilation errors with libstdc++v3 for AVR target and allow --enable-libstdcxx

2023-09-29 Thread Jonathan Wakely
On Tue, 6 Dec 2016 at 17:59, Jonathan Wakely wrote:
> >Subject: [PATCH 3/3] Enable libstdc++ compilation in AVR targets
> >
> >Enable libstdc++ compilation in AVR targets with AVR-Libc. Most
> >floating point math functions are already defined in AVR-Libc, so
> >defines are in place to avoid multiple definition of these functions.
>
> I've committed this one too.


Hi Felipe,

Back in 2006 we committed a patch from you that made this change:

--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -9,6 +9,32 @@ case "${host}" in
 # This is a freestanding configuration; there is nothing to do here.
 ;;

+  avr*-*-*)
+AC_DEFINE(HAVE_ACOSF)
+AC_DEFINE(HAVE_ASINF)
+AC_DEFINE(HAVE_ATAN2F)
+AC_DEFINE(HAVE_ATANF)
+AC_DEFINE(HAVE_CEILF)
+AC_DEFINE(HAVE_COSF)
+AC_DEFINE(HAVE_COSHF)
+AC_DEFINE(HAVE_EXPF)
+AC_DEFINE(HAVE_FABSF)
+AC_DEFINE(HAVE_FLOORF)
+AC_DEFINE(HAVE_FMODF)
+AC_DEFINE(HAVE_FREXPF)
+AC_DEFINE(HAVE_SQRTF)
+AC_DEFINE(HAVE_HYPOTF)
+AC_DEFINE(HAVE_LDEXPF)
+AC_DEFINE(HAVE_LOG10F)
+AC_DEFINE(HAVE_LOGF)
+AC_DEFINE(HAVE_MODFF)
+AC_DEFINE(HAVE_POWF)
+AC_DEFINE(HAVE_SINF)
+AC_DEFINE(HAVE_SINHF)
+AC_DEFINE(HAVE_TANF)
+AC_DEFINE(HAVE_TANHF)
+;;
+
   mips*-sde-elf*)
 # These definitions are for the SDE C library rather than newlib.
 SECTION_FLAGS='-ffunction-sections -fdata-sections'

I'm testing a change today which causes a build failure on avr,
because of your config change.

I've filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111639 about
this, could you take a look please?

You said that AVR has those math functions, so we don't need to define
them in libstdc++-v3/src/c++98/math_stubs_float.cc but I don't think
that's true. It doesn't have them, it has macros like this:

extern double acos(double __x) __ATTR_CONST__;
#define acosfacos/**< The alias for acos().*/

That does indeed cause build failures in math_stubs_float.cc, but not
because of duplicate definitions of acosf etc.

And the macro definitions are not acceptable definitions of those
functions for a C++ library.

I've proposed a fix in the bug report.



Re: Fix compilation errors with libstdc++v3 for AVR target and allow --enable-libstdcxx

2023-09-29 Thread Jonathan Wakely
On Fri, 29 Sept 2023 at 15:07, Jonathan Wakely  wrote:
>
> On Tue, 6 Dec 2016 at 17:59, Jonathan Wakely wrote:
> > >Subject: [PATCH 3/3] Enable libstdc++ compilation in AVR targets
> > >
> > >Enable libstdc++ compilation in AVR targets with AVR-Libc. Most
> > >floating point math functions are already defined in AVR-Libc, so
> > >defines are in place to avoid multiple definition of these functions.
> >
> > I've committed this one too.
>
>
> Hi Felipe,
>
> Back in 2006 we committed a patch from you that made this change:

Oops, sorry for the typo, I meant 2016 of course!


>
> --- a/libstdc++-v3/crossconfig.m4
> +++ b/libstdc++-v3/crossconfig.m4
> @@ -9,6 +9,32 @@ case "${host}" in
>  # This is a freestanding configuration; there is nothing to do here.
>  ;;
>
> +  avr*-*-*)
> +AC_DEFINE(HAVE_ACOSF)
> +AC_DEFINE(HAVE_ASINF)
> +AC_DEFINE(HAVE_ATAN2F)
> +AC_DEFINE(HAVE_ATANF)
> +AC_DEFINE(HAVE_CEILF)
> +AC_DEFINE(HAVE_COSF)
> +AC_DEFINE(HAVE_COSHF)
> +AC_DEFINE(HAVE_EXPF)
> +AC_DEFINE(HAVE_FABSF)
> +AC_DEFINE(HAVE_FLOORF)
> +AC_DEFINE(HAVE_FMODF)
> +AC_DEFINE(HAVE_FREXPF)
> +AC_DEFINE(HAVE_SQRTF)
> +AC_DEFINE(HAVE_HYPOTF)
> +AC_DEFINE(HAVE_LDEXPF)
> +AC_DEFINE(HAVE_LOG10F)
> +AC_DEFINE(HAVE_LOGF)
> +AC_DEFINE(HAVE_MODFF)
> +AC_DEFINE(HAVE_POWF)
> +AC_DEFINE(HAVE_SINF)
> +AC_DEFINE(HAVE_SINHF)
> +AC_DEFINE(HAVE_TANF)
> +AC_DEFINE(HAVE_TANHF)
> +;;
> +
>mips*-sde-elf*)
>  # These definitions are for the SDE C library rather than newlib.
>  SECTION_FLAGS='-ffunction-sections -fdata-sections'
>
> I'm testing a change today which causes a build failure on avr,
> because of your config change.
>
> I've filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111639 about
> this, could you take a look please?
>
> You said that AVR has those math functions, so we don't need to define
> them in libstdc++-v3/src/c++98/math_stubs_float.cc but I don't think
> that's true. It doesn't have them, it has macros like this:
>
> extern double acos(double __x) __ATTR_CONST__;
> #define acosfacos/**< The alias for acos().*/
>
> That does indeed cause build failures in math_stubs_float.cc, but not
> because of duplicate definitions of acosf etc.
>
> And the macro definitions are not acceptable definitions of those
> functions for a C++ library.
>
> I've proposed a fix in the bug report.



Re: [PATCH v3] libstdc++: Fix handling of surrogate CP in codecvt [PR108976]

2023-09-29 Thread Jonathan Wakely
On Thu, 28 Sept 2023 at 20:39, Dimitrij Mijoski via Libstdc++
 wrote:
>
> This patch fixes the handling of surrogate code points in all standard
> facets for transcoding Unicode that are based on std::codecvt. Surrogate
> code points should always be treated as error. On the other hand
> surrogate code units can only appear in UTF-16 and only when they come
> in a proper pair.
>
> Additionally, it fixes a bug in std::codecvt_utf16::in() when odd number
> of bytes were given in the range [from, from_end), error was returned
> always. The last byte in such range does not form a full UTF-16 code
> unit and we can not make any decisions for error, instead partial should
> be returned.
>
> The testsuite for testing these facets was updated in the following
> order:
>
> 1. All functions that test codecvts that work with UTF-8 were refactored
>and made more generic so they accept codecvt that works with the char
>type char8_t.
> 2. The same functions were updated with new test cases for transcoding
>errors and now additionally test for surrogates, overlong UTF-8
>sequences, code points out of the Unicode range, and more tests for
>missing leading and trailing code units.
> 3. New tests were added to test codecvt_utf16 in both of its variants,
>UTF-16 <-> UTF-32/UCS-4 and UTF-16 <-> UCS-2.
>
> libstdc++-v3/ChangeLog:
>
> * src/c++11/codecvt.cc (read_utf8_code_point): Fix handing of
> surrogates in UTF-8.
> (ucs4_out): Fix handling of surrogates in UCS-4 -> UTF-8.
> (ucs4_in): Fix handling of range with odd number of bytes.
> (ucs4_out): Fix handling of surrogates in UCS-4 -> UTF-16.
> (ucs2_out): Fix handling of surrogates in UCS-2 -> UTF-16.
> (ucs2_in): Fix handling of range with odd number of bytes.
> (__codecvt_utf16_base::do_in): Likewise.
> (__codecvt_utf16_base::do_in): Likewise.
> (__codecvt_utf16_base::do_in): Likewise.
> * testsuite/22_locale/codecvt/codecvt_unicode.cc: Renames, add
> tests for codecvt_utf16 and codecvt_utf16.
> * testsuite/22_locale/codecvt/codecvt_unicode.h: Refactor UTF-8
> testing functions for char8_t, add more test cases for errors,
> add testing functions for codecvt_utf16.
> * testsuite/22_locale/codecvt/codecvt_unicode_wchar_t.cc:
> Renames, add tests for codecvt_utf16.
> * testsuite/22_locale/codecvt/codecvt_utf16/79980.cc (test06):
> Fix test.
> * testsuite/22_locale/codecvt/codecvt_unicode_char8_t.cc: New test.

Thanks, your v2 patch was still on my TODO list. I've pushed this
version to trunk now.



Re: [PATCH] libstdc++: Ensure active union member is correctly set

2023-09-29 Thread Jonathan Wakely
On Fri, 29 Sept 2023 at 10:32, Jonathan Wakely  wrote:
> > Thanks for the comments, here's an updated version of the patch.
> > Bootstrapped and regtested on x86_64-pc-linux-gnu.
>
> Great, I'll get this committed today - thanks!

That's done now.

> >
> > I'll note that there are some existing calls to `_M_use_local_data()`
> > already used only for their side effects without a cast to void, e.g.
> >
> >   /**
> >*  @brief  Default constructor creates an empty string.
> >*/
> >   _GLIBCXX20_CONSTEXPR
> >   basic_string()
> >   _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)
> >   : _M_dataplus(_M_local_data())
> >   {
> > _M_use_local_data();
> > _M_set_length(0);
> >   }
> >
> > I haven't updated these, but should this be changed for consistency?
>
> Yes, good idea. I can do that.

I started to do that, and decided it made more sense to split out the
constexpr loop from _M_use_local_data() into a separate function,
_M_init_local_buf(). Then we can use that for all the places where we
don't care about the return value. That avoids the overhead of using
pointer_traits::pointer_to when we don't need the return value (which
is admittedly only going to be an issue for -O0 code, but I think it's
cleaner this way anyway).

Please see the attached patch and let me know what you think.


> Thanks again for fixing these. I think this might fix some bug reports
> about clang rejecting our std::string in constant expressions, so I'll
> check those.

Your patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110900
(so we should backport it to gcc-13 and gcc-12 too).
commit 2668979d3206ff6c039ac0165aae29377a15666c
Author: Jonathan Wakely 
Date:   Fri Sep 29 12:12:22 2023

libstdc++: Split std::basic_string::_M_use_local_data into two functions

This splits out the activate-the-union-member-for-constexpr logic from
_M_use_local_data, so that it can be used separately in cases that don't
need to use std::pointer_traits::pointer_to to obtain the
return value.

This leaves only three uses of _M_use_local_data() which are all the
same form:

  __s._M_data(_M_use_local_data());
  __s._M_set_length(0);

We could remove _M_use_local_data() and change those three places to use
a new _M_reset() function that does:

  _M_init_local_buf();
  _M_data(_M_local_data());
  _M_set_length(0);

This is left for a future change.

libstdc++-v3/ChangeLog:

* include/bits/basic_string.h (_M_init_local_buf()): New
function.
(_M_use_local_data()): Use _M_init_local_buf.
(basic_string(), basic_string(const Alloc&))
(basic_string(basic_string&&))
(basic_string(basic_string&&, const Alloc&)): Use
_M_init_local_buf instead of _M_use_local_data().
* include/bits/basic_string.tcc (swap(basic_string&))
(_M_construct(InIter, InIter, forward_iterator_tag))
(_M_construct(size_type, CharT), reserve()): Likewise.
(_M_construct(InIter, InIter, input_iterator_tag)): Remove call
to _M_use_local_data() and initialize the local buffer directly.

diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index 4f94cd967cf..18a19b8dcbc 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -353,13 +353,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   // Ensure that _M_local_buf is the active member of the union.
   __attribute__((__always_inline__))
   _GLIBCXX14_CONSTEXPR
-  pointer
-  _M_use_local_data() _GLIBCXX_NOEXCEPT
+  void
+  _M_init_local_buf() _GLIBCXX_NOEXCEPT
   {
 #if __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
  for (size_type __i = 0; __i <= _S_local_capacity; ++__i)
_M_local_buf[__i] = _CharT();
+#endif
+  }
+
+  __attribute__((__always_inline__))
+  _GLIBCXX14_CONSTEXPR
+  pointer
+  _M_use_local_data() _GLIBCXX_NOEXCEPT
+  {
+#if __glibcxx_is_constant_evaluated
+   _M_init_local_buf();
 #endif
return _M_local_data();
   }
@@ -522,7 +532,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)
   : _M_dataplus(_M_local_data())
   {
-   _M_use_local_data();
+   _M_init_local_buf();
_M_set_length(0);
   }
 
@@ -534,7 +544,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT
   : _M_dataplus(_M_local_data(), __a)
   {
-   _M_use_local_data();
+  

Re: [PATCH] libstdc++: Ensure active union member is correctly set

2023-09-29 Thread Jonathan Wakely
On Fri, 29 Sept 2023 at 17:29, Nathaniel Shead
 wrote:
>
> On Fri, Sep 29, 2023 at 04:06:33PM +0100, Jonathan Wakely wrote:
> > On Fri, 29 Sept 2023 at 10:32, Jonathan Wakely  wrote:
> > > > Thanks for the comments, here's an updated version of the patch.
> > > > Bootstrapped and regtested on x86_64-pc-linux-gnu.
> > >
> > > Great, I'll get this committed today - thanks!
> >
> > That's done now.
> >
>
> Thanks!
>
> > > >
> > > > I'll note that there are some existing calls to `_M_use_local_data()`
> > > > already used only for their side effects without a cast to void, e.g.
> > > >
> > > >   /**
> > > >*  @brief  Default constructor creates an empty string.
> > > >*/
> > > >   _GLIBCXX20_CONSTEXPR
> > > >   basic_string()
> > > >   
> > > > _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value)
> > > >   : _M_dataplus(_M_local_data())
> > > >   {
> > > > _M_use_local_data();
> > > > _M_set_length(0);
> > > >   }
> > > >
> > > > I haven't updated these, but should this be changed for consistency?
> > >
> > > Yes, good idea. I can do that.
> >
> > I started to do that, and decided it made more sense to split out the
> > constexpr loop from _M_use_local_data() into a separate function,
> > _M_init_local_buf(). Then we can use that for all the places where we
> > don't care about the return value. That avoids the overhead of using
> > pointer_traits::pointer_to when we don't need the return value (which
> > is admittedly only going to be an issue for -O0 code, but I think it's
> > cleaner this way anyway).
> >
> > Please see the attached patch and let me know what you think.
>
> I agree, and it also looks clearer to me what is happening.

Good, I'll make this change next week then.


>
> >
> > > Thanks again for fixing these. I think this might fix some bug reports
> > > about clang rejecting our std::string in constant expressions, so I'll
> > > check those.
> >
> > Your patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110900
> > (so we should backport it to gcc-13 and gcc-12 too).
>
> > commit 2668979d3206ff6c039ac0165aae29377a15666c
> > Author: Jonathan Wakely 
> > Date:   Fri Sep 29 12:12:22 2023
> >
> > libstdc++: Split std::basic_string::_M_use_local_data into two functions
> >
> > This splits out the activate-the-union-member-for-constexpr logic from
> > _M_use_local_data, so that it can be used separately in cases that don't
> > need to use std::pointer_traits::pointer_to to obtain the
> > return value.
> >
> > This leaves only three uses of _M_use_local_data() which are all the
> > same form:
> >
> >   __s._M_data(_M_use_local_data());
> >   __s._M_set_length(0);
> >
> > We could remove _M_use_local_data() and change those three places to use
> > a new _M_reset() function that does:
> >
> >   _M_init_local_buf();
> >   _M_data(_M_local_data());
> >   _M_set_length(0);
> >
> > This is left for a future change.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/bits/basic_string.h (_M_init_local_buf()): New
> > function.
> > (_M_use_local_data()): Use _M_init_local_buf.
> > (basic_string(), basic_string(const Alloc&))
> > (basic_string(basic_string&&))
> > (basic_string(basic_string&&, const Alloc&)): Use
> > _M_init_local_buf instead of _M_use_local_data().
> > * include/bits/basic_string.tcc (swap(basic_string&))
> > (_M_construct(InIter, InIter, forward_iterator_tag))
> > (_M_construct(size_type, CharT), reserve()): Likewise.
> > (_M_construct(InIter, InIter, input_iterator_tag)): Remove call
> > to _M_use_local_data() and initialize the local buffer directly.
> >
> > diff --git a/libstdc++-v3/include/bits/basic_string.h 
> > b/libstdc++-v3/include/bits/basic_string.h
> > index 4f94cd967cf..18a19b8dcbc 100644
> > --- a/libstdc++-v3/include/bits/basic_string.h
> > +++ b/libstdc++-v3/include/bits/basic_string.h
> > @@ -353,13 +353,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
> >// Ensure that _M_local_

Re: [PATCH] Fix coroutine tests for libstdc++ gnu-version-namespace mode

2023-10-03 Thread Jonathan Wakely
On Mon, 2 Oct 2023 at 18:07, François Dumont  wrote:
>
> Hi
>
> Gentle reminder for this minor patch.

It looks like you attached the wrong patch.


>
> Thanks
>
> On 23/09/2023 22:10, François Dumont wrote:
> > I'm eventually fixing those tests the same way we manage this problem
> > in libstdc++ testsuite.
> >
> >testsuite: Add optional libstdc++ version namespace in expected
> > diagnostic
> >
> > When libstdc++ is build with
> > --enable-symvers=gnu-versioned-namespace diagnostics are
> > showing this namespace, currently __8.
> >
> > gcc/testsuite/ChangeLog:
> >
> > *
> > testsuite/g++.dg/coroutines/coro-bad-alloc-00-bad-op-new.C: Add optional
> > '__8' version namespace in expected diagnostic.
> > *
> > testsuite/g++.dg/coroutines/coro-bad-alloc-01-bad-op-del.C: Likewise.
> > *
> > testsuite/g++.dg/coroutines/coro-bad-alloc-02-no-op-new-nt.C: Likewise.
> > *
> > testsuite/g++.dg/coroutines/coro-bad-grooaf-01-grooaf-expected.C:
> > Likewise.
> > * testsuite/g++.dg/coroutines/pr97438.C: Likewise.
> > * testsuite/g++.dg/coroutines/ramp-return-b.C: Likewise.
> >
> > Tested under Linux x86_64.
> >
> > I'm contributing to libstdc++ so I already have write access.
> >
> > Ok to commit ?
> >
> > François


Re: [PATCH 2/2] libstdc++: _versioned_namespace is always non-None

2023-10-03 Thread Jonathan Wakely
On Tue, 3 Oct 2023, 19:27 Tom Tromey,  wrote:

> Some code in the pretty-printers seems to assume that the
> _versioned_namespace global might be None (or the empty string).
> However, doesn't occur, as the variable is never reassigned.
>

ok for trunk, but we should just remove that bit from xmethods.py as the
variable is never even set in that file.



> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py: Assume that
> _versioned_namespace is non-None.
> * python/libstdcxx/v6/xmethods.py (is_specialization_of):
> Assume that _versioned_namespace is non-None.
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 15 ++-
>  libstdc++-v3/python/libstdcxx/v6/xmethods.py |  3 +--
>  2 files changed, 7 insertions(+), 11 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 23efbd171ec..e370551cbe1 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -139,7 +139,7 @@ def lookup_templ_spec(templ, *args):
>  except gdb.error as e:
>  # Type not found, try again in versioned namespace.
>  global _versioned_namespace
> -if _versioned_namespace and _versioned_namespace not in templ:
> +if _versioned_namespace not in templ:
>  t = t.replace('::', '::' + _versioned_namespace, 1)
>  try:
>  return gdb.lookup_type(t)
> @@ -211,16 +211,13 @@ def is_specialization_of(x, template_name):
>  global _versioned_namespace
>  if isinstance(x, gdb.Type):
>  x = x.tag
> -if _versioned_namespace:
> -template_name = '(%s)?%s' % (_versioned_namespace, template_name)
> +template_name = '(%s)?%s' % (_versioned_namespace, template_name)
>  return re.match('^std::%s<.*>$' % template_name, x) is not None
>
>
>  def strip_versioned_namespace(typename):
>  global _versioned_namespace
> -if _versioned_namespace:
> -return typename.replace(_versioned_namespace, '')
> -return typename
> +return typename.replace(_versioned_namespace, '')
>
>
>  def strip_inline_namespaces(type_str):
> @@ -2355,7 +2352,7 @@ class Printer(object):
>  # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
>  def add_version(self, base, name, function):
>  self.add(base + name, function)
> -if _versioned_namespace and '__cxx11' not in base:
> +if '__cxx11' not in base:
>  vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
> _versioned_namespace, base)
>  self.add(vbase + name, function)
> @@ -2527,7 +2524,7 @@ def add_one_template_type_printer(obj, name,
> defargs):
>  printer = TemplateTypePrinter('std::__debug::' + name, defargs)
>  gdb.types.register_type_printer(obj, printer)
>
> -if _versioned_namespace and '__cxx11' not in name:
> +if '__cxx11' not in name:
>  # Add second type printer for same type in versioned namespace:
>  ns = 'std::' + _versioned_namespace
>  # PR 86112 Cannot use dict comprehension here:
> @@ -2628,7 +2625,7 @@ class FilteringTypePrinter(object):
>  def add_one_type_printer(obj, template, name, targ1=None):
>  printer = FilteringTypePrinter('std::' + template, 'std::' + name,
> targ1)
>  gdb.types.register_type_printer(obj, printer)
> -if _versioned_namespace and '__cxx11' not in template:
> +if '__cxx11' not in template:
>  ns = 'std::' + _versioned_namespace
>  printer = FilteringTypePrinter(ns + template, ns + name, targ1)
>  gdb.types.register_type_printer(obj, printer)
> diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> index 8ccf57c4d6b..42e60eb57b1 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> @@ -39,8 +39,7 @@ def is_specialization_of(x, template_name):
>  """
>  if isinstance(x, gdb.Type):
>  x = x.tag
> -if _versioned_namespace:
> -template_name = '(%s)?%s' % (_versioned_namespace, template_name)
> +template_name = '(%s)?%s' % (_versioned_namespace, template_name)
>  return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not
> None
>
>  class LibStdCxxXMethod(gdb.xmethod.XMethod):
> --
> 2.40.1
>
>


Re: [PATCH 2/2] libstdc++: _versioned_namespace is always non-None

2023-10-03 Thread Jonathan Wakely
On Tue, 3 Oct 2023, 23:55 Jonathan Wakely,  wrote:

>
>
> On Tue, 3 Oct 2023, 19:27 Tom Tromey,  wrote:
>
>> Some code in the pretty-printers seems to assume that the
>> _versioned_namespace global might be None (or the empty string).
>> However, doesn't occur, as the variable is never reassigned.
>>
>
> ok for trunk, but we should just remove that bit from xmethods.py as the
> variable is never even set in that file.
>

Oh I see you already addressed that in another patch :-)


>
>
>> libstdc++-v3/ChangeLog:
>>
>> * python/libstdcxx/v6/printers.py: Assume that
>> _versioned_namespace is non-None.
>> * python/libstdcxx/v6/xmethods.py (is_specialization_of):
>> Assume that _versioned_namespace is non-None.
>> ---
>>  libstdc++-v3/python/libstdcxx/v6/printers.py | 15 ++-
>>  libstdc++-v3/python/libstdcxx/v6/xmethods.py |  3 +--
>>  2 files changed, 7 insertions(+), 11 deletions(-)
>>
>> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
>> b/libstdc++-v3/python/libstdcxx/v6/printers.py
>> index 23efbd171ec..e370551cbe1 100644
>> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
>> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
>> @@ -139,7 +139,7 @@ def lookup_templ_spec(templ, *args):
>>  except gdb.error as e:
>>  # Type not found, try again in versioned namespace.
>>  global _versioned_namespace
>> -if _versioned_namespace and _versioned_namespace not in templ:
>> +if _versioned_namespace not in templ:
>>  t = t.replace('::', '::' + _versioned_namespace, 1)
>>  try:
>>  return gdb.lookup_type(t)
>> @@ -211,16 +211,13 @@ def is_specialization_of(x, template_name):
>>  global _versioned_namespace
>>  if isinstance(x, gdb.Type):
>>  x = x.tag
>> -if _versioned_namespace:
>> -template_name = '(%s)?%s' % (_versioned_namespace, template_name)
>> +template_name = '(%s)?%s' % (_versioned_namespace, template_name)
>>  return re.match('^std::%s<.*>$' % template_name, x) is not None
>>
>>
>>  def strip_versioned_namespace(typename):
>>  global _versioned_namespace
>> -if _versioned_namespace:
>> -return typename.replace(_versioned_namespace, '')
>> -return typename
>> +return typename.replace(_versioned_namespace, '')
>>
>>
>>  def strip_inline_namespaces(type_str):
>> @@ -2355,7 +2352,7 @@ class Printer(object):
>>  # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
>>  def add_version(self, base, name, function):
>>  self.add(base + name, function)
>> -if _versioned_namespace and '__cxx11' not in base:
>> +if '__cxx11' not in base:
>>  vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
>> _versioned_namespace, base)
>>  self.add(vbase + name, function)
>> @@ -2527,7 +2524,7 @@ def add_one_template_type_printer(obj, name,
>> defargs):
>>  printer = TemplateTypePrinter('std::__debug::' + name, defargs)
>>  gdb.types.register_type_printer(obj, printer)
>>
>> -if _versioned_namespace and '__cxx11' not in name:
>> +if '__cxx11' not in name:
>>  # Add second type printer for same type in versioned namespace:
>>  ns = 'std::' + _versioned_namespace
>>  # PR 86112 Cannot use dict comprehension here:
>> @@ -2628,7 +2625,7 @@ class FilteringTypePrinter(object):
>>  def add_one_type_printer(obj, template, name, targ1=None):
>>  printer = FilteringTypePrinter('std::' + template, 'std::' + name,
>> targ1)
>>  gdb.types.register_type_printer(obj, printer)
>> -if _versioned_namespace and '__cxx11' not in template:
>> +if '__cxx11' not in template:
>>  ns = 'std::' + _versioned_namespace
>>  printer = FilteringTypePrinter(ns + template, ns + name, targ1)
>>  gdb.types.register_type_printer(obj, printer)
>> diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
>> b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
>> index 8ccf57c4d6b..42e60eb57b1 100644
>> --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
>> +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
>> @@ -39,8 +39,7 @@ def is_specialization_of(x, template_name):
>>  """
>>  if isinstance(x, gdb.Type):
>>  x = x.tag
>> -if _versioned_namespace:
>> -template_name = '(%s)?%s' % (_versioned_namespace, template_name)
>> +template_name = '(%s)?%s' % (_versioned_namespace, template_name)
>>  return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not
>> None
>>
>>  class LibStdCxxXMethod(gdb.xmethod.XMethod):
>> --
>> 2.40.1
>>
>>


Re: [PATCH 1/2] libstdc++: Define _versioned_namespace in xmethods.py

2023-10-03 Thread Jonathan Wakely
On Tue, 3 Oct 2023, 18:19 Tom Tromey,  wrote:

> flake8 pointed out that is_specialization_of in xmethods.py looks at a
> global that wasn't added to the file.  This patch correct the
> oversight.
>

OK, thanks



>
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/xmethods.py (_versioned_namespace):
> Define.
> ---
>  libstdc++-v3/python/libstdcxx/v6/xmethods.py | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> index 844c8a2105a..8ccf57c4d6b 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> @@ -28,6 +28,8 @@ def get_bool_type():
>  def get_std_size_type():
>  return gdb.lookup_type('std::size_t')
>
> +_versioned_namespace = '__8::'
> +
>  def is_specialization_of(x, template_name):
>  """
>  Test whether a type is a specialization of the named class template.
> --
> 2.40.1
>
>


Re: [PATCH 1/2] testsuite: Add dg-require-atomic-exchange non-atomic code

2023-10-04 Thread Jonathan Wakely
On Wed, 4 Oct 2023 at 03:56, Hans-Peter Nilsson  wrote:
>
> > From: Christophe Lyon 
> > Date: Tue, 3 Oct 2023 15:20:39 +0200
>
> > Maybe we need a new variant of dg-require-thread-fence ?
>
> Yes: many of the dg-require-thread-fence users need
> something stronger.  Tested arm-eabi together with the next
> patch (2/2) with
> RUNTESTFLAGS=--target_board=arm-sim/-mthumb/-march=armv6s-m/-mtune=cortex-m0/-mfloat-abi=soft/-mfpu=auto\
> conformance.exp=29_atomics/\*
>
> (Incidentally, in the patch context is seen
> dg-require-atomic-builtins which is a misnomer: it should
> rather be named "dg-require-lock-atomic-builtins-free".)

dg-require-lock-free-atomic-builtins or
dg-require-atomic-builtins-lock-free, surely?


>
> Ok to commit?
>
> -- >8 --
> Some targets (armv6) support inline atomic load and store,
> i.e. dg-require-thread-fence matches, but not atomic like
> atomic exchange.  This directive will replace uses of
> dg-require-thread-fence where an atomic exchange operation
> is actually used.
>
> * testsuite/lib/dg-options.exp (dg-require-atomic-exchange): New proc.
> * testsuite/lib/libstdc++.exp (check_v3_target_atomic_exchange): 
> Ditto.

OK

> ---
>  libstdc++-v3/testsuite/lib/dg-options.exp |  9 ++
>  libstdc++-v3/testsuite/lib/libstdc++.exp  | 35 +++
>  2 files changed, 44 insertions(+)
>
> diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp 
> b/libstdc++-v3/testsuite/lib/dg-options.exp
> index 84ad0c65330b..b13c2f244c63 100644
> --- a/libstdc++-v3/testsuite/lib/dg-options.exp
> +++ b/libstdc++-v3/testsuite/lib/dg-options.exp
> @@ -133,6 +133,15 @@ proc dg-require-thread-fence { args } {
>  return
>  }
>
> +proc dg-require-atomic-exchange { args } {
> +if { ![ check_v3_target_atomic_exchange ] } {
> +   upvar dg-do-what dg-do-what
> +   set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
> +   return
> +}
> +return
> +}
> +
>  proc dg-require-atomic-builtins { args } {
>  if { ![ check_v3_target_atomic_builtins ] } {
> upvar dg-do-what dg-do-what
> diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp 
> b/libstdc++-v3/testsuite/lib/libstdc++.exp
> index 608056e5068e..481f81711074 100644
> --- a/libstdc++-v3/testsuite/lib/libstdc++.exp
> +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
> @@ -1221,6 +1221,41 @@ proc check_v3_target_thread_fence { } {
>  }]
>  }
>
> +proc check_v3_target_atomic_exchange { } {
> +return [check_v3_target_prop_cached et_atomic_exchange {
> +   global cxxflags
> +   global DEFAULT_CXXFLAGS
> +
> +   # Set up and link a C++11 test program that depends
> +   # on atomic exchange be available for "int".
> +   set src atomic_exchange[pid].cc
> +
> +   set f [open $src "w"]
> +   puts $f "
> +int i, j, k;
> +   int main() {
> +   __atomic_exchange (&i, &j, &k, __ATOMIC_SEQ_CST);
> +   return 0;
> +   }"
> +   close $f
> +
> +   set cxxflags_saved $cxxflags
> +   set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror -std=gnu++11"
> +
> +   set lines [v3_target_compile $src /dev/null executable ""]
> +   set cxxflags $cxxflags_saved
> +   file delete $src
> +
> +   if [string match "" $lines] {
> +   # No error message, linking succeeded.
> +   return 1
> +   } else {
> +   verbose "check_v3_target_atomic_exchange: compilation failed" 2
> +   return 0
> +   }
> +}]
> +}
> +
>  # Return 1 if atomics_bool and atomic_int are always lock-free, 0 otherwise.
>  proc check_v3_target_atomic_builtins { } {
>  return [check_v3_target_prop_cached et_atomic_builtins {
> --
> 2.30.2
>
>
> >
> > Thanks,
> >
> > Christophe
> >
> >
> > Ok to commit?
> > >
> > > -- >8 --
> > > Make __atomic_test_and_set consistent with other __atomic_ and __sync_
> > > builtins: call a matching library function instead of emitting
> > > non-atomic code when the target has no direct insn support.
> > >
> > > There's special-case code handling targetm.atomic_test_and_set_trueval
> > > != 1 trying a modified maybe_emit_sync_lock_test_and_set.  Previously,
> > > if that worked but its matching emit_store_flag_force returned NULL,
> > > we'd segfault later on.  Now that the caller handles NULL, gcc_assert
> > > here instead.
> > >
> > > While the referenced PR:s are ARM-specific, the issue is general.
> > >
> > > PR target/107567
> > > PR target/109166
> > > * builtins.cc (expand_builtin)  > > BUILT_IN_ATOMIC_TEST_AND_SET>:
> > > Handle failure from expand_builtin_atomic_test_and_set.
> > > * optabs.cc (expand_atomic_test_and_set): When all attempts fail 
> > > to
> > > generate atomic code through target support, return NULL
> > > instead of emitting non-atomic code.  Also, for code handling
> > > targetm.atomic_test_and_set_trueval != 1, gcc_assert result
> > > from calling emit_store_flag_force instead of returning NULL.
> > > 

Re: [PATCH 2/2] testsuite: Replace many dg-require-thread-fence with dg-require-atomic-exchange

2023-10-04 Thread Jonathan Wakely
On Wed, 4 Oct 2023 at 04:11, Hans-Peter Nilsson  wrote:
>
> > From: Christophe Lyon 
> > Date: Tue, 3 Oct 2023 15:20:39 +0200
>
> > The patch passed almost all our CI configurations, except arm-eabi when
> > testing with
> >  -mthumb/-march=armv6s-m/-mtune=cortex-m0/-mfloat-abi=soft/-mfpu=auto
> > where is causes these failures:
> > FAIL: 29_atomics/atomic_flag/clear/1.cc -std=gnu++17 (test for excess
> > errors)
> > UNRESOLVED: 29_atomics/atomic_flag/clear/1.cc -std=gnu++17 compilation
> > failed to produce executable
> > FAIL: 29_atomics/atomic_flag/cons/value_init.cc -std=gnu++20 (test for
> > excess errors)
> > UNRESOLVED: 29_atomics/atomic_flag/cons/value_init.cc -std=gnu++20
> > compilation failed to produce executable
> > FAIL: 29_atomics/atomic_flag/cons/value_init.cc -std=gnu++26 (test for
> > excess errors)
> > UNRESOLVED: 29_atomics/atomic_flag/cons/value_init.cc -std=gnu++26
> > compilation failed to produce executable
> > FAIL: 29_atomics/atomic_flag/test_and_set/explicit.cc -std=gnu++17 (test
> > for excess errors)
> > UNRESOLVED: 29_atomics/atomic_flag/test_and_set/explicit.cc -std=gnu++17
> > compilation failed to produce executable
> > FAIL: 29_atomics/atomic_flag/test_and_set/implicit.cc -std=gnu++17 (test
> > for excess errors)
> > UNRESOLVED: 29_atomics/atomic_flag/test_and_set/implicit.cc -std=gnu++17
> > compilation failed to produce executable
> >
> > The linker error is:
> > undefined reference to `__atomic_test_and_set'
>
> Here's 2/2, fixing those regressions by, after code
> inspection, gating those test-case users of
> dg-require-thread-fence that actually use not just
> atomic-load/store functionality, but a form of
> compare-exchange, including the test-and-set cases listed
> above as testsuite regressions.  That neatly includes the
> regressions above.

The new dg-require proc checks for __atomic_exchange, which is not the
same as compare-exchange, and not the same as test-and-set on
atomic_flag. Does it just happen to be true for arm that the presence
of __atomic_exchange also implies the other atomic operations?

The new proc also only tests it for int, which presumably means none
of these tests rely on atomics for long long being present. Some of
the tests use atomics on pointers, which should work for ILP32 targets
if atomics work on int, but the new dg-require-atomic-exchange isn't
sufficient to check that it will work for pointers on LP64 targets.

Maybe it happens to work today for the targets where we have issues,
but we seem to be assuming that there will be no LP64 targets where
these atomics are absent for 64-bit pointers. Are there supported
risc-v ISA subsets where that isn't true? And we're assuming that
__atomic_exchange being present implies all other ops are present,
which seems like a bad assumption to me. I would be more confident
testing for __atomic_compare_exchange, because with a wait-free CAS
you can implement any other atomic operation, but the same isn't true
for __atomic_exchange.

>
> Again, other libstdc++ test-cases should likely also use
> this gate, from what I see of "undefined references" in
> libstdc++.log.
>
> Tested together with 1/2.
> Ok to commit?
>
> (N.B. there was a stray suffix "non-atomic code" in the
> subject of 1/2; that's just a typo which will not be
> committed.)
>
> -- >8 --
> These tests actually use a form of atomic exchange, not just
> atomic loading and storing.  Some target have the latter,
> but not the former, yielding linker errors for missing
> library functions (and not supported by libatomic).
>
> This change is just for existing uses of
> dg-require-thread-fence.  It does not fix any other tests
> that should also be gated on dg-require-atomic-exchange.
>
> * testsuite/29_atomics/atomic/compare_exchange_padding.cc,
> testsuite/29_atomics/atomic_flag/clear/1.cc,
> testsuite/29_atomics/atomic_flag/cons/value_init.cc,
> testsuite/29_atomics/atomic_flag/test_and_set/explicit.cc,
> testsuite/29_atomics/atomic_flag/test_and_set/implicit.cc,
> testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc,
> testsuite/29_atomics/atomic_ref/generic.cc,
> testsuite/29_atomics/atomic_ref/integral.cc,
> testsuite/29_atomics/atomic_ref/pointer.cc: Replace
> dg-require-thread-fence with dg-require-atomic-exchange.
> ---
>  .../testsuite/29_atomics/atomic/compare_exchange_padding.cc | 2 +-
>  libstdc++-v3/testsuite/29_atomics/atomic_flag/clear/1.cc| 2 +-
>  .../testsuite/29_atomics/atomic_flag/cons/value_init.cc | 2 +-
>  .../testsuite/29_atomics/atomic_flag/test_and_set/explicit.cc   | 2 +-
>  .../testsuite/29_atomics/atomic_flag/test_and_set/implicit.cc   | 2 +-
>  .../testsuite/29_atomics/atomic_ref/compare_exchange_padding.cc | 2 +-
>  libstdc++-v3/testsuite/29_atomics/atomic_ref/generic.cc | 2 +-
>  libstdc++-v3/testsuite/29_atomics/atomic_ref/integral.cc| 2 +-
>  libstdc++-v3/testsuite/29_atomics/atomic_ref/po

[committed,gcc-11] libstdc++: Fix testsuite failures with -O0

2023-10-04 Thread Jonathan Wakely
I've pushed this to gcc-11 after testing on x86_64-linux.

-- >8 --

Backport the prune.exp change from r12-4425-g1595fe44e11a96 to fix two
testsuite failures when testing with -O0:
FAIL: 20_util/uses_allocator/69293_neg.cc (test for excess errors)
FAIL: 20_util/uses_allocator/cons_neg.cc (test for excess errors)

Also force some 20_util/integer_comparisons/ xfail tests to use -O2 so
that the errors match the dg-error directives.

libstdc++-v3/ChangeLog:

* testsuite/20_util/integer_comparisons/greater_equal_neg.cc:
Add -O2 to dg-options.
* testsuite/20_util/integer_comparisons/greater_neg.cc:
Likewise.
* testsuite/20_util/integer_comparisons/less_equal_neg.cc:
Likewise.
* testsuite/lib/prune.exp: Prune 'in constexpr expansion'.
---
 .../testsuite/20_util/integer_comparisons/greater_equal_neg.cc  | 2 +-
 .../testsuite/20_util/integer_comparisons/greater_neg.cc| 2 +-
 .../testsuite/20_util/integer_comparisons/less_equal_neg.cc | 2 +-
 libstdc++-v3/testsuite/lib/prune.exp| 1 +
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git 
a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc 
b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc
index 62633262948..028dce3df51 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc
@@ -15,7 +15,7 @@
 // with this library; see the file COPYING3.  If not see
 // .
 
-// { dg-options "-std=gnu++2a" }
+// { dg-options "-std=gnu++2a -O2" }
 // { dg-do compile { target c++2a } }
 
 #include 
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc 
b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc
index 48cb64d5676..f0422bc1948 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc
@@ -15,7 +15,7 @@
 // with this library; see the file COPYING3.  If not see
 // .
 
-// { dg-options "-std=gnu++2a" }
+// { dg-options "-std=gnu++2a -O2" }
 // { dg-do compile { target c++2a } }
 
 #include 
diff --git 
a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc 
b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc
index a16b36a83c9..3bd5d6480fe 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc
@@ -15,7 +15,7 @@
 // with this library; see the file COPYING3.  If not see
 // .
 
-// { dg-options "-std=gnu++2a" }
+// { dg-options "-std=gnu++2a -O2" }
 // { dg-do compile { target c++2a } }
 
 #include 
diff --git a/libstdc++-v3/testsuite/lib/prune.exp 
b/libstdc++-v3/testsuite/lib/prune.exp
index 6c905631f16..2ebfb922ef4 100644
--- a/libstdc++-v3/testsuite/lib/prune.exp
+++ b/libstdc++-v3/testsuite/lib/prune.exp
@@ -46,6 +46,7 @@ proc libstdc++-dg-prune { system text } {
 regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" 
$text "" text
 regsub -all "(^|\n)\[^\n\]*:   (recursively )?required \[^\n\]*" $text "" 
text
 regsub -all "(^|\n)\[^\n\]*:   . skipping \[0-9\]* instantiation contexts 
\[^\n\]*" $text "" text
+regsub -all "(^|\n)\[^\n\]*:   in .constexpr. expansion \[^\n\]*" $text "" 
text
 regsub -all "(^|\n)inlined from \[^\n\]*" $text "" text
 # Why doesn't GCC need these to strip header context?
 regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text
-- 
2.41.0



[PATCH] wwwdocs: Add ADL to C++ non-bugs

2023-10-04 Thread Jonathan Wakely
We have a long history of INVALID bugs about std functions being
available in the global namespace (PRs 27846, 67566, 82619, 99865,
110602, 111553, probably others). Let's document it.

Also de-prioritize the C++98-only bugs, which are unlikely to affect
anybody nowadays.

OK for wwwdocs?

-- >8 --

Add ADL to C++ non-bugs

Also move the item about C++98 'export' to the end, and update the item
about <: digraphs that only applies to C++98.

---
 htdocs/bugs/index.html | 36 
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/htdocs/bugs/index.html b/htdocs/bugs/index.html
index 813b78c0..41edc561 100644
--- a/htdocs/bugs/index.html
+++ b/htdocs/bugs/index.html
@@ -539,15 +539,15 @@ for details.
 C++
 
 
-export
-Most C++ compilers (G++ included) never implemented C++98
-export, which was removed in C++11, and the keyword reused in
-C++20 by the Modules feature. The C++98 feature was intended to support
-separate compilation of template declarations and
-definitions. Without export, a template definition must be in
-scope to be used. The obvious workaround is simply to place all definitions in
-the header itself. Alternatively, the compilation unit containing template
-definitions may be included from the header.
+Functions can be called without qualifying them with their namespace.
+
+Argument Dependent Lookup (ADL) means that functions can be found in namespaces
+associated with their arguments. This means that move(arg) can
+call std::move if arg is a type defined in namespace
+std, such as std::string or std::vector.
+If std::move is not the function you intended to call, use a
+qualified name such as ::move(arg) or foo::move(arg).
+
 
 Nested classes can access private members and types of the containing
 class.
@@ -597,9 +597,9 @@ handler and catch it in the main thread.
 If you have a class in the global namespace, say named X,
 and want to give it as a template argument to some other class, say
 std::vector, then std::vector<::X>
-fails with a parser error.
+fails with a parser error in C++98/C++03 mode.
 
-The reason is that the standard mandates that the sequence
+The reason is that the C++98 standard mandates that the sequence
 <: is treated as if it were the token [.
 (There are several such combinations of characters - they are called
 digraphs.) Depending on the version, the compiler then reports
@@ -608,7 +608,19 @@ a parse error before the character : (the 
colon before
 
 The simplest way to avoid this is to write std::vector<
 ::X>, i.e. place a space between the opening angle bracket
-and the scope operator.
+and the scope operator, or compile using C++11 or later. Defect report 1104
+changed the parser rules so that <:: works as expected.
+
+
+export
+Most C++ compilers (G++ included) never implemented C++98
+export, which was removed in C++11, and the keyword reused in
+C++20 by the Modules feature. The C++98 feature was intended to support
+separate compilation of template declarations and
+definitions. Without export, a template definition must be in
+scope to be used. The obvious workaround is simply to place all definitions in
+the header itself. Alternatively, the compilation unit containing template
+definitions may be included from the header.
 
 
 Common problems when upgrading the compiler
-- 
2.41.0



Re: [PATCH] libstdc++: Correctly call _string_types function

2023-10-04 Thread Jonathan Wakely
On Wed, 4 Oct 2023 at 16:10, Tom Tromey  wrote:
>
> flake8 points out that the new call to _string_types from
> StdExpAnyPrinter.__init__ is not correct -- it needs to be qualified.

OK, thanks.


>
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py
> (StdExpAnyPrinter.__init__): Qualify call to
> _string_types.
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 23efbd171ec..9a51f26d8e0 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -1386,7 +1386,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
>  # FIXME need to expand 'std::string' so that gdb.lookup_type 
> works
>  if 'std::string' in mgrname:
>  mgrtypes = []
> -for s in _string_types():
> +for s in StdExpAnyPrinter._string_types():
>  try:
>  x = re.sub(r"std::string(?!\w)", s, m.group(1))
>  # The following lookup might raise gdb.error if the
> --
> 2.40.1
>


Re: [committed] libstdc++: Define std::numeric_limits<_FloatNN> before C++23

2023-10-04 Thread Jonathan Wakely
On Wed, 4 Oct 2023 at 16:54, Stephan Bergmann  wrote:
>
> On 8/17/23 22:32, Jonathan Wakely via Libstdc++ wrote:
> > Tested x86_64-linux. Pushed to trunk.
> >
> > -- >8 --
> >
> > The extended floating-point types such as _Float32 are supported by GCC
> > prior to C++23, you just can't use the standard-conforming names from
> >  to refer to them. This change defines the specializations of
> > std::numeric_limits for those types for older dialects, not only for
> > C++23.
> >
> > libstdc++-v3/ChangeLog:
> >
> >   * include/bits/c++config (__gnu_cxx::__bfloat16_t): Define
> >   whenever __BFLT16_DIG__ is defined, not only for C++23.
> >   * include/std/limits (numeric_limits): Likewise.
> >   (numeric_limits<_Float16>, numeric_limits<_Float32>)
> >   (numeric_limits<_Float64>): Likewise for other extended
> >   floating-point types.
> > ---
> >   libstdc++-v3/include/bits/c++config |   4 +-
> >   libstdc++-v3/include/std/limits | 194 +++-
> >   2 files changed, 103 insertions(+), 95 deletions(-)
> >
> [...]
> > diff --git a/libstdc++-v3/include/std/limits 
> > b/libstdc++-v3/include/std/limits
> > index 52b19ef8264..7a59e7520eb 100644
> > --- a/libstdc++-v3/include/std/limits
> > +++ b/libstdc++-v3/include/std/limits
> > @@ -1890,189 +1890,197 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> [...]
> >   __glibcxx_float_n(64)
> >   #endif
> > -#ifdef __STDCPP_FLOAT128_T__
> > +#ifdef __FLT128_DIG__
> >   __glibcxx_float_n(128)
> >   #endif
> >   #undef __glibcxx_float_n
> [...]
>
> The above change (from __STDCPP_FLOAT128_T__ to __FLT128_DIG__) now
> started to cause issues with Clang on Clang 18 trunk:
>
> * Clang does not support a _Float128 type.
>
> * Clang does not predefine __STDCPP_FLOAT128_T__.
>
> * But since
> <https://github.com/llvm/llvm-project/commit/457f582ffe23e951380bc345c4c96ec053c09681>
> "[clang] Predefined macros for float128 support (#67196)", Clang 18
> trunk does predefine __FLT128_DIG__ now.  Which causes
>
> > $ cat test.cc
> > #include 
>
> > $ clang++ -fsyntax-only test.cc
> > In file included from test.cc:1:
> > /home/sbergman/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:1995:1:
> >  error: use of undeclared identifier '_Float128'
> >  1995 | __glibcxx_float_n(128)
> >   | ^
> > /home/sbergman/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:1903:27:
> >  note: expanded from macro '__glibcxx_float_n'
> >  1903 | struct numeric_limits<_Float##BITSIZE>  
> > \
> >   |   ^
> > :36:1: note: expanded from here
> >36 | _Float128
> >   | ^
> > 1 error generated.
>
> (I don't know whether or not it is useful for Clang to predefine
> __FLT128_DIG__ when not providing a _Float128 type.  I assume
> <https://www.iso.org/standard/65615.html> "ISO/IEC TS 18661-3:2015", as
> referenced by the C++ standard, might be relevant here, but don't know
> that document.  I added Pranav, the author of the relevant Clang commit,
> in cc here.)


It's completely wrong or Clang to define a macro describing properties
of a non-existent type.

This was reported as
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111687 and closed as
INVALID, it needs to be fixed in Clang.


>



Re: [PATCH 2/2] testsuite: Replace many dg-require-thread-fence with dg-require-atomic-exchange

2023-10-04 Thread Jonathan Wakely
On Wed, 4 Oct 2023 at 16:15, Hans-Peter Nilsson  wrote:
>
> > From: Jonathan Wakely 
> > Date: Wed, 4 Oct 2023 09:29:43 +0100
>
> > The new dg-require proc checks for __atomic_exchange, which is not the
> > same as compare-exchange, and not the same as test-and-set on
> > atomic_flag. Does it just happen to be true for arm that the presence
> > of __atomic_exchange also implies the other atomic operations?
>
> I missed pointing out that if the target implements
> something that emits actual insns for __atomic_exchange
> (and/or __atomic_compare_exchange), it has also implemented
> test-and-set.  Cf. optabs.cc:expand_atomic_test_and_set (at
> r14-4395-g027a94cf32be0b).
>
> Similarly a insn-level __atomic_compare_exchange
> implementation (atomic_compare_and_swapM) also does it for
> __atomic_exchange.

Ah great, that makes testing __atomic_exchange good enough then.

>
> > The new proc also only tests it for int, which presumably means none
> > of these tests rely on atomics for long long being present. Some of
> > the tests use atomics on pointers, which should work for ILP32 targets
> > if atomics work on int, but the new dg-require-atomic-exchange isn't
> > sufficient to check that it will work for pointers on LP64 targets.
>
> Right, I'll amend to test a uintptr_t...
>
> > Maybe it happens to work today for the targets where we have issues,
> > but we seem to be assuming that there will be no LP64 targets where
> > these atomics are absent for 64-bit pointers. Are there supported
> > risc-v ISA subsets where that isn't true?
>
> ...but generally, I'd like to leave future amendments like
> that to the Next Guy, just like the Previous Guy left
> dg-require-thread-fence for me (us) to split up.  But,
> perhaps we can prepare for such amendments by giving it a
> more specific name: suggesting
> dg-require-atomic-cmpxchg-word (bikeshedding opportunity),
> testing __atomic_compare_exchange.
>
> IOW, I don't think we should make a distinction, looking for
> other operations and sizes at this time.

Yep, that's fine. Worse is better. Maybe just add a comment before the
definition of the new effective target check noting that we only test
for one atomic op, but the implementation in gcc means that's good
enough.

>
> > And we're assuming that
> > __atomic_exchange being present implies all other ops are present,
> > which seems like a bad assumption to me. I would be more confident
> > testing for __atomic_compare_exchange, because with a wait-free CAS
> > you can implement any other atomic operation, but the same isn't true
> > for __atomic_exchange.
>
> Yes, I switched them around.
>
> New version coming up.

Thanks!


>
> brgds, H-P
>



Re: [PATCH] wwwdocs: Add ADL to C++ non-bugs

2023-10-05 Thread Jonathan Wakely
On Wed, 4 Oct 2023 at 20:17, Jason Merrill  wrote:
>
> On 10/3/23 10:45, Jonathan Wakely wrote:
> > We have a long history of INVALID bugs about std functions being
> > available in the global namespace (PRs 27846, 67566, 82619, 99865,
> > 110602, 111553, probably others). Let's document it.
> >
> > Also de-prioritize the C++98-only bugs, which are unlikely to affect
> > anybody nowadays.
> >
> > OK for wwwdocs?
>
> OK, thanks.
>
> Jason


After pushing it I realised the formatting looks bad compared to the
other items in the list, so I've pushed the attached follow-up as
obvious.
commit 1b1a0cf29826ce9287a203cde00fd1512918fc17
Author: Jonathan Wakely 
Date:   Thu Oct 5 10:09:54 2023 +0100

Add  to new item in C++ non-bugs list

diff --git a/htdocs/bugs/index.html b/htdocs/bugs/index.html
index 41edc561..da3d4c0d 100644
--- a/htdocs/bugs/index.html
+++ b/htdocs/bugs/index.html
@@ -541,12 +541,14 @@ for details.
 
 Functions can be called without qualifying them with their namespace.
 
+
 Argument Dependent Lookup (ADL) means that functions can be found in namespaces
 associated with their arguments. This means that move(arg) can
 call std::move if arg is a type defined in namespace
 std, such as std::string or std::vector.
 If std::move is not the function you intended to call, use a
 qualified name such as ::move(arg) or foo::move(arg).
+
 
 
 Nested classes can access private members and types of the containing


Re: [PATCH][_GLIBCXX_INLINE_VERSION] Add missing symbols

2023-10-05 Thread Jonathan Wakely
On Thu, 5 Oct 2023 at 18:04, François Dumont  wrote:
>
> Here is a patch to fix following test case in gcc:
>
> gcc/testsuite/g++.dg/cpp23/ext-floating13.C
>
>  libstdc++: [_GLIBCXX_INLINE_VERSION] Add missing float symbols
>
>  libstdc++-v3/ChangeLog:
>
>  * config/abi/pre/gnu-versioned-namespace.ver: Add missing
> symbols
>  for _Float{16,32,64,128,32x,64x,128x}.
>
> Ok to commit ?

OK, thanks.


>
> François
>



Re: [PATCH] libstdc++: Fix tr1/8_c_compatibility/cstdio/functions.cc regression with recent glibc

2023-10-12 Thread Jonathan Wakely
On Thursday, 12 October 2023, Jakub Jelinek  wrote:
> Hi!
>
> The following testcase started FAILing recently after the
>
https://sourceware.org/git/?p=glibc.git;a=commit;h=64b1a44183a3094672ed304532bedb9acc707554
> glibc change which marked vfscanf with nonnull (1) attribute.
> While vfwscanf hasn't been marked similarly (strangely), the patch changes
> that too.  By using va_arg one hides the value of it from the compiler
> (volatile keyword would do too, or making the FILE* stream a function
> argument, but then it might need to be guarded by #if or something).
>
> Tested on x86_64-linux, ok for trunk?

OK, thanks.

>
> 2023-10-12  Jakub Jelinek  
>
> * testsuite/tr1/8_c_compatibility/cstdio/functions.cc (test01):
> Initialize stream to va_arg(ap, FILE*) rather than 0.
> * testsuite/tr1/8_c_compatibility/cwchar/functions.cc (test01):
> Likewise.
>
> --- libstdc++-v3/testsuite/tr1/8_c_compatibility/cstdio/functions.cc.jj
2023-01-16 23:19:06.651711546 +0100
> +++ libstdc++-v3/testsuite/tr1/8_c_compatibility/cstdio/functions.cc
2023-10-12 09:46:28.695011763 +0200
> @@ -35,7 +35,7 @@ void test01(int dummy, ...)
>char* s = 0;
>const char* cs = 0;
>const char* format = "%i";
> -  FILE* stream = 0;
> +  FILE* stream = va_arg(ap, FILE*);
>std::size_t n = 0;
>
>int ret;
> --- libstdc++-v3/testsuite/tr1/8_c_compatibility/cwchar/functions.cc.jj
2023-01-16 23:19:06.651711546 +0100
> +++ libstdc++-v3/testsuite/tr1/8_c_compatibility/cwchar/functions.cc
2023-10-12 09:46:19.236141897 +0200
> @@ -42,7 +42,7 @@ void test01(int dummy, ...)
>  #endif
>
>  #if _GLIBCXX_HAVE_VFWSCANF
> -  FILE* stream = 0;
> +  FILE* stream = va_arg(arg, FILE*);
>const wchar_t* format1 = 0;
>int ret1;
>ret1 = std::tr1::vfwscanf(stream, format1, arg);
>
> Jakub
>
>


Re: Ping: [PATCH v2 1/2] testsuite: Add dg-require-atomic-cmpxchg-word

2023-10-12 Thread Jonathan Wakely
On Thu, 12 Oct 2023, 17:11 Jeff Law,  wrote:

>
>
> On 10/12/23 08:38, Christophe Lyon wrote:
> > LGTM but I'm not a maintainer ;-)
> LGTM to as well -- I usually try to stay out of libstdc++, but this
> looks simple enough.  Both patches in this series are OK.
>

Thanks for stepping in, Jeff. The patches are indeed fine, I'm just offline
due to circumstances beyond my control. I hope normal service will resume
soon.


Re: [PATCH] libstdc++: Workaround for LLVM-61763 in ranges

2023-10-14 Thread Jonathan Wakely
On Sat, 14 Oct 2023, 00:33 Benjamin Brock,  wrote:

> This is my first time submitting a patch, so my apologies if I'm
> submitting incorrectly or missing something.
>

Thanks for contributing!

I don't think this patch counts as legally significant, but if you
contribute again in future you should be aware of
https://gcc.gnu.org/contribute.html#legal and either complete the copyright
assignment paperwork, or add a DCO sign-off to the commit message.


> Clang is unable to compile parts of libstdc++'s ranges implementation
> due to LLVM-61763, a Clang frontend compiler bug in handling the
> declarations of constrained friends.  The problem areas are zip_view,
> zip_transform_view, and adjacent_transform_view.
>
> A simple ranges program like the following fails to compile using
> Clang trunk and libstdc++.
>
>   std::vector v = {1, 2, 3, 4};
>   int sum = 0;
>   for (auto&& [i, j] : std::ranges::views::zip(v, v))
> sum += i * j;
>
> In file included from :1:
>
> /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/ranges:4655:14:
> error: type constraint differs in template redeclaration
>  4655 | template
>   |  ^
> . . . . . .
>
> Godbolt: https://godbolt.org/z/Ynbs15aGh
>
> This patch adds a small workaround that avoids declaring constrained
> friends when compiling with Clang, instead making some members public.
> MSVC's standard library has implemented a similar workaround.
>
> Scanning through libstdc++, there do appear to be other workarounds
> for Clang, e.g. in complex and experimental/simd.  Hopefully this kind
> of workaround is acceptable---while the core issue is a Clang compiler
> bug, it may take a while to fix, and it would be very useful for
> libstdc++ ranges to work with Clang in the meantime.
>

Yes, this is ok because the hack is limited to __clang__.


> 2023-10-13  Benjamin Brock 
>
> libstdc++-v3/ChangeLog:
>
> * include/std/ranges: implement workaround for LLVM-61763 in
>   zip_view and adjacency_view
>

This should be a complete sentence, so capital letter and full stop.

I can get this pushed to trunk and gcc-13 next week, thanks again for the
patch.



> ---
>
> diff --git a/libstdc++-v3/include/std/ranges
> b/libstdc++-v3/include/std/ranges
> index 1d529a886be..7893e3a84c9 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -4632,6 +4632,9 @@ namespace views::__adaptor
>class zip_view<_Vs...>::_Iterator
>  : public __detail::__zip_view_iter_cat<_Const, _Vs...>
>{
> +#ifdef __clang__ // LLVM-61763 workaround
> +  public:
> +#endif
>
>  __detail::__tuple_or_pair_t _Vs>>...> _M_current;
>
>  constexpr explicit
> @@ -4652,11 +4655,13 @@ namespace views::__adaptor
> return input_iterator_tag{};
>  }
>
> +#ifndef __clang__ // LLVM-61763 workaround
>  template
>requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) &&
> is_object_v<_Fp>
> && regular_invocable<_Fp&, range_reference_t<_Ws>...>
> && std::__detail::__can_reference range_reference_t<_Ws>...>>
>friend class zip_transform_view;
> +#endif
>
>public:
>  // iterator_category defined in __zip_view_iter_cat
> @@ -5327,6 +5332,9 @@ namespace views::__adaptor
>template
>class adjacent_view<_Vp, _Nm>::_Iterator
>{
> +#ifdef __clang__ // LLVM-61763 workaround
> +  public:
> +#endif
>  using _Base = __detail::__maybe_const_t<_Const, _Vp>;
>  array, _Nm> _M_current = array,
> _Nm>();
>
> @@ -5367,12 +5375,14 @@ namespace views::__adaptor
>
>  friend class adjacent_view;
>
> +#ifndef __clang__ // LLVM-61763 workaround
>  template
>requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
>  && regular_invocable<__detail::__unarize<_Fp&, _Mm>,
> range_reference_t<_Wp>>
>  &&
> std::__detail::__can_reference _Mm>,
>
> range_reference_t<_Wp>>>
>friend class adjacent_transform_view;
> +#endif
>
>public:
>  using iterator_category = input_iterator_tag;
>


Re: [PATCH] libstdc++: testsuite: Enhance codecvt_unicode with tests for length()

2023-10-18 Thread Jonathan Wakely
On Tue, 17 Oct 2023 at 23:51, Dimitrij Mijoski  wrote:
>
> We can test codecvt::length() with the same data that we test
> codecvt::in(). For each call of in() we add another call to length().
> Some additional small cosmentic changes are applied.

Thanks! I'll get this applied.

>
> libstdc++-v3/ChangeLog:
>
> * testsuite/22_locale/codecvt/codecvt_unicode.h: Test length()
> ---
>  .../22_locale/codecvt/codecvt_unicode.h   | 103 +++---
>  1 file changed, 90 insertions(+), 13 deletions(-)
>
> diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h 
> b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
> index d3ae42fac..b3c257ec2 100644
> --- a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
> +++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
> @@ -17,7 +17,6 @@
>
>  #include 
>  #include 
> -#include 
>  #include 
>
>  struct test_offsets_ok
> @@ -79,6 +78,10 @@ utf8_to_utf32_in_ok (const std::codecvt mbstate_t> &cvt)
>VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
>if (t.out_size < array_size (out))
> VERIFY (out[t.out_size] == 0);
> +
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
> +  VERIFY (len == t.in_size);
>  }
>
>for (auto t : offsets)
> @@ -99,6 +102,10 @@ utf8_to_utf32_in_ok (const std::codecvt mbstate_t> &cvt)
>VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
>if (t.out_size < array_size (out))
> VERIFY (out[t.out_size] == 0);
> +
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, array_size (out));
> +  VERIFY (len == t.in_size);
>  }
>  }
>
> @@ -163,6 +170,10 @@ utf8_to_utf32_in_partial (const std::codecvt ExternT, mbstate_t> &cvt)
>   == 0);
>if (t.expected_out_next < array_size (out))
> VERIFY (out[t.expected_out_next] == 0);
> +
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
> +  VERIFY (len == t.expected_in_next);
>  }
>  }
>
> @@ -303,6 +314,10 @@ utf8_to_utf32_in_error (const std::codecvt ExternT, mbstate_t> &cvt)
>if (t.expected_out_next < array_size (out))
> VERIFY (out[t.expected_out_next] == 0);
>
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
> +  VERIFY (len == t.expected_in_next);
> +
>in[t.replace_pos] = old_char;
>  }
>  }
> @@ -334,7 +349,7 @@ utf32_to_utf8_out_ok (const std::codecvt ExternT, mbstate_t> &cvt)
>VERIFY (char_traits::length (in) == 4);
>VERIFY (char_traits::length (exp) == 10);
>
> -  const test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {4, 
> 10}};
> +  test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {4, 10}};
>for (auto t : offsets)
>  {
>ExternT out[array_size (exp) - 1] = {};
> @@ -374,7 +389,7 @@ utf32_to_utf8_out_partial (const std::codecvt ExternT, mbstate_t> &cvt)
>VERIFY (char_traits::length (in) == 4);
>VERIFY (char_traits::length (exp) == 10);
>
> -  const test_offsets_partial offsets[] = {
> +  test_offsets_partial offsets[] = {
>  {1, 0, 0, 0}, // no space for first CP
>
>  {2, 1, 1, 1}, // no space for second CP
> @@ -528,6 +543,10 @@ utf8_to_utf16_in_ok (const std::codecvt ExternT, mbstate_t> &cvt)
>VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
>if (t.out_size < array_size (out))
> VERIFY (out[t.out_size] == 0);
> +
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
> +  VERIFY (len == t.in_size);
>  }
>
>for (auto t : offsets)
> @@ -548,6 +567,10 @@ utf8_to_utf16_in_ok (const std::codecvt ExternT, mbstate_t> &cvt)
>VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
>if (t.out_size < array_size (out))
> VERIFY (out[t.out_size] == 0);
> +
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, array_size (out));
> +  VERIFY (len == t.in_size);
>  }
>  }
>
> @@ -617,6 +640,10 @@ utf8_to_utf16_in_partial (const std::codecvt ExternT, mbstate_t> &cvt)
>   == 0);
>if (t.expected_out_next < array_size (out))
> VERIFY (out[t.expected_out_next] == 0);
> +
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
> +  VERIFY (len == t.expected_in_next);
>  }
>  }
>
> @@ -757,6 +784,10 @@ utf8_to_utf16_in_error (const std::codecvt ExternT, mbstate_t> &cvt)
>if (t.expected_out_next < array_size (out))
> VERIFY (out[t.expected_out_next] == 0);
>
> +  state = {};
> +  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
> +  VERIFY (len == t.expected_in_next);
> +
>in[t.replace_pos] = old_char;
>  }
>  }
> @@ -788,7 +819,7 @@ utf16_to_utf8_out_ok (const std::codecvt ExternT, mbstate_t> &cvt)
>VERIFY (char_traits::length (in) == 

Re: [PATCH][_Hashtable] Fix merge

2023-10-19 Thread Jonathan Wakely
On Thursday, 19 October 2023, François Dumont  wrote:
> libstdc++: [_Hashtable] Do not reuse untrusted cached hash code
>
> On merge reuse merged node cached hash code only if we are on the same
type of
> hash and this hash is stateless. Usage of function pointers or
std::function as
> hash functor will prevent this optimization.

I found this first sentence a little hard to parse. How about:

On merge, reuse a merged node's cached hash code only if we are on the same
type of
hash and this hash is stateless.


And for the second sentence, would it be clearer to say "will prevent
reusing cached hash codes" instead of "will prevent this optimization"?


And for the comment on the new function, I think this reads better:

"Only use the node's (possibly cached) hash code if its hash function _H2
matches _Hash. Otherwise recompute it using _Hash."

The code and tests look good, so if you're happy with the comment+changelog
suggestions, this is ok for trunk.

This seems like a bug fix that should be backported too, after some time on
trunk.


>
> libstdc++-v3/ChangeLog
>
> * include/bits/hashtable_policy.h
> (_Hash_code_base::_M_hash_code(const _Hash&, const
_Hash_node_value<>&)): Remove.
> (_Hash_code_base::_M_hash_code<_H2>(const _H2&, const
_Hash_node_value<>&)): Remove.
> * include/bits/hashtable.h
> (_M_src_hash_code<_H2>(const _H2&, const key_type&, const
__node_value_type&)): New.
> (_M_merge_unique<>, _M_merge_multi<>): Use latter.
> * testsuite/23_containers/unordered_map/modifiers/merge.cc
> (test04, test05, test06): New test cases.
>
> Tested under Linux x86_64, ok to commit ?
>
> François
>
>


Re: Limit Debug mode impact: overload __niter_base

2018-07-02 Thread Jonathan Wakely

On 01/07/18 21:20 +0200, François Dumont wrote:

    Here is a new proposal between yours and mine.

    It is still adding a function to wrap what __niter_base unwrap, I 
called it __nwrap_iter for this reason. But it takes advantage of 


Since "niter" refers to __normal_iterator I think a name based on
"niter" would be better than nsomething_iter.

__niter_wrap
__niter_rewrap
__niter_lift (misuse of functional programming term?)
__niter_raise (misuse of linear algebra term?)
__make_niter
__remake_niter


knowing that __niter_base will only unwrap random access iterator to 
use an expression to that will do the right thing, no matter the 
original iterator type.


OK, since __niter_base only transforms types based on 
__normal_iterator that seems safe to assume (in theory we could use

__normal_iterator with non-random access iterators, but we don't).

Could you please add a comment to the __nwrap_iter saying something
like:

 // Reverse the __niter_base transformation to get a
 // __normal_iterator back again (this assumes that __normal_iterator
 // is only used to wrap random access iterators, like pointers).


    I eventually found no issue in the testsuite, despite the 
std::equal change. I might have had a local invalid test.


Yes, I *did* test it already :-)





diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index d429943..003ae8d 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -277,6 +277,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__niter_base(_Iterator __it)
{ return __it; }

+  // Convert an iterator of type _From to an iterator of type _To.
+  // e.g. from int* to __normal_iterator.
+  template
+inline _Iterator
+__nwrap_iter(_Iterator, _Iterator, _Iterator __res)
+{ return __res; }
+
+  template
+inline _From
+__nwrap_iter(_From __from, _To __to, _To __res)
+{ return __from + (__res - __to); }


Every time you call this function you pass it:

 __nwrap_iter(x, __niter_base(x), y)

So can the __niter_base(x) call happen inside __nwrap_iter?

i.e.

 template
   inline _From
   __nwrap_iter(_From __from, _To __res)
   { return __from + (__res - __niter_base(__from)); }




Re: [PATCH] Remove -Wabi from libstdc++ build options

2018-07-02 Thread Jonathan Wakely

On 30/06/18 20:48 +, Bernd Edlinger wrote:

Hi,

the -Wabi option prints a warning as follows:

cc1plus: warning: -Wabi won't warn about anything [-Wabi]
cc1plus: note: -Wabi warns about differences from the most up-to-date
ABI, which is also used by default
cc1plus: note: use e.g. -Wabi=11 to warn about changes from GCC 7

This happens many times while building libstdc++, and as the warning
explains, it is good for nothing, so this patch removes it.


Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


No, I don't think we want to simply remove it.

Maybe https://gcc.gnu.org/ml/gcc/2018-06/msg00276.html instead?




[PATCH] Optimize std::sub_match comparisons using string_view-like type

2018-07-02 Thread Jonathan Wakely

Avoid creation of unnecessary basic_string objects by using a simplified
string_view type and performing comparisons on that type instead. A
temporary basic_string object is still used when the sub_match's
iterators are not contiguous, in order to get an object that the
__string_view can reference.

* include/bits/regex.h (sub_match::operator string_type): Call str().
(sub_match::compare): Use _M_str() instead of str().
(sub_match::_M_compare): New public function.
(sub_match::__string_view): New helper type.
(sub_match::_M_str): New overloaded functions to avoid creating a
string_type object when not needed.
(operator==, operator!=, operator<, operator>, operator<=, operator>=):
Use sub_match::_M_compare instead of creating string_type objects.
Fix Doxygen comments.
* include/bits/regex_compiler.h (__has_contiguous_iter): Remove.
(__is_contiguous_normal_iter): Rename to __is_contiguous_iter and
simplify.
(__enable_if_contiguous_iter, __disable_if_contiguous_iter): Use
__enable_if_t.
* include/std/type_traits (__enable_if_t): Define for C++11.
* testsuite/28_regex/sub_match/compare.cc: New.
* testsuite/util/testsuite_iterators.h (remove_cv): Add transformation
trait.
(input_iterator_wrapper): Use remove_cv for value_type argument of
std::iterator base class.

We could avoid temporary string_type objects even for non-contiguous
iterators by writing a manual "compare" function that uses
char_traits::lt on every element in the iterator ranges. It's not
obvious that would actually be an optimization (and I haven't measured
it). For sub-expression matches that fit in an SSO buffer creating a
string doesn't allocate, and once we have a std::string or
std::wstring we benefit from highly optimized strncmp or wcsncmp
implementations in glibc. Maybe we could use an adaptive approach
where we create a string when value_type is char or wchar_t, and
_BiIter is random-access, and std:distance(first, second) <= SSO size.
Otherwise we'd use a manual loop using char_traits::lt. I don't plan
to work on that, the common cases are all likely to be using pointers
or basic_string::const_iterator and so already optimized by this
patch.

Tested powerpc64le-linux, committed to trunk.


commit b6d43fcbdd4987c3bcb48960dc05a1145deca747
Author: Jonathan Wakely 
Date:   Mon Jul 2 18:34:09 2018 +0100

Optimize std::sub_match comparisons using string_view-like type

Avoid creation of unnecessary basic_string objects by using a simplified
string_view type and performing comparisons on that type instead. A
temporary basic_string object is still used when the sub_match's
iterators are not contiguous, in order to get an object that the
__string_view can reference.

* include/bits/regex.h (sub_match::operator string_type): Call 
str().
(sub_match::compare): Use _M_str() instead of str().
(sub_match::_M_compare): New public function.
(sub_match::__string_view): New helper type.
(sub_match::_M_str): New overloaded functions to avoid creating a
string_type object when not needed.
(operator==, operator!=, operator<, operator>, operator<=, 
operator>=):
Use sub_match::_M_compare instead of creating string_type objects.
Fix Doxygen comments.
* include/bits/regex_compiler.h (__has_contiguous_iter): Remove.
(__is_contiguous_normal_iter): Rename to __is_contiguous_iter and
simplify.
(__enable_if_contiguous_iter, __disable_if_contiguous_iter): Use
__enable_if_t.
* include/std/type_traits (__enable_if_t): Define for C++11.
* testsuite/28_regex/sub_match/compare.cc: New.
* testsuite/util/testsuite_iterators.h (remove_cv): Add 
transformation
trait.
(input_iterator_wrapper): Use remove_cv for value_type argument of
std::iterator base class.

diff --git a/libstdc++-v3/include/bits/regex.h 
b/libstdc++-v3/include/bits/regex.h
index 6b6501e98ae..af6fe3f0d79 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -42,8 +42,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
 
 namespace __detail
 {
-  enum class _RegexExecutorPolicy : int
-{ _S_auto, _S_alternate };
+  enum class _RegexExecutorPolicy : int { _S_auto, _S_alternate };
 
   templatematched ? std::distance(this->first, this->second) : 0; }
@@ -893,11 +890,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
* from the unwary.
*/
   operator string_type() const
-  {
-   return this->matched
- ? string_type(this->first, this->second)
- : string_type();
-  }
+  { return str(); }
 
   /**
* @brief Gets the matching sequence

[PATCH] P0887R1 The identity metafunction

2018-07-02 Thread Jonathan Wakely

A recently-approved C++2a feature, trivial to implement.

* include/std/type_traits (type_identity, type_identity_t): Define
   for C++2a.
* testsuite/20_util/type_identity/requirements/alias_decl.cc: New.
* testsuite/20_util/type_identity/requirements/
explicit_instantiation.cc:New.
* testsuite/20_util/type_identity/requirements/typedefs.cc: New.

Tested powerpc64le-linux, committed to trunk.

commit 54f6b78dc937cbaee50522bf9cd18ac4e0855d39
Author: Jonathan Wakely 
Date:   Mon Jul 2 21:32:24 2018 +0100

P0887R1 The identity metafunction

* include/std/type_traits (type_identity, type_identity_t): Define
for C++2a.
* testsuite/20_util/type_identity/requirements/alias_decl.cc: New.
* testsuite/20_util/type_identity/requirements/
explicit_instantiation.cc:New.
* testsuite/20_util/type_identity/requirements/typedefs.cc: New.

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 0c7e97286ca..b2d3380f024 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2996,6 +2996,13 @@ template 
   template
 using remove_cvref_t = __remove_cvref_t<_Tp>;
 
+  /// Identity metafunction.
+  template
+struct type_identity { using type = _Tp; };
+
+  template
+using type_identity_t = typename type_identity<_Tp>::type;
+
 #endif // C++2a
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git 
a/libstdc++-v3/testsuite/20_util/type_identity/requirements/alias_decl.cc 
b/libstdc++-v3/testsuite/20_util/type_identity/requirements/alias_decl.cc
new file mode 100644
index 000..6729d118273
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/type_identity/requirements/alias_decl.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2018 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 "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+//
+#include 
+
+using namespace std;
+
+template>
+  struct test; // undefined
+
+template
+  struct test : std::true_type { };
+
+static_assert( test{}, "type_identity_t" );
+static_assert( test{}, "type_identity_t" );
+static_assert( test{}, "type_identity_t" );
+static_assert( test{}, "type_identity_t" );
+static_assert( test{}, "type_identity_t" );
diff --git 
a/libstdc++-v3/testsuite/20_util/type_identity/requirements/explicit_instantiation.cc
 
b/libstdc++-v3/testsuite/20_util/type_identity/requirements/explicit_instantiation.cc
new file mode 100644
index 000..07387e719ce
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/20_util/type_identity/requirements/explicit_instantiation.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 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 "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include 
+
+namespace std
+{
+  typedef short test_type;
+  template struct type_identity;
+}
diff --git 
a/libstdc++-v3/testsuite/20_util/type_identity/requirements/typedefs.cc 
b/libstdc++-v3/testsuite/20_util/type_identity/requirements/typedefs.cc
new file mode 100644
index 000..77f0cba9b4c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/type_identity/requirements/typedefs.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2018 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 modi

[PATCH] P0758R1 Implicit conversion traits

2018-07-02 Thread Jonathan Wakely

Extend __is_convertible_helper to also detect whether the conversion is
non-throwing, for std::is_nothrow_convertible in C++2a,

* include/std/type_traits [__cplusplus > 201703]
(__is_convertible_helper::__is_nothrow_type): Define new member.
(__is_convertible_helper<_From, _To, false>::__test_aux1): Add
noexcept.
(__is_convertible_helper<_From, _To, false>::__test_nothrow)
(__is_convertible_helper<_From, _To, false>::__is_nothrow_type): Add
new members.
(is_nothrow_convertible, is_nothrow_convertible_v): Define for C++2a.
* testsuite/20_util/is_nothrow_convertible/value.cc: New.
* testsuite/20_util/is_nothrow_convertible/requirements/
explicit_instantiation.cc: New.
* testsuite/20_util/is_nothrow_convertible/requirements/typedefs.cc:
New.

Tested powerpc64le-linux, committed to trunk.


commit 3cc486f1802c45d8705d8d5239170a0e1c0151c7
Author: Jonathan Wakely 
Date:   Mon Jul 2 21:33:14 2018 +0100

P0758R1 Implicit conversion traits

Extend __is_convertible_helper to also detect whether the conversion is
non-throwing, for std::is_nothrow_convertible in C++2a,

* include/std/type_traits [__cplusplus > 201703]
(__is_convertible_helper::__is_nothrow_type): Define new member.
(__is_convertible_helper<_From, _To, false>::__test_aux1): Add
noexcept.
(__is_convertible_helper<_From, _To, false>::__test_nothrow)
(__is_convertible_helper<_From, _To, false>::__is_nothrow_type): Add
new members.
(is_nothrow_convertible, is_nothrow_convertible_v): Define for 
C++2a.
* testsuite/20_util/is_nothrow_convertible/value.cc: New.
* testsuite/20_util/is_nothrow_convertible/requirements/
explicit_instantiation.cc: New.
* testsuite/20_util/is_nothrow_convertible/requirements/typedefs.cc:
New.

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index b2d3380f024..accea6df648 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1341,13 +1341,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool = __or_, is_function<_To>,
 is_array<_To>>::value>
 struct __is_convertible_helper
-{ typedef typename is_void<_To>::type type; };
+{
+  typedef typename is_void<_To>::type type;
+#if __cplusplus > 201703L
+  typedef type __is_nothrow_type;
+#endif
+};
 
   template
 class __is_convertible_helper<_From, _To, false>
 {
-   template
-   static void __test_aux(_To1);
+  template
+   static void __test_aux(_To1) noexcept;
 
   template(std::declval<_From1>()))>
@@ -1358,8 +1363,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static false_type
__test(...);
 
+#if __cplusplus > 201703L
+  template(std::declval<_From1>()))>
+   static __bool_constant<_NoEx>
+   __test_nothrow(int);
+
+  template
+   static false_type
+   __test_nothrow(...);
+#endif
+
 public:
   typedef decltype(__test<_From, _To>(0)) type;
+
+#if __cplusplus > 201703L
+  typedef decltype(__test_nothrow<_From, _To>(0)) __is_nothrow_type;
+#endif
 };
 
 
@@ -1369,6 +1389,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __is_convertible_helper<_From, _To>::type
 { };
 
+#if __cplusplus > 201703L
+  /// is_nothrow_convertible
+  template
+struct is_nothrow_convertible
+: public __is_convertible_helper<_From, _To>::__is_nothrow_type
+{ };
+
+  /// is_nothrow_convertible_v
+  template
+inline constexpr bool is_nothrow_convertible_v
+  = is_nothrow_convertible<_From, _To>::value;
+#endif // C++2a
 
   // Const-volatile modifications.
 
diff --git 
a/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/requirements/explicit_instantiation.cc
 
b/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/requirements/explicit_instantiation.cc
new file mode 100644
index 000..68f1adecb38
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/requirements/explicit_instantiation.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 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 re

Re: Limit Debug mode impact: overload __niter_base

2018-07-03 Thread Jonathan Wakely

On 03/07/18 07:47 +0200, François Dumont wrote:

Here is the updated patch.

    * include/bits/stl_algobase.h (__niter_wrap): New.
    (__copy_move_a2(_II, _II, _OI)): Use latter.
    (__copy_move_backward_a2(_BI1, _BI1, _BI2)): Likewise.
    (fill_n(_OI, _Size, const _Tp&)): Likewise.
    (equal(_II1, _II1, _II2)): Use __glibcxx_requires_can_increment.
    * include/debug/stl_iterator.h
    (std::__niter_base(const __gnu_cxx::_Safe_iterator<
    __gnu_cxx::__normal_iterator<>, _Sequence>&)): New declaration.
    * include/debug/vector (__niter_base(const __gnu_cxx::_Safe_iterator<
    __gnu_cxx::__normal_iterator<>, _Sequence>&)): New.

Ok to commit ?


On 02/07/2018 13:57, Jonathan Wakely wrote:

On 01/07/18 21:20 +0200, François Dumont wrote:

    Here is a new proposal between yours and mine.

    It is still adding a function to wrap what __niter_base 
unwrap, I called it __nwrap_iter for this reason. But it takes 
advantage of


Since "niter" refers to __normal_iterator I think a name based on
"niter" would be better than nsomething_iter.

__niter_wrap
__niter_rewrap
__niter_lift (misuse of functional programming term?)
__niter_raise (misuse of linear algebra term?)
__make_niter
__remake_niter


knowing that __niter_base will only unwrap random access iterator 
to use an expression to that will do the right thing, no matter 
the original iterator type.


OK, since __niter_base only transforms types based on 
__normal_iterator that seems safe to assume (in theory we could use

__normal_iterator with non-random access iterators, but we don't).

Could you please add a comment to the __nwrap_iter saying something
like:

 // Reverse the __niter_base transformation to get a
 // __normal_iterator back again (this assumes that __normal_iterator
 // is only used to wrap random access iterators, like pointers).


    I eventually found no issue in the testsuite, despite the 
std::equal change. I might have had a local invalid test.


Yes, I *did* test it already :-)




diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h

index d429943..003ae8d 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -277,6 +277,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    __niter_base(_Iterator __it)
    { return __it; }

+  // Convert an iterator of type _From to an iterator of type _To.
+  // e.g. from int* to __normal_iterator.
+  template
+    inline _Iterator
+    __nwrap_iter(_Iterator, _Iterator, _Iterator __res)
+    { return __res; }
+
+  template
+    inline _From
+    __nwrap_iter(_From __from, _To __to, _To __res)
+    { return __from + (__res - __to); }


Every time you call this function you pass it:

 __nwrap_iter(x, __niter_base(x), y)

So can the __niter_base(x) call happen inside __nwrap_iter?

i.e.

 template
   inline _From
   __nwrap_iter(_From __from, _To __res)
   { return __from + (__res - __niter_base(__from)); }








diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index d429943..e5e7d15 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -277,6 +277,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__niter_base(_Iterator __it)
{ return __it; }

+  // Reverse the __niter_base transformation to get a
+  // __normal_iterator back again (this assumes that __normal_iterator
+  // is only used to wrap random access iterators, like pointers).


Please move the comment onto the other overload, since that's the one
that actually does the wrapping.

Maybe we should re-order the overloads, so the __niter_wrap<_From, _To>
overload comes first, then on the second one add a comment:

   // No need to wrap, iterator already has the right type


+  template
+inline _Iterator
+__niter_wrap(_Iterator, _Iterator __res)
+{ return __res; }
+
+  template
+inline _From
+__niter_wrap(_From __from, _To __res)
+{ return __from + (__res - __niter_base(__from)); }


Please qualify this call as std::__niter_base

OK with those changes, thanks.



Re: [PATCH] When using -fprofile-generate=/some/path mangle absolute path of file (PR lto/85759).

2018-07-03 Thread Jonathan Wakely

On 16/05/18 13:53 +0200, Martin Liška wrote:

On 12/21/2017 10:13 AM, Martin Liška wrote:

On 12/20/2017 06:45 PM, Jakub Jelinek wrote:

Another thing is that the "/" in there is wrong, so
  const char dir_separator_str[] = { DIR_SEPARATOR, '\0' };
  char *b = concat (profile_data_prefix, dir_separator_str, pwd, NULL);
needs to be used instead.


This looks much nicer, I forgot about DIR_SEPARATOR.


Does profile_data_prefix have any dir separators stripped from the end?


That's easy to achieve..


Is pwd guaranteed to be relative in this case?


.. however this is absolute path, which would be problematic on a DOC based FS.
Maybe we should do the same path mangling as we do for purpose of gcov:

https://github.com/gcc-mirror/gcc/blob/master/gcc/gcov.c#L2424


Hi.

I decided to implement that. Which means for:

$ gcc -fprofile-generate=/tmp/myfolder empty.c -O2 && ./a.out

we get following file:
/tmp/myfolder/#home#marxin#Programming#testcases#tmp#empty.gcda

That guarantees we have a unique file path. As seen in the PR it
can produce a funny ICE.

I've been testing the patch.
Ready after it finishes tests?

Martin



What do you think about it?
Regarding the string manipulation: I'm not an expert, but work with string in C
is for me always a pain :)

Martin






From 386a4561a4d1501e8959871791289e95f6a89af5 Mon Sep 17 00:00:00 2001

From: marxin 
Date: Wed, 16 Aug 2017 10:22:57 +0200
Subject: [PATCH] When using -fprofile-generate=/some/path mangle absolute path
of file (PR lto/85759).

gcc/ChangeLog:

2018-05-16  Martin Liska  

PR lto/85759
* coverage.c (coverage_init): Mangle full path name.
* doc/invoke.texi: Document the change.
* gcov-io.c (mangle_path): New.
* gcov-io.h (mangle_path): Likewise.
* gcov.c (mangle_name): Use mangle_path for path mangling.
---
gcc/coverage.c  | 20 ++--
gcc/doc/invoke.texi |  3 +++
gcc/gcov-io.c   | 49 +
gcc/gcov-io.h   |  1 +
gcc/gcov.c  | 37 +
5 files changed, 72 insertions(+), 38 deletions(-)

diff --git a/gcc/coverage.c b/gcc/coverage.c
index 32ef298a11f..6e621c3ff96 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -1227,8 +1227,24 @@ coverage_init (const char *filename)
g->get_passes ()->get_pass_profile ()->static_pass_number;
  g->get_dumps ()->dump_start (profile_pass_num, NULL);

-  if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
-profile_data_prefix = getpwd ();
+  if (!IS_ABSOLUTE_PATH (filename))
+{
+  /* When a profile_data_prefix is provided, then mangle full path
+of filename in order to prevent file path clashing.  */
+  if (profile_data_prefix)
+   {
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ const char separator = "\\";


As mentioned on IRC, this is ill-formed due to the missing *


+#else
+ const char *separator = "/";
+#endif
+ filename = concat (getpwd (), separator, filename, NULL);
+ filename = mangle_path (filename);
+ len = strlen (filename);
+   }
+  else
+   profile_data_prefix = getpwd ();
+}

  if (profile_data_prefix)
prefix_len = strlen (profile_data_prefix);
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ca3772bbebf..4859cec0ab5 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11253,6 +11253,9 @@ and used by @option{-fprofile-use} and 
@option{-fbranch-probabilities}
and its related options.  Both absolute and relative paths can be used.
By default, GCC uses the current directory as @var{path}, thus the
profile data file appears in the same directory as the object file.
+In order to prevent filename clashing, if object file name is not an absolute
+path, we mangle absolute path of @file{@var{sourcename}.gcda} file and
+use it as file name of a @file{.gcda} file.


This is missing several definite articles, and is inconsistent about
using "filename" and "file name", i.e.

In order to prevent the file name clashing, if the object file name is
not an absolute path, we mangle the absolute path of the
@file{@var{sourcename}.gcda} file and use it as the file name of a
@file{.gcda} file. 



Re: PR libstdc++/86272 Fix undefined __glibcxx_check_insert_range2

2018-07-03 Thread Jonathan Wakely

On 03/07/18 22:11 +0200, François Dumont wrote:

Hi

    I plan to commit attached patch to fix the __gnu_debug::string 
undefined macro.


    Is it ok the way I used some tests to now validate 
__gnu_debug::string on check-debug ?


Yes, good idea. We don't want to do that for *every* basic_string
test, but doing it for a few of them means we cover the
__gnu_debug::string.

OK for trunk and the affected branches. Thanks.




[PATCH] P0556R3 Integral power-of-2 operations, P0553R2 Bit operations

2018-07-03 Thread Jonathan Wakely

P0553R2 is not in the C++2a working draft yet, but is likely to be
approved soon. Neither proposal supports std::byte but this adds
overloads of each function for std::byte, assuming that will also get
added.

* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/precompiled/stdc++.h: Include new header.
* include/std/bit: New header.
(__rotl, __rotr, __countl_zero, __countl_one, __countr_zero)
(__countr_one, __popcount, __ispow2, __ceil2, __floor2, __log2p1):
Define for C++14.
[!__STRICT_ANSI__] (rotl, rotr, countl_zero, countl_one, countr_zero)
(countr_one, popcount): Define for C++2a. Also overload for std::byte.
(ispow2, ceil2, floor2, log2p1): Define for C++2a.
[!__STRICT_ANSI__] (ispow2, ceil2, floor2, log2p1): Overload for
std::byte.
* testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: New.
* testsuite/26_numerics/bit/bit.pow.two/floor2.cc: New.
* testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: New.
* testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: New.
* testsuite/26_numerics/bit/bitops.rot/rotl.cc: New.
* testsuite/26_numerics/bit/bitops.rot/rotr.cc: New.
* testsuite/26_numerics/bit/bitops.count/countl_one.cc: New.
* testsuite/26_numerics/bit/bitops.count/countl_zero.cc: New.
* testsuite/26_numerics/bit/bitops.count/countr_one.cc: New.
* testsuite/26_numerics/bit/bitops.count/countr_zero.cc: New.

Tested powerpc64le-linux, committed to trunk.


commit 8e5c24b33c987bc72d429755ed90958f7931711b
Author: Jonathan Wakely 
Date:   Tue Jul 3 21:33:20 2018 +0100

P0556R3 Integral power-of-2 operations, P0553R2 Bit operations

P0553R2 is not in the C++2a working draft yet, but is likely to be
approved soon. Neither proposal supports std::byte but this adds
overloads of each function for std::byte, assuming that will also get
added.

* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/precompiled/stdc++.h: Include new header.
* include/std/bit: New header.
(__rotl, __rotr, __countl_zero, __countl_one, __countr_zero)
(__countr_one, __popcount, __ispow2, __ceil2, __floor2, __log2p1):
Define for C++14.
[!__STRICT_ANSI__] (rotl, rotr, countl_zero, countl_one, 
countr_zero)
(countr_one, popcount): Define for C++2a. Also overload for 
std::byte.
(ispow2, ceil2, floor2, log2p1): Define for C++2a.
[!__STRICT_ANSI__] (ispow2, ceil2, floor2, log2p1): Overload for
std::byte.
* testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: New.
* testsuite/26_numerics/bit/bit.pow.two/floor2.cc: New.
* testsuite/26_numerics/bit/bit.pow.two/ispow2.cc: New.
* testsuite/26_numerics/bit/bit.pow.two/log2p1.cc: New.
* testsuite/26_numerics/bit/bitops.rot/rotl.cc: New.
* testsuite/26_numerics/bit/bitops.rot/rotr.cc: New.
* testsuite/26_numerics/bit/bitops.count/countl_one.cc: New.
* testsuite/26_numerics/bit/bitops.count/countl_zero.cc: New.
* testsuite/26_numerics/bit/bitops.count/countr_one.cc: New.
* testsuite/26_numerics/bit/bitops.count/countr_zero.cc: New.

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index f91907df325..d1453a5abce 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -30,6 +30,7 @@ std_headers = \
${std_srcdir}/any \
${std_srcdir}/array \
${std_srcdir}/atomic \
+   ${std_srcdir}/bit \
${std_srcdir}/bitset \
${std_srcdir}/charconv \
${std_srcdir}/chrono \
diff --git a/libstdc++-v3/include/precompiled/stdc++.h 
b/libstdc++-v3/include/precompiled/stdc++.h
index 9b056bb3467..80769233eb3 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -134,6 +134,7 @@
 #endif
 
 #if __cplusplus > 201703L
+#include 
 // #include 
 // #include 
 // #include 
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
new file mode 100644
index 000..76aa0957b56
--- /dev/null
+++ b/libstdc++-v3/include/std/bit
@@ -0,0 +1,359 @@
+//  -*- C++ -*-
+
+// Copyright (C) 2018 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 

[PATCH] Remove redundant #if conditional

2018-07-03 Thread Jonathan Wakely

The whole file is guarded by the same check already.

* include/bits/alloc_traits.h: Remove redundant preprocessor
condition.

Tested powerpc64le-linux, committed to trunk.

commit 76fd352d2bccd2a7399f6693cb5c7a8e9c65274b
Author: Jonathan Wakely 
Date:   Tue Jul 3 00:26:07 2018 +0100

Remove redundant #if conditional

The whole file is guarded by the same check already.

* include/bits/alloc_traits.h: Remove redundant preprocessor
condition.

diff --git a/libstdc++-v3/include/bits/alloc_traits.h 
b/libstdc++-v3/include/bits/alloc_traits.h
index eee9d8502e4..742fdd0447d 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -598,7 +598,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : is_copy_constructible<_Tp>
 { };
 
-#if __cplusplus >= 201103L
   // Trait to detect Allocator-like types.
   template
 struct __is_allocator : false_type { };
@@ -612,10 +611,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 using _RequireAllocator
   = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
-#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-
-#endif
-#endif
+#endif // C++11
+#endif // _ALLOC_TRAITS_H


Re: [PATCH] P0556R3 Integral power-of-2 operations, P0553R2 Bit operations

2018-07-03 Thread Jonathan Wakely

On 03/07/18 23:40 +0200, Jakub Jelinek wrote:

On Tue, Jul 03, 2018 at 10:02:47PM +0100, Jonathan Wakely wrote:

+#ifndef _GLIBCXX_BIT
+#define _GLIBCXX_BIT 1
+
+#pragma GCC system_header
+
+#if __cplusplus >= 201402L
+
+#include 
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template
+constexpr _Tp
+__rotl(_Tp __x, unsigned int __s) noexcept
+{
+  constexpr auto _Nd = numeric_limits<_Tp>::digits;
+  const unsigned __sN = __s % _Nd;
+  if (__sN)
+return (__x << __sN) | (__x >> (_Nd - __sN));


Wouldn't it be better to use some branchless pattern that
GCC can also optimize well, like:
 return (__x << __sN) | (__x >> ((-_sN) & (_Nd - 1)));
(iff _Nd is always power of two),


_Nd is 20 for one of the INT_N types on msp340, but we could have a
special case for the rare integer types with unusual sizes.


or perhaps
 return (__x << __sN) | (__x >> ((-_sN) % _Nd));
which is going to be folded into the above one for power of two constants?


That looks good.


E.g. ia32intrin.h also uses:
/* 64bit rol */
extern __inline unsigned long long
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
__rolq (unsigned long long __X, int __C)
{
 __C &= 63;
 return (__X << __C) | (__X >> (-__C & 63));
}
etc.


Should we delegate to those intrinsics for x86, so that
__builtin_ia32_rolqi and __builtin_ia32_rolhi can be used when
relevant?




Re: [PATCH] P0556R3 Integral power-of-2 operations, P0553R2 Bit operations

2018-07-04 Thread Jonathan Wakely

On 03/07/18 23:23 +0100, Jonathan Wakely wrote:

On 03/07/18 23:40 +0200, Jakub Jelinek wrote:

On Tue, Jul 03, 2018 at 10:02:47PM +0100, Jonathan Wakely wrote:

+#ifndef _GLIBCXX_BIT
+#define _GLIBCXX_BIT 1
+
+#pragma GCC system_header
+
+#if __cplusplus >= 201402L
+
+#include 
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template
+constexpr _Tp
+__rotl(_Tp __x, unsigned int __s) noexcept
+{
+  constexpr auto _Nd = numeric_limits<_Tp>::digits;
+  const unsigned __sN = __s % _Nd;
+  if (__sN)
+return (__x << __sN) | (__x >> (_Nd - __sN));


Wouldn't it be better to use some branchless pattern that
GCC can also optimize well, like:
return (__x << __sN) | (__x >> ((-_sN) & (_Nd - 1)));
(iff _Nd is always power of two),


_Nd is 20 for one of the INT_N types on msp340, but we could have a
special case for the rare integer types with unusual sizes.


or perhaps
return (__x << __sN) | (__x >> ((-_sN) % _Nd));
which is going to be folded into the above one for power of two constants?


That looks good.


Committed as attached (with a test I forgot to add for popcount).


commit 796e90be02c691bc57c89172940aa047caa199ab
Author: Jonathan Wakely 
Date:   Wed Jul 4 00:07:43 2018 +0100

Optimize std::rotl and std::rotr, add test for std::popcount

* include/std/bit (__rotl, __rotr): Avoid branch.
(_If_is_unsigned_integer): Use remove_cv_t.
* testsuite/26_numerics/bit/bitops.count/popcount.cc: New.

diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index 76aa0957b56..ace88954030 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -46,9 +46,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   constexpr auto _Nd = numeric_limits<_Tp>::digits;
   const unsigned __sN = __s % _Nd;
-  if (__sN)
-return (__x << __sN) | (__x >> (_Nd - __sN));
-  return __x;
+  return (__x << __sN) | (__x >> ((-__sN) % _Nd));
 }
 
   template
@@ -57,9 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   constexpr auto _Nd = numeric_limits<_Tp>::digits;
   const unsigned __sN = __s % _Nd;
-  if (__sN)
-return (__x >> __sN) | (__x << (_Nd - __sN));
-  return __x;
+  return (__x >> __sN) | (__x << ((-__sN) % _Nd));
 }
 
   template
@@ -237,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 using _If_is_unsigned_integer
-  = typename _If_is_unsigned_integer_type<_Tp, _Up>::type;
+  = typename _If_is_unsigned_integer_type, _Up>::type;
 
 #if ! __STRICT_ANSI__
   // [bitops.rot], rotating
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/popcount.cc b/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/popcount.cc
new file mode 100644
index 000..2982cb19bbe
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/popcount.cc
@@ -0,0 +1,108 @@
+// Copyright (C) 2018 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-do run { target c++11 } }
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include 
+
+template
+constexpr auto
+test(UInt x)
+-> decltype(std::popcount(x))
+{
+  static_assert( noexcept(std::popcount(x)) );
+
+  constexpr unsigned digits = std::numeric_limits::digits;
+
+  static_assert( std::popcount((UInt)0) == 0 );
+  static_assert( std::popcount((UInt)-1) == digits );
+  static_assert( std::popcount((UInt)-2) == digits - 1 );
+  static_assert( std::popcount((UInt)127) == 7 );
+
+  static_assert( std::popcount((UInt)1) == 1 );
+  static_assert( std::popcount((UInt)2) == 1 );
+  static_assert( std::popcount((UInt)0x70) == 3 );
+
+  if constexpr (std::numeric_limits::digits > 8)
+  {
+static_assert( std::popcount((UInt)(0x101)) == 2 );
+static_assert( std::popcount((UInt)(0xfff)) == 12 );
+  }
+
+  if constexpr (std::numeric_limits::digits > 64)
+  {
+static_assert( std::popcount((UInt)0x) == 64 );
+static_assert( std::popcount(0x | ((UInt)1 << 64)) == 33 );
+static_assert( std::popcount(0x55

Re: [PATCH] P0556R3 Integral power-of-2 operations, P0553R2 Bit operations

2018-07-04 Thread Jonathan Wakely

On 04/07/18 10:09 +0200, Jakub Jelinek wrote:

On Tue, Jul 03, 2018 at 11:24:00PM +0100, Jonathan Wakely wrote:

> Wouldn't it be better to use some branchless pattern that
> GCC can also optimize well, like:
>  return (__x << __sN) | (__x >> ((-_sN) & (_Nd - 1)));
> (iff _Nd is always power of two),

_Nd is 20 for one of the INT_N types on msp340, but we could have a
special case for the rare integer types with unusual sizes.

> or perhaps
>  return (__x << __sN) | (__x >> ((-_sN) % _Nd));
> which is going to be folded into the above one for power of two constants?

That looks good.


Unfortunately it is not correct if _Nd is not power of two.
E.g. for __sN 1, -1U % 20 is 15, not 19.
So it would need to be
 return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd));
Unfortunately, our rotate pattern recognizer handles
 return (__x << __sN) | (__x >> ((-__sN) % _Nd));
or
 return (__x << __sN) | (__x >> ((-__sN) & (_Nd - 1)));
but doesn't handle the _Nd - __sN case.
Is this C++17+ only?  Then perhaps


The std::rotr and std::rotl functions are C++2a only, but I've added
the __rotr and __rotl versions for our own internal use in C++14 and
later.

In practice I have no internal use for rotr and rotl, so I could
remove the __rot[rl] forms. However, won't ((_Nd & (_Nd - 1)) optimize
to a constant even without if-constexpr? I'll check.


 if constexpr ((_Nd & (_Nd - 1)) == 0)
return (__x << __sN) | (__x >> (-__sN & (_Nd - 1)));
 return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd));

Verify that on x86_64 for all the unsigned {char,short,int,long long} you
actually get a mere rol? instruction with perhaps some register movement,
but no masking, nor shifts etc.


Will do.


> E.g. ia32intrin.h also uses:
> /* 64bit rol */
> extern __inline unsigned long long
> __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> __rolq (unsigned long long __X, int __C)
> {
>  __C &= 63;
>  return (__X << __C) | (__X >> (-__C & 63));
> }
> etc.

Should we delegate to those intrinsics for x86, so that
__builtin_ia32_rolqi and __builtin_ia32_rolhi can be used when
relevant?


No, the pattern recognizers should handle (for power of two bitcounts)
even the char/short cases.  Those intrinsics predate the improvements
in rotate pattern recognition.


OK, good to know.




[PATCH] PR libstdc++/86398 fix std::is_trivially_constructible regression

2018-07-04 Thread Jonathan Wakely

The intrinsic doesn't check for allowed conversions between scalar
types, so restore the std::is_constructible check.

Also make some trivial whitespace changes.

PR libstdc++/86398
* include/std/type_traits (is_trivially_constructible): Check
is_constructible before __is_trivially_constructible.
* testsuite/20_util/is_trivially_constructible/value.cc: Add more
tests, including negative cases.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Use
zero for dg-error lineno.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
Likewise.

I got sick of repeatedly adjusting the dg-error lines in the
make_signed/make_unsigned tests so have just changed them to match any
line.

Tested powerpc64le-linux, committed to trunk.

commit dfa577ddbb6a4161f23e61fde5ca9ca09753a4ab
Author: Jonathan Wakely 
Date:   Wed Jul 4 09:40:07 2018 +0100

PR libstdc++/86398 fix std::is_trivially_constructible regression

The intrinsic doesn't check for allowed conversions between scalar
types, so restore the std::is_constructible check.

Also make some trivial whitespace changes.

PR libstdc++/86398
* include/std/type_traits (is_trivially_constructible): Check
is_constructible before __is_trivially_constructible.
* testsuite/20_util/is_trivially_constructible/value.cc: Add more
tests, including negative cases.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Use
zero for dg-error lineno.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
Likewise.

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index accea6df648..4df82bf6d8c 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1136,7 +1136,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_trivially_constructible
   template
 struct is_trivially_constructible
-: public __bool_constant<__is_trivially_constructible(_Tp, _Args...)>
+: public __and_, __bool_constant<
+ __is_trivially_constructible(_Tp, _Args...)>>::type
 { };
 
   /// is_trivially_default_constructible
@@ -1159,21 +1160,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 struct __is_implicitly_default_constructible_impl
-  : public __do_is_implicitly_default_constructible_impl
-  {
-typedef decltype(__test(declval<_Tp>())) type;
-  };
+: public __do_is_implicitly_default_constructible_impl
+{
+  typedef decltype(__test(declval<_Tp>())) type;
+};
 
   template
 struct __is_implicitly_default_constructible_safe
-  : public __is_implicitly_default_constructible_impl<_Tp>::type
-  { };
+: public __is_implicitly_default_constructible_impl<_Tp>::type
+{ };
 
   template 
 struct __is_implicitly_default_constructible
-  : public __and_,
-  __is_implicitly_default_constructible_safe<_Tp>>
-  { };
+: public __and_,
+   __is_implicitly_default_constructible_safe<_Tp>>
+{ };
 
   /// is_trivially_copy_constructible
 
diff --git a/libstdc++-v3/testsuite/20_util/is_trivially_constructible/value.cc 
b/libstdc++-v3/testsuite/20_util/is_trivially_constructible/value.cc
index d2ab27df86f..f260c2a7927 100644
--- a/libstdc++-v3/testsuite/20_util/is_trivially_constructible/value.cc
+++ b/libstdc++-v3/testsuite/20_util/is_trivially_constructible/value.cc
@@ -44,124 +44,140 @@ void test01()
   using std::is_trivially_constructible;
   using namespace __gnu_test;
 
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(false), "PR 86398");
+  static_assert(test_property(false), "PR 86398");
+  static_assert(test_property(false), "PR 86398");
+  static_assert(test_property(false), "PR 86398");
+  static_assert(test_property(false), "PR 86398");
+  static_assert(test_property(false), "");
+  static_assert(test_property(true), "");
+  static_assert(test_property(true), "");
+  static_assert(test_property(true), "");
+  static_assert(test_property(false), "");
-  static_assert(test_property(false), "");
-  static_assert(test_property(false), "");
-  static_assert(test_property(false), "");
-  static_assert(test_property(false), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), "");
-  static_assert(test_property(true), ""

Re: [PATCH] P0556R3 Integral power-of-2 operations, P0553R2 Bit operations

2018-07-04 Thread Jonathan Wakely

On 04/07/18 10:26 +0200, Jakub Jelinek wrote:

On Wed, Jul 04, 2018 at 09:14:04AM +0100, Jonathan Wakely wrote:

> Unfortunately it is not correct if _Nd is not power of two.
> E.g. for __sN 1, -1U % 20 is 15, not 19.
> So it would need to be
>  return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd));
> Unfortunately, our rotate pattern recognizer handles
>  return (__x << __sN) | (__x >> ((-__sN) % _Nd));
> or
>  return (__x << __sN) | (__x >> ((-__sN) & (_Nd - 1)));
> but doesn't handle the _Nd - __sN case.
> Is this C++17+ only?  Then perhaps

The std::rotr and std::rotl functions are C++2a only, but I've added
the __rotr and __rotl versions for our own internal use in C++14 and
later.

In practice I have no internal use for rotr and rotl, so I could
remove the __rot[rl] forms. However, won't ((_Nd & (_Nd - 1)) optimize
to a constant even without if-constexpr? I'll check.


It should, sure.

Anyway, I guess my C tests didn't test properly what happens in your
functions.  We actually do optimize:
unsigned long long foo (unsigned long long __x, unsigned int __s)
{
 constexpr int _Nd = 64;
 unsigned int _sN = __s % _Nd;
 return (__x << _sN) | (__x >> ((_Nd - _sN) % _Nd));
}
properly, just don't do it if it is:
unsigned long long foo (unsigned long long __x, unsigned int __s)
{
 int _Nd = 64;
 unsigned int _sN = __s % _Nd;
 return (__x << _sN) | (__x >> ((_Nd - _sN) % _Nd));
}
Apparently, the (64 - x) & 63 optimization to -x & 63 is only done
somewhere in the FEs and not in match.pd, which is something we should fix.

But with constexpr _Nd you actually can use
 return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd));
unconditionally.


OK here's what I've just tested and committed to trunk.


commit 35640efe0911095ad6ce38771e40a22a6cbb1221
Author: Jonathan Wakely 
Date:   Wed Jul 4 14:37:57 2018 +0100

Fix std::__rotl and std::__rotr

2018-07-04  Jonathan Wakely  
Jakub Jelinek  

* include/std/bit (__rotl, __rotr): Fix for non-power of two sizes.

diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index ace88954030..a23f2ba60d1 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -46,7 +46,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   constexpr auto _Nd = numeric_limits<_Tp>::digits;
   const unsigned __sN = __s % _Nd;
-  return (__x << __sN) | (__x >> ((-__sN) % _Nd));
+  return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd));
 }
 
   template
@@ -55,7 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   constexpr auto _Nd = numeric_limits<_Tp>::digits;
   const unsigned __sN = __s % _Nd;
-  return (__x >> __sN) | (__x << ((-__sN) % _Nd));
+  return (__x >> __sN) | (__x << ((_Nd - __sN) % _Nd));
 }
 
   template


Re: [PATCH] Add experimental::sample and experimental::shuffle from N4531

2018-07-04 Thread Jonathan Wakely

On 29/06/18 10:45 +0100, Jonathan Wakely wrote:

On 29/06/18 09:39 +0200, Christophe Lyon wrote:

On Fri, 29 Jun 2018 at 09:21, Jonathan Wakely  wrote:


On 29/06/18 08:55 +0200, Christophe Lyon wrote:

On Mon, 25 Jun 2018 at 18:23, Jonathan Wakely  wrote:


The additions to  were added in 2015 but the new
algorithms in  were not. This adds them.

* include/experimental/algorithm (sample, shuffle): Add new overloads
using per-thread random number engine.
* testsuite/experimental/algorithm/sample.cc: Simpify and reduce
dependencies by using __gnu_test::test_container.
* testsuite/experimental/algorithm/sample-2.cc: New.
* testsuite/experimental/algorithm/shuffle.cc: New.

Tested x86_64-linux, committed to trunk.

This would be safe to backport, but nobody has noticed the algos are
missing or complained, so it doesn't seem very important to backport.




Hi,

On bare-metal targets (aarch64 and arm + newlib), I've noticed that
the two new tests fail:
PASS: experimental/algorithm/shuffle.cc (test for excess errors)
spawn 
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc3/utils/bin/qemu-wrapper.sh
./shuffle.exe
terminate called after throwing an instance of 'std::runtime_error'
 what():  random_device::random_device(const std::string&)

*** EXIT code 4242
FAIL: experimental/algorithm/shuffle.cc execution test

PASS: experimental/algorithm/sample-2.cc (test for excess errors)
spawn 
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc3/utils/bin/qemu-wrapper.sh
./sample-2.exe
terminate called after throwing an instance of 'std::runtime_error'
 what():  random_device::random_device(const std::string&)

*** EXIT code 4242
FAIL: experimental/algorithm/sample-2.cc execution test

Does this ring a bell?


Does the existing testsuite/experimental/random/randint.cc file fail
in the same way?



Yes it does.

And so do:
25_algorithms/make_heap/complexity.cc


This one also uses std::random_device.


23_containers/array/element_access/at_neg.cc


Hmm,

// Expected behavior is to either throw and have the uncaught
// exception end up in a terminate handler which eventually exits,
// or abort. (Depending on -fno-exceptions.)

So this is expected to XFAIL.


26_numerics/random/random_device/cons/default.cc


We should XFAIL the ones that use std::random_device, if we can
identify an effective target to describe them.


This adds a new "random_device" effective-target, so the tests are
disabled when the random_device isn't usable.

Tested powerpc64le-linux, committed to trunk. If this works for
Christophe's bare metal targets I'll backport it to gcc-8-branch too.


commit b32bcdc1dc7ff6d483a4a7223d78198b7522cbe4
Author: Jonathan Wakely 
Date:   Wed Jul 4 15:44:45 2018 +0100

Define "random_device" effective target

Currently only matches targets where _GLIBCXX_USE_RANDOM_TR1 is defined,
which means /dev/random and /dev/urandom are usable.

* testsuite/25_algorithms/make_heap/complexity.cc: Require effective
target for std::random_device.
* testsuite/26_numerics/random/random_device/cons/default.cc:
Likewise.
* testsuite/experimental/algorithm/sample-2.cc: Likewise.
* testsuite/experimental/algorithm/shuffle.cc: Likewise.
* testsuite/experimental/random/randint.cc: Likewise.
* testsuite/lib/libstdc++.exp
(check_effective_target_random_device): New proc.

diff --git a/libstdc++-v3/testsuite/25_algorithms/make_heap/complexity.cc b/libstdc++-v3/testsuite/25_algorithms/make_heap/complexity.cc
index cca48f61e0a..069d2d0433d 100644
--- a/libstdc++-v3/testsuite/25_algorithms/make_heap/complexity.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/make_heap/complexity.cc
@@ -16,6 +16,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do run { target c++11 } }
+// { dg-require-effective-target random_device }
 
 #include 
 #include 
diff --git a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc
index 38210963f7e..5a34526a5f7 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/random_device/cons/default.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++11 } }
+// { dg-require-effective-target random_device }
 // { dg-require-cstdint "" }
 //
 // 2008-11-24  Edward M. Smith-Rowland <3dw...@verizon.net>
diff --git a/libstdc++-v3/testsuite/experimental/algorithm/sample-2.cc b/libstdc++-v3/testsuite/experimental/algorithm/sample-2.cc
index 541d17e08a0..ef3f7daa14c 100644
--- a/libstdc++-v3/testsuite/experimental/algorithm/sample-2.cc
+++ b/libstdc++-v3/testsuite/experimental/algorithm/sample-2.cc
@@ -16,6 +16,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do run { target c++1

[PATCH] P0458R2 Checking for Existence of an Element in Associative Containers

2018-07-04 Thread Jonathan Wakely

* include/bits/stl_map.h (map::contains): Add for C++2a.
* include/bits/stl_multimap.h (multimap::contains): Likewise.
* include/bits/stl_multiset.h (multiset::contains): Likewise.
* include/bits/stl_set.h (set::contains): Likewise.
* include/bits/stl_tree.h (__has_is_transparent_t): Define alias.
(_Rb_tree::_M_find_tr, _Rb_tree::_M_count_tr)
(_Rb_tree::_M_lower_bound_tr, _Rb_tree::_M_upper_bound_tr)
(_Rb_tree::_M_equal_range_tr): Use __has_is_transparent_t.
* include/bits/unordered_map.h (unordered_map::contains)
(unordered_multimap::contains): Add for C++2a.
* include/bits/unordered_set.h (unordered_set::contains)
(unordered_multiset::contains): Likewise.
* testsuite/23_containers/map/operations/contains.cc: New.
* testsuite/23_containers/multimap/operations/contains.cc: New.
* testsuite/23_containers/multiset/operations/contains.cc: New.
* testsuite/23_containers/set/operations/contains.cc: New.
* testsuite/23_containers/unordered_map/operations/contains.cc: New.
* testsuite/23_containers/unordered_multimap/operations/contains.cc:
New.
* testsuite/23_containers/unordered_multiset/operations/contains.cc:
New.
* testsuite/23_containers/unordered_set/operations/contains.cc: New.

Tested powerpc64le-linux, committed to trunk.


commit c38607c44696e07f44f56abf339f5453b04a5e70
Author: Jonathan Wakely 
Date:   Wed Jul 4 19:15:11 2018 +0100

P0458R2 Checking for Existence of an Element in Associative Containers

* include/bits/stl_map.h (map::contains): Add for C++2a.
* include/bits/stl_multimap.h (multimap::contains): Likewise.
* include/bits/stl_multiset.h (multiset::contains): Likewise.
* include/bits/stl_set.h (set::contains): Likewise.
* include/bits/stl_tree.h (__has_is_transparent_t): Define alias.
(_Rb_tree::_M_find_tr, _Rb_tree::_M_count_tr)
(_Rb_tree::_M_lower_bound_tr, _Rb_tree::_M_upper_bound_tr)
(_Rb_tree::_M_equal_range_tr): Use __has_is_transparent_t.
* include/bits/unordered_map.h (unordered_map::contains)
(unordered_multimap::contains): Add for C++2a.
* include/bits/unordered_set.h (unordered_set::contains)
(unordered_multiset::contains): Likewise.
* testsuite/23_containers/map/operations/contains.cc: New.
* testsuite/23_containers/multimap/operations/contains.cc: New.
* testsuite/23_containers/multiset/operations/contains.cc: New.
* testsuite/23_containers/set/operations/contains.cc: New.
* testsuite/23_containers/unordered_map/operations/contains.cc: New.
* testsuite/23_containers/unordered_multimap/operations/contains.cc:
New.
* testsuite/23_containers/unordered_multiset/operations/contains.cc:
New.
* testsuite/23_containers/unordered_set/operations/contains.cc: New.

diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index b81a2c4b7fc..fdd058b060d 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -1223,6 +1223,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
   //@}
 
+#if __cplusplus > 201703L
+  //@{
+  /**
+   *  @brief  Finds whether an element with the given key exists.
+   *  @param  __x  Key of (key, value) pairs to be located.
+   *  @return  True if there is an element with the specified key.
+   */
+  bool
+  contains(const key_type& __x) const
+  { return _M_t.find(__x) != _M_t.end(); }
+
+  template
+	auto
+	contains(const _Kt& __x) const
+	-> decltype(_M_t._M_find_tr(__x), void(), true)
+	{ return _M_t._M_find_tr(__x) != _M_t.end(); }
+  //@}
+#endif
+
   //@{
   /**
*  @brief Finds the beginning of a subsequence matching given key.
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 23332ee53f8..9357d1db6aa 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -893,6 +893,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
   //@}
 
+#if __cplusplus > 201703L
+  //@{
+  /**
+   *  @brief  Finds whether an element with the given key exists.
+   *  @param  __x  Key of (key, value) pairs to be located.
+   *  @return  True if there is any element with the specified key.
+   */
+  bool
+  contains(const key_type& __x) const
+  { return _M_t.find(__x) != _M_t.end(); }
+
+  template
+	auto
+	contains(const _Kt& __x) const
+	-> decltype(_M_t._M_find_tr(__x), void(), true)
+	{ return _M_t._M_find_tr(__x) != _M_t.end(); }
+  //@}
+#endif
+
   //@{
   /**
*  @brief Finds the beginning of a subsequence matching giv

[PATCH] P0646R1 Improving the Return Value of Erase-Like Algorithms I

2018-07-04 Thread Jonathan Wakely

In C++2a the remove, remove_if and unique members of std::list and
std::forward_list have been changed to return the number of elements
removed. This is an ABI change for the remove members and the
non-template unique members, so an abi-tag is used to give those symbols
new mangled names in C++2a mode. For the function templates the return
type is part of the mangled name so no abi-tag is needed.

* include/bits/forward_list.h (__cpp_lib_list_remove_return_type):
Define.
(forward_list::__remove_return_type): Define typedef as size_type or
void, according to __cplusplus value.
(_GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
empty, according to __cplusplus value.
(forward_list::remove, forward_list::unique): Use typedef and macro
to change return type and add abi-tag for C++2a.
(forward_list::remove_if, forward_list::unique): Use
typedef to change return type for C++2a.
* include/bits/forward_list.tcc (_GLIBCXX20_ONLY): Define macro.
(forward_list::remove, forward_list::remove_if)
(forward_list::unique): Return number of removed elements
for C++2a.
* include/bits/list.tcc (_GLIBCXX20_ONLY): Define macro.
(list::remove, list::unique, list::remove_if)
(list::unique): Return number of removed elements
for C++2a.
* include/bits/stl_list.h (__cpp_lib_list_remove_return_type): Define.
(list::__remove_return_type): Define typedef as size_type or
void, according to __cplusplus value.
(_GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
empty, according to __cplusplus value.
(list::remove, list::unique): Use typedef and macro to change return
type and add abi-tag for C++2a.
(list::remove_if, list::unique): Use
typedef to change return type for C++2a.
* include/std/version (__cpp_lib_list_remove_return_type): Define.
* testsuite/23_containers/forward_list/operations/
remove_cxx20_return.cc: New.
* testsuite/23_containers/forward_list/operations/
unique_cxx20_return.cc: New.

Tested powerpc64le-linux, committed to trunk.


commit 438e6398493708d2fb13766c9dff5305ebb98eec
Author: Jonathan Wakely 
Date:   Wed Jul 4 20:13:34 2018 +0100

P0646R1 Improving the Return Value of Erase-Like Algorithms I

In C++2a the remove, remove_if and unique members of std::list and
std::forward_list have been changed to return the number of elements
removed. This is an ABI change for the remove members and the
non-template unique members, so an abi-tag is used to give those symbols
new mangled names in C++2a mode. For the function templates the return
type is part of the mangled name so no abi-tag is needed.

* include/bits/forward_list.h (__cpp_lib_list_remove_return_type):
Define.
(forward_list::__remove_return_type): Define typedef as size_type or
void, according to __cplusplus value.
(_GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag 
or
empty, according to __cplusplus value.
(forward_list::remove, forward_list::unique): Use typedef and macro
to change return type and add abi-tag for C++2a.
(forward_list::remove_if, forward_list::unique): Use
typedef to change return type for C++2a.
* include/bits/forward_list.tcc (_GLIBCXX20_ONLY): Define macro.
(forward_list::remove, forward_list::remove_if)
(forward_list::unique): Return number of removed elements
for C++2a.
* include/bits/list.tcc (_GLIBCXX20_ONLY): Define macro.
(list::remove, list::unique, list::remove_if)
(list::unique): Return number of removed elements
for C++2a.
* include/bits/stl_list.h (__cpp_lib_list_remove_return_type): 
Define.
(list::__remove_return_type): Define typedef as size_type or
void, according to __cplusplus value.
(_GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
empty, according to __cplusplus value.
(list::remove, list::unique): Use typedef and macro to change return
type and add abi-tag for C++2a.
(list::remove_if, list::unique): Use
typedef to change return type for C++2a.
* include/std/version (__cpp_lib_list_remove_return_type): Define.
* testsuite/23_containers/forward_list/operations/
remove_cxx20_return.cc: New.
* testsuite/23_containers/forward_list/operations/
unique_cxx20_return.cc: New.

diff --git a/libstdc++-v3/include/bits/forward_list.h 
b/libstdc++-v3/include/bits/forward_list.h
index 8c4c074e454..84a4ad4d5dc 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h

[wwwdocs] Document more C++2a support in libstdc++

2018-07-04 Thread Jonathan Wakely

Committed to CVS.


? htdocs/gcc-9/.changes.html.swp
Index: htdocs/gcc-9/changes.html
===
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-9/changes.html,v
retrieving revision 1.10
diff -u -r1.10 changes.html
--- htdocs/gcc-9/changes.html	2 Jul 2018 16:08:32 -	1.10
+++ htdocs/gcc-9/changes.html	4 Jul 2018 20:16:09 -
@@ -60,8 +60,11 @@
 Runtime Library (libstdc++)
 
   Improved experimental support for C++2a,
-  including std::remove_cvref
-  and the  header.
+  including type traits std::remove_cvref,
+  std::is_trivially_convertible, and
+  std::type_identity,
+  and headers  and .
+  
   Support for opening file streams with wide character paths on Windows
   Incomplete support for the C++17 Filesystem library and the Filesystem
   TS on Windows.


Re: [wwwdocs] Document more C++2a support in libstdc++

2018-07-04 Thread Jonathan Wakely

On 04/07/18 16:19 -0400, Tim Song wrote:

On Wed, Jul 4, 2018 at 4:17 PM, Jonathan Wakely  wrote:

+  std::is_trivially_convertible, and


s/trivially/nothrow/


Oops, thanks - fixed by this patch, also committed.


Index: htdocs/gcc-9/changes.html
===
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-9/changes.html,v
retrieving revision 1.11
diff -u -r1.11 changes.html
--- htdocs/gcc-9/changes.html	4 Jul 2018 20:16:47 -	1.11
+++ htdocs/gcc-9/changes.html	4 Jul 2018 20:21:58 -
@@ -61,7 +61,7 @@
 
   Improved experimental support for C++2a,
   including type traits std::remove_cvref,
-  std::is_trivially_convertible, and
+  std::is_nothrow_convertible, and
   std::type_identity,
   and headers <bit> and <version>.
   


Re: Enhance __gnu_debug::string debug assertion

2018-07-05 Thread Jonathan Wakely

On 05/07/18 07:28 +0200, François Dumont wrote:
    This patch improves the assertion message generated in 2 
__gnu_debug::string constructors giving the assertion context thanks 
to the __FUNCTION__ macro.


Was:

/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/string:56: 
const _CharT* __gnu_debug::__check_string(const _CharT*, _Integer, 
const char*, unsigned int, const char*) [with _CharT = char; _Integer 
= long unsigned int]: Assertion '__s != 0 || __n == 0' failed.

XFAIL: 21_strings/basic_string/debug/1_neg.cc execution test

Now:

/home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/string:172:
In function:
    __gnu_debug::basic_string<_CharT, _Traits,
    _Allocator>::basic_string(const _CharT*,
    __gnu_debug::basic_string<_CharT, _Traits, _Allocator>::size_type, 
const

    _Allocator&) [with _CharT = char; _Traits = std::char_traits;
    _Allocator = std::allocator; __gnu_debug::basic_string<_CharT,
    _Traits, _Allocator>::size_type = long unsigned int]

Error: __s != 0 || __n == 0.
XFAIL: 21_strings/basic_string/debug/1_neg.cc execution test

    Tested under Linux x86_64 normal and debug modes.

    If not told otherwise I plan to commit the attached patch tomorrow.


Looks good - thanks.



[PATCH] PR libstdc++/58265 implement LWG 2063 for COW strings

2018-07-05 Thread Jonathan Wakely

For COW strings the default constructor does not allocate when
_GLIBCXX_FULLY_DYNAMIC_STRING == 0, so can be noexcept. The move
constructor and swap do not allocate when the allocators are equal, so
add conditional noexcept using allocator_traits::is_always_equal.

PR libstdc++/58265
* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
[_GLIBCXX_FULLY_DYNAMIC_STRING==0] (basic_string::basic_string()):
Add GLIBCXX_NOEXCEPT.
(basic_string::operator=(basic_string&&)): Add _GLIBCXX_NOEXCEPT_IF
to depend on the allocator's is_always_equal property (LWG 2063).
(basic_string::swap(basic_string&)): Likewise.
* include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]
(basic_string::swap(basic_string&)): Likewise.
* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
Check is_nothrow_move_assignable.
* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
Check is_nothrow_move_assignable.
* testsuite/21_strings/basic_string/cons/char/
noexcept_move_construct.cc: Likewise.
* testsuite/21_strings/basic_string/cons/wchar_t/
noexcept_move_construct.cc: Likewise.

Tested powerpc64le-linux, committed to trunk.


commit 926b3b642595383cb4abfbeb3586eecc721c1935
Author: Jonathan Wakely 
Date:   Thu Jul 5 15:12:06 2018 +0100

PR libstdc++/58265 implement LWG 2063 for COW strings

For COW strings the default constructor does not allocate when
_GLIBCXX_FULLY_DYNAMIC_STRING == 0, so can be noexcept. The move
constructor and swap do not allocate when the allocators are equal, so
add conditional noexcept using allocator_traits::is_always_equal.

PR libstdc++/58265
* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
[_GLIBCXX_FULLY_DYNAMIC_STRING==0] (basic_string::basic_string()):
Add GLIBCXX_NOEXCEPT.
(basic_string::operator=(basic_string&&)): Add _GLIBCXX_NOEXCEPT_IF
to depend on the allocator's is_always_equal property (LWG 2063).
(basic_string::swap(basic_string&)): Likewise.
* include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]
(basic_string::swap(basic_string&)): Likewise.
* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
Check is_nothrow_move_assignable.
* 
testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
Check is_nothrow_move_assignable.
* testsuite/21_strings/basic_string/cons/char/
noexcept_move_construct.cc: Likewise.
* testsuite/21_strings/basic_string/cons/wchar_t/
noexcept_move_construct.cc: Likewise.

diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index a77074da249..baad58682b6 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3486,6 +3486,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*/
   basic_string()
 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
+  _GLIBCXX_NOEXCEPT
   : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
 #else
   : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()){ }
@@ -3642,7 +3643,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
*  @param  __str  Source string.
*/
   basic_string&
-  operator=(const basic_string& __str) 
+  operator=(const basic_string& __str)
   { return this->assign(__str); }
 
   /**
@@ -3675,9 +3676,9 @@ _GLIBCXX_END_NAMESPACE_CXX11
*  The contents of @a str are moved into this string (without copying).
*  @a str is a valid, but unspecified string.
**/
-  // PR 58265, this should be noexcept.
   basic_string&
   operator=(basic_string&& __str)
+  _GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)
   {
// NB: DR 1204.
this->swap(__str);
@@ -5111,9 +5112,9 @@ _GLIBCXX_END_NAMESPACE_CXX11
*  Exchanges the contents of this string with that of @a __s in constant
*  time.
   */
-  // PR 58265, this should be noexcept.
   void
-  swap(basic_string& __s);
+  swap(basic_string& __s)
+  _GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value);
 
   // String operations:
   /**
diff --git a/libstdc++-v3/include/bits/basic_string.tcc 
b/libstdc++-v3/include/bits/basic_string.tcc
index 04b68ca0202..51bbb7bd6a0 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -967,6 +967,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 void
 basic_string<_CharT, _Traits, _Alloc>::
 swap(basic_string& __s)
+_GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)
 {
   if (_M

Re: [PATCH] PR libstdc++/58265 implement LWG 2063 for COW strings

2018-07-05 Thread Jonathan Wakely

On 05/07/18 16:55 +0100, Jonathan Wakely wrote:

For COW strings the default constructor does not allocate when
_GLIBCXX_FULLY_DYNAMIC_STRING == 0, so can be noexcept. The move
constructor and swap do not allocate when the allocators are equal, so
add conditional noexcept using allocator_traits::is_always_equal.

PR libstdc++/58265
* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
[_GLIBCXX_FULLY_DYNAMIC_STRING==0] (basic_string::basic_string()):
Add GLIBCXX_NOEXCEPT.
(basic_string::operator=(basic_string&&)): Add _GLIBCXX_NOEXCEPT_IF
to depend on the allocator's is_always_equal property (LWG 2063).
(basic_string::swap(basic_string&)): Likewise.
* include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]
(basic_string::swap(basic_string&)): Likewise.
* testsuite/21_strings/basic_string/allocator/char/move_assign.cc:
Check is_nothrow_move_assignable.
* testsuite/21_strings/basic_string/allocator/wchar_t/move_assign.cc:
Check is_nothrow_move_assignable.
* testsuite/21_strings/basic_string/cons/char/
noexcept_move_construct.cc: Likewise.
* testsuite/21_strings/basic_string/cons/wchar_t/
noexcept_move_construct.cc: Likewise.


I missed a bit, finished by this patch. With these changes the SSO and
COW strings are slightly closer in behaviour, although the COW one is
still missing lots of C++11 features (like passing const_iterator
instead of iterator) and C++17 features (deduction guides).

Tested powerpc64le-linux, committed to trunk.


commit 265fc27e34d7fb8fb80653e3f9782c56c70a7ce4
Author: Jonathan Wakely 
Date:   Thu Jul 5 17:08:54 2018 +0100

PR libstdc++/58265 add noexcept to basic_string::assign(basic_string&&)

PR libstdc++/58265
* include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI]
(basic_string::assign(basic_string&&)): Add conditional noexcept
depending on the allocator's is_always_equal property (LWG 2063).
* testsuite/21_strings/basic_string/modifiers/assign/char/
move_assign.cc: Check for non-throwing exception specification.
* testsuite/21_strings/basic_string/modifiers/assign/wchar_t/
move_assign.cc: Likewise.

diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index baad58682b6..2d1b9dc6c29 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -725,7 +725,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*  The contents of @a str are moved into this string (without copying).
*  @a str is a valid, but unspecified string.
**/
-  // PR 58265, this should be noexcept.
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 2063. Contradictory requirements for string move assignment
   basic_string&
@@ -4275,9 +4274,9 @@ _GLIBCXX_END_NAMESPACE_CXX11
*  This function sets this string to the exact contents of @a __str.
*  @a __str is a valid, but unspecified string.
*/
-  // PR 58265, this should be noexcept.
   basic_string&
   assign(basic_string&& __str)
+  noexcept(allocator_traits<_Alloc>::is_always_equal::value)
   {
 	this->swap(__str);
 	return *this;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/move_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/move_assign.cc
index e9116b9c0e0..7089fea04c2 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/move_assign.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/char/move_assign.cc
@@ -32,6 +32,9 @@ void test01()
   a.push_back('1');
   b.assign(std::move(a));
   VERIFY( b.size() == 1 && b[0] == '1' && a.size() == 0 );
+
+  // True for std::allocator because is_always_equal, but not true in general:
+  static_assert(noexcept(a.assign(std::move(b))), "lwg 2063");
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/move_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/move_assign.cc
index 74e342a8ef4..8d394602a9f 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/move_assign.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/assign/wchar_t/move_assign.cc
@@ -32,6 +32,9 @@ void test01()
   a.push_back(L'1');
   b.assign(std::move(a));
   VERIFY( b.size() == 1 && b[0] == '1' && a.size() == 0 );
+
+  // True for std::allocator because is_always_equal, but not true in general:
+  static_assert(noexcept(a.assign(std::move(b))), "lwg 2063");
 }
 
 int main()


[PATCH] Add xfail-if to some tests that fail with COW strings

2018-07-05 Thread Jonathan Wakely
These tests fail when run with -D_GLIBCXX_USE_CXX11_ABI=0 


* testsuite/21_strings/basic_string/cons/char/deduction.cc: XFAIL for
COW strings.
* testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc:
Likewise.
* testsuite/21_strings/basic_string/requirements/
explicit_instantiation/debug.cc: Likewise.

Tested powerpc64le-linux, committed to trunk.

commit 643a1bb749c54ecc5faed9c675d7f4a29cfbea6a
Author: Jonathan Wakely 
Date:   Thu Jul 5 17:44:09 2018 +0100

Add xfail-if to some tests that fail with COW strings

These tests fail when run with -D_GLIBCXX_USE_CXX11_ABI=0

* testsuite/21_strings/basic_string/cons/char/deduction.cc: XFAIL 
for
COW strings.
* testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc:
Likewise.
* testsuite/21_strings/basic_string/requirements/
explicit_instantiation/debug.cc: Likewise.

diff --git 
a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/deduction.cc 
b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/deduction.cc
index fc28467e29b..4662fbd4b4d 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/deduction.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/deduction.cc
@@ -17,6 +17,7 @@
 
 // { dg-options "-std=gnu++17" }
 // { dg-do compile { target c++17 } }
+// { dg-xfail-if "COW string missing deduction guides" { ! cxx11-abi } }
 
 #include 
 #include 
diff --git 
a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc 
b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc
index c40651f13db..7740af51123 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc
@@ -17,6 +17,7 @@
 
 // { dg-options "-std=gnu++17" }
 // { dg-do compile { target c++17 } }
+// { dg-xfail-if "COW string missing deduction guides" { ! cxx11-abi } }
 
 #include 
 #include 
diff --git 
a/libstdc++-v3/testsuite/21_strings/basic_string/requirements/explicit_instantiation/debug.cc
 
b/libstdc++-v3/testsuite/21_strings/basic_string/requirements/explicit_instantiation/debug.cc
index a166a9b1d58..20b8f59ba3d 100644
--- 
a/libstdc++-v3/testsuite/21_strings/basic_string/requirements/explicit_instantiation/debug.cc
+++ 
b/libstdc++-v3/testsuite/21_strings/basic_string/requirements/explicit_instantiation/debug.cc
@@ -20,8 +20,9 @@
 #include 
 
 // { dg-do compile }
+// { dg-xfail-if "COW string missing some required members" { ! cxx11-abi } }
 
 // libstdc++/21770
 namespace debug = __gnu_debug;
-template class debug::basic_string, 
+template class debug::basic_string,
   std::allocator >;


[PATCH] PR libstdc++/85831 define move constructors and operators for exceptions

2018-07-05 Thread Jonathan Wakely

PR libstdc++/85831
* config/abi/pre/gnu.ver: Export move constructors and move
assignment operators for std::logic_error and std::runtime_error.
* include/std/stdexcept: Use _GLIBCXX_NOTHROW instead of
_GLIBCXX_USE_NOEXCEPT.
(logic_error, runtime_error): Declare move constructors and move
assignment operators. When not declared already, define copy
constructors and copy assignment operators as explicit-defaulted.
(domain_error, invalid_argument, length_error, out_of_range)
(overflow_error, underflow_error): Define move constructors and move
assignment operators as explicitly-defaulted.
* libsupc++/exception.h (exception): Likewise.
* src/c++11/cow-stdexcept.cc (logic_error, runtime_error): Define
move constructors and move assignment operators as defaulted.
* testsuite/19_diagnostics/stdexcept.cc: Check that constructors and
assignment operators are defined.

Tested powerpc64le-linux, committed to trunk.

commit cdf98fe7aeb8f7815daed0d30709395ef2d34d7a
Author: Jonathan Wakely 
Date:   Thu Jul 5 12:09:48 2018 +0100

PR libstdc++/85831 define move constructors and operators for exceptions

PR libstdc++/85831
* config/abi/pre/gnu.ver: Export move constructors and move
assignment operators for std::logic_error and std::runtime_error.
* include/std/stdexcept: Use _GLIBCXX_NOTHROW instead of
_GLIBCXX_USE_NOEXCEPT.
(logic_error, runtime_error): Declare move constructors and move
assignment operators. When not declared already, define copy
constructors and copy assignment operators as explicit-defaulted.
(domain_error, invalid_argument, length_error, out_of_range)
(overflow_error, underflow_error): Define move constructors and move
assignment operators as explicitly-defaulted.
* libsupc++/exception.h (exception): Likewise.
* src/c++11/cow-stdexcept.cc (logic_error, runtime_error): Define
move constructors and move assignment operators as defaulted.
* testsuite/19_diagnostics/stdexcept.cc: Check that constructors and
assignment operators are defined.

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index 782b1238742..521cebf1f80 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2014,6 +2014,13 @@ GLIBCXX_3.4.26 {
 # std::basic_string::insert(const_iterator, initializer_list)
 
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEN9__gnu_cxx17__normal_iteratorIPK[cw]S4_EESt16initializer_listI[cw]E;
 
+# std::logic_error move operations
+_ZNSt11logic_errorC[12]EOS_;
+_ZNSt11logic_erroraSEOS_;
+# std::runtime_error move operations
+_ZNSt13runtime_errorC[12]EOS_;
+_ZNSt13runtime_erroraSEOS_;
+
 } GLIBCXX_3.4.25;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/include/std/stdexcept 
b/libstdc++-v3/include/std/stdexcept
index 5267e5692bf..4fcc719f005 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -55,8 +55,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 __cow_string();
 __cow_string(const std::string&);
 __cow_string(const char*, size_t);
-__cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT;
-__cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT;
+__cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
+__cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
 ~__cow_string();
 #if __cplusplus >= 201103L
 __cow_string(__cow_string&&) noexcept;
@@ -83,7 +83,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   char _M_bytes[sizeof(__str)];
 };
 
-__sso_string() _GLIBCXX_USE_NOEXCEPT;
+__sso_string() _GLIBCXX_NOTHROW;
 __sso_string(const std::string&);
 __sso_string(const char*, size_t);
 __sso_string(const __sso_string&);
@@ -122,19 +122,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
 explicit
 logic_error(const char*) _GLIBCXX_TXN_SAFE;
+
+logic_error(logic_error&&) noexcept;
+logic_error& operator=(logic_error&&) noexcept;
 #endif
 
 #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
-logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
-logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
+logic_error(const logic_error&) _GLIBCXX_NOTHROW;
+logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
+#elif __cplusplus >= 201103L
+logic_error(const logic_error&) = default;
+logic_error& operator=(const logic_error&) = default;
 #endif
 
-virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+   

[PATCH] include/std/variant (__accepted_index): Use void_t.

2018-07-06 Thread Jonathan Wakely

Tested powerpc64le-linux, committed to trunk.


commit d66ad3c7feea986bfb95543e07b7063931d97e96
Author: Jonathan Wakely 
Date:   Fri Jul 6 09:58:12 2018 +0100

* include/std/variant (__accepted_index): Use void_t.

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 63eafdd58e5..66d878142a4 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -710,7 +710,8 @@ namespace __variant
 };
 
   // Helper for variant(_Tp&&) and variant::operator=(_Tp&&).
-  // __accepted_index maps the arbitrary _Tp to an alternative type in 
_Variant.
+  // __accepted_index maps an arbitrary _Tp to an alternative type in _Variant
+  // (or to variant_npos).
   template
 struct __accepted_index
 { static constexpr size_t value = variant_npos; };
@@ -718,8 +719,7 @@ namespace __variant
   template
 struct __accepted_index<
   _Tp, variant<_Types...>,
-  decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()),
-  std::declval())>
+  void_t::_S_fun(std::declval<_Tp>()))>>
 {
   static constexpr size_t value = sizeof...(_Types) - 1
- decltype(__overload_set<_Types...>::


[PATCH] P0935R0 Eradicating unnecessarily explicit default constructors

2018-07-06 Thread Jonathan Wakely

This is the last remaining piece of P0935R0. This adds a default
constructor to each of the streambuf and stream types in  so
that default construction does not use the 'explicit' constructor that
has a single, defaulted argument.

P0935R0 Eradicating unnecessarily explicit default constructors
* config/abi/pre/gnu.ver: Tighten existing patterns and export new
default constructor symbols.
* include/std/sstream (basic_stringbuf, basic_istringstream)
(basic_ostringstream, basic_stringstream): Remove default arguments
from explicit constructors taking ios_base::openmode and add separate
non-explicit default constructors.
* testsuite/27_io/basic_istringstream/cons/default.cc: New.
* testsuite/27_io/basic_ostringstream/cons/default.cc: New.
* testsuite/27_io/basic_stringstream/cons/default.cc: New.
* testsuite/27_io/basic_stringbuf/cons/char/default.cc: New.
* testsuite/27_io/basic_stringbuf/cons/wchar_t/default.cc: New.

Tested powerpc64le-linux, committed to trunk.

commit 650035269ded698f16e66fa04f8d21dcb1b94fa8
Author: Jonathan Wakely 
Date:   Fri Jul 6 11:38:57 2018 +0100

P0935R0 Eradicating unnecessarily explicit default constructors

This is the last remaining piece of P0935R0. This adds a default
constructor to each of the streambuf and stream types in  so
that default construction does not use the 'explicit' constructor that
has a single, defaulted argument.

P0935R0 Eradicating unnecessarily explicit default constructors
* config/abi/pre/gnu.ver: Tighten existing patterns and export new
default constructor symbols.
* include/std/sstream (basic_stringbuf, basic_istringstream)
(basic_ostringstream, basic_stringstream): Remove default arguments
from explicit constructors taking ios_base::openmode and add 
separate
non-explicit default constructors.
* testsuite/27_io/basic_istringstream/cons/default.cc: New.
* testsuite/27_io/basic_ostringstream/cons/default.cc: New.
* testsuite/27_io/basic_stringstream/cons/default.cc: New.
* testsuite/27_io/basic_stringbuf/cons/char/default.cc: New.
* testsuite/27_io/basic_stringbuf/cons/wchar_t/default.cc: New.

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index 521cebf1f80..e634d3ab707 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1748,10 +1748,20 @@ GLIBCXX_3.4.21 {
 
_ZStplI[cw]St11char_traitsI[cw]ESaI[cw]EENSt7__cxx1112basic_stringIT_T0_T1_EE*;
 
 # ABI-tagged stringstreams
-_ZNSt7__cxx1115basic_stringbuf*;
-_ZNSt7__cxx1118basic_stringstream*;
-_ZNSt7__cxx1119basic_istringstream*;
-_ZNSt7__cxx1119basic_ostringstream*;
+#   _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]*;
+
_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[ORS]*;
+_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev;
+_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]*__xfer_bufptrs*;
+
_ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[a1346789]*;
+#   _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]*;
+
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[ORS]*;
+
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev;
+_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a34]*;
+#   _ZNSt7__cxx1119basic_istringstreamI[cw]St11char_traitsI[cw]*;
+#   _ZNSt7__cxx1119basic_ostringstreamI[cw]St11char_traitsI[cw]*;
+
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[ORS]*;
+
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev;
+
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a34]*;
 _ZNKSt7__cxx1115basic_stringbuf*;
 _ZNKSt7__cxx1118basic_stringstream*;
 _ZNKSt7__cxx1119basic_istringstream*;
@@ -2021,6 +2031,14 @@ GLIBCXX_3.4.26 {
 _ZNSt13runtime_errorC[12]EOS_;
 _ZNSt13runtime_erroraSEOS_;
 
+# Default constructors for stringstreams
+_ZNSt15basic_stringbuf[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+_ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+_ZNSt19basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+_ZNSt7__cxx1115basic_stringbuf[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+
 } GLIBCXX_3.4.25;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream
index 8ad18d00fb6..71d69e94b65 100644
--- a/libstdc++-v3

[PATCH] Simplify linker script patterns for std::exception_ptr

2018-07-06 Thread Jonathan Wakely

* config/abi/pre/gnu.ver: Use wildcards to combine related patterns.

Tested x86_64-linux and powerpc64le-linux, committed to trunk.

commit 6ae49a85e8e83390225aae7dbbe01518005cf34f
Author: Jonathan Wakely 
Date:   Fri Jul 6 13:40:00 2018 +0100

Simplify linker script patterns for std::exception_ptr

* config/abi/pre/gnu.ver: Use wildcards to combine related patterns.

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index e634d3ab707..b09bdef6d09 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2174,14 +2174,10 @@ CXXABI_1.3.3 {
 
 #ifdef HAVE_EXCEPTION_PTR_SINCE_GCC46
 # exception_ptr
-_ZNSt15__exception_ptr13exception_ptrC1Ev;
-_ZNSt15__exception_ptr13exception_ptrC2Ev;
-_ZNSt15__exception_ptr13exception_ptrC1ERKS0_;
-_ZNSt15__exception_ptr13exception_ptrC2ERKS0_;
-_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE;
-_ZNSt15__exception_ptr13exception_ptrC2EMS0_FvvE;
-_ZNSt15__exception_ptr13exception_ptrD1Ev;
-_ZNSt15__exception_ptr13exception_ptrD2Ev;
+_ZNSt15__exception_ptr13exception_ptrC[12]Ev;
+_ZNSt15__exception_ptr13exception_ptrC[12]ERKS0_;
+_ZNSt15__exception_ptr13exception_ptrC[12]EMS0_FvvE;
+_ZNSt15__exception_ptr13exception_ptrD[12]Ev;
 _ZNSt15__exception_ptr13exception_ptraSERKS0_;
 _ZNKSt15__exception_ptr13exception_ptrcvMS0_FvvEEv;
 _ZNKSt15__exception_ptr13exception_ptrntEv;


[PATCH] PR libstdc++/84928 use std::move in algorithms

2018-07-06 Thread Jonathan Wakely

P0616R0 altered the effects of the  algorithms to use std::move
on the accumulator values (resolving LWG 2055). This implements the
change for C++2a, but retains the previous behaviour for older
standards.

* include/bits/stl_numeric.h (_GLIBCXX_MOVE_IF_20): Define macro to
conditionally move, according to __cplusplus value.
(accumulate, inner_product, partial_sum, adjacent_difference): Use
_GLIBCXX_MOVE_IF_20.
* testsuite/26_numerics/accumulate/lwg2055.cc: New test.
* testsuite/26_numerics/adjacent_difference/lwg2055.cc: New test.
* testsuite/26_numerics/inner_product/lwg2055.cc: New test.
* testsuite/26_numerics/partial_sum/lwg2055.cc: New test.

Tested powerpc64le-linux, committed to trunk.


commit 1a98726ac77827d3978d694f33ef5183ff3c2def
Author: Jonathan Wakely 
Date:   Fri Jul 6 14:58:03 2018 +0100

PR libstdc++/84928 use std::move in  algorithms

P0616R0 altered the effects of the  algorithms to use std::move
on the accumulator values (resolving LWG 2055). This implements the
change for C++2a, but retains the previous behaviour for older
standards.

* include/bits/stl_numeric.h (_GLIBCXX_MOVE_IF_20): Define macro to
conditionally move, according to __cplusplus value.
(accumulate, inner_product, partial_sum, adjacent_difference): Use
_GLIBCXX_MOVE_IF_20.
* testsuite/26_numerics/accumulate/lwg2055.cc: New test.
* testsuite/26_numerics/adjacent_difference/lwg2055.cc: New test.
* testsuite/26_numerics/inner_product/lwg2055.cc: New test.
* testsuite/26_numerics/partial_sum/lwg2055.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_numeric.h 
b/libstdc++-v3/include/bits/stl_numeric.h
index dcc29fe065c..f4f6f9ef5ae 100644
--- a/libstdc++-v3/include/bits/stl_numeric.h
+++ b/libstdc++-v3/include/bits/stl_numeric.h
@@ -104,6 +104,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_ALGO
 
+#if __cplusplus > 201703L
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// DR 2055. std::move in std::accumulate and other algorithms
+# define _GLIBCXX_MOVE_IF_20(_E) std::move(_E)
+#else
+# define _GLIBCXX_MOVE_IF_20(_E) _E
+#endif
+
   /**
*  @brief  Accumulate values in a range.
*
@@ -124,7 +132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   __glibcxx_requires_valid_range(__first, __last);
 
   for (; __first != __last; ++__first)
-   __init = __init + *__first;
+   __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
   return __init;
 }
 
@@ -151,7 +159,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   __glibcxx_requires_valid_range(__first, __last);
 
   for (; __first != __last; ++__first)
-   __init = __binary_op(__init, *__first);
+   __init = __binary_op(_GLIBCXX_MOVE_IF_20(__init), *__first);
   return __init;
 }
 
@@ -180,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   __glibcxx_requires_valid_range(__first1, __last1);
 
   for (; __first1 != __last1; ++__first1, (void)++__first2)
-   __init = __init + (*__first1 * *__first2);
+   __init = _GLIBCXX_MOVE_IF_20(__init) + (*__first1 * *__first2);
   return __init;
 }
 
@@ -214,7 +222,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   __glibcxx_requires_valid_range(__first1, __last1);
 
   for (; __first1 != __last1; ++__first1, (void)++__first2)
-   __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
+   __init = __binary_op1(_GLIBCXX_MOVE_IF_20(__init),
+ __binary_op2(*__first1, *__first2));
   return __init;
 }
 
@@ -251,7 +260,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   *__result = __value;
   while (++__first != __last)
{
- __value = __value + *__first;
+ __value = _GLIBCXX_MOVE_IF_20(__value) + *__first;
  *++__result = __value;
}
   return ++__result;
@@ -292,7 +301,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   *__result = __value;
   while (++__first != __last)
{
- __value = __binary_op(__value, *__first);
+ __value = __binary_op(_GLIBCXX_MOVE_IF_20(__value), *__first);
  *++__result = __value;
}
   return ++__result;
@@ -332,7 +341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   while (++__first != __last)
{
  _ValueType __tmp = *__first;
- *++__result = __tmp - __value;
+ *++__result = __tmp - _GLIBCXX_MOVE_IF_20(__value);
  __value = _GLIBCXX_MOVE(__tmp);
}
   return ++__result;
@@ -375,12 +384,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   while (++__first != __last)
{
  _ValueType __tmp = *__first;
- *++__result = __binary_op(__tmp, __value);
+ *++__result = __binary_op(__tmp, _GLIBCXX_MOVE_IF_20(__value));
  __value = _GLIBCXX_MOVE(__tmp);
}
   return ++__result;
 }
 
+#undef _GLIBCXX_MOVE_IF_20
+
 _GLIBCXX_END_NAMESPACE_ALGO
 } // namespace std
 
d

Re: [PATCH] S/390: libstdc++: 64 and 32 bit baseline update

2018-07-16 Thread Jonathan Wakely

On 16/07/18 09:58 +0200, Andreas Krebbel wrote:

On 07/13/2018 04:58 PM, Andreas Schwab wrote:

On Jul 13 2018, Andreas Krebbel  wrote:


@@ -5645,3 +5657,5 @@ OBJECT:8:_ZTTSi@@GLIBCXX_3.4
 OBJECT:8:_ZTTSo@@GLIBCXX_3.4
 OBJECT:8:_ZTTSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4
 OBJECT:8:_ZTTSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4
+TLS:4:_ZSt11__once_call@@GLIBCXX_3.4.11
+TLS:4:_ZSt15__once_callable@@GLIBCXX_3.4.11


You should not have any TLS entries.


Ok, thanks. I've committed the patch with these entries removed.


Thanks!




[PATCH] PR libstdc++/86537 remove less> partial specialization

2018-07-16 Thread Jonathan Wakely

The standard doesn't specify this partial specialization (it was
required after the changes in N2637 but then should have been removed
following LWG 1262). Its presence is observable because it causes
different results when operator< has been overloaded for a shared_ptr
specialization.

PR libstdc++/86537
* include/bits/shared_ptr.h (less>): Remove
non-standard partial specialization.
* include/bits/shared_ptr_base.h (_Sp_less): Remove class definition.
(less<__shared_ptr<_Tp, _Lp>): Remove partial specialization.
* testsuite/20_util/shared_ptr/comparison/86537.cc: New test.

Tested powerpc64le-linux, committed to trunk.


commit 1c48999500e277c2ff1e742214857faef842f80c
Author: Jonathan Wakely 
Date:   Mon Jul 16 16:52:19 2018 +0100

PR libstdc++/86537 remove less> partial specialization

The standard doesn't specify this partial specialization (it was
required after the changes in N2637 but then should have been removed
following LWG 1262). Its presence is observable because it causes
different results when operator< has been overloaded for a shared_ptr
specialization.

PR libstdc++/86537
* include/bits/shared_ptr.h (less>): Remove
non-standard partial specialization.
* include/bits/shared_ptr_base.h (_Sp_less): Remove class 
definition.
(less<__shared_ptr<_Tp, _Lp>): Remove partial specialization.
* testsuite/20_util/shared_ptr/comparison/86537.cc: New test.

diff --git a/libstdc++-v3/include/bits/shared_ptr.h 
b/libstdc++-v3/include/bits/shared_ptr.h
index 2a54145083d..2a82f186328 100644
--- a/libstdc++-v3/include/bits/shared_ptr.h
+++ b/libstdc++-v3/include/bits/shared_ptr.h
@@ -480,10 +480,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
 { return !(nullptr < __a); }
 
-  template
-struct less> : public _Sp_less>
-{ };
-
   // 20.7.2.2.8 shared_ptr specialized algorithms.
   template
 inline void
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h 
b/libstdc++-v3/include/bits/shared_ptr_base.h
index 887edbd7879..f3994da158f 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -1502,22 +1502,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
 { return !(nullptr < __a); }
 
-  template
-struct _Sp_less : public binary_function<_Sp, _Sp, bool>
-{
-  bool
-  operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
-  {
-   typedef typename _Sp::element_type element_type;
-   return std::less()(__lhs.get(), __rhs.get());
-  }
-};
-
-  template
-struct less<__shared_ptr<_Tp, _Lp>>
-: public _Sp_less<__shared_ptr<_Tp, _Lp>>
-{ };
-
   // 20.7.2.2.8 shared_ptr specialized algorithms.
   template
 inline void
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/comparison/86537.cc 
b/libstdc++-v3/testsuite/20_util/shared_ptr/comparison/86537.cc
new file mode 100644
index 000..c8440a38ad0
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/comparison/86537.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2018 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-do run { target c++11 } }
+
+#include 
+#include 
+
+struct Should_not_happen { };
+
+struct X { };
+
+namespace std {
+  template<> struct less {
+bool operator()(X*, X*) const { throw Should_not_happen(); }
+  };
+}
+
+bool custom_op_called = false;
+
+bool
+operator<(const std::shared_ptr&, const std::shared_ptr&)
+{
+  custom_op_called = true;
+  return false;
+}
+
+void
+test01()
+{
+  const std::shared_ptr sp;
+  bool b = sp < sp;
+  VERIFY( !b );
+  VERIFY( custom_op_called );
+
+  std::less> lt;
+  custom_op_called = false;
+  b = lt(sp, sp);
+  VERIFY( !b );
+  VERIFY( custom_op_called ); // PR libstdc++/86537 and LWG DR 1262
+
+#if __cplusplus >= 201402L
+  std::less<> ltv;
+  custom_op_called = false;
+  b = ltv(sp, sp);
+  VERIFY( !b );
+  VERIFY( custom_op_called );
+#endif
+}
+
+int
+main()
+{
+  test01();
+}


[PATCH] scripts/create_testsuite_files: Fix typo in comment.

2018-07-16 Thread Jonathan Wakely

Committed to trunk.


commit 2a123b20c5bbb6b54d157281e2dbe546a28086f5
Author: Jonathan Wakely 
Date:   Mon Jul 16 18:41:31 2018 +0100

* scripts/create_testsuite_files: Fix typo in comment.

diff --git a/libstdc++-v3/scripts/create_testsuite_files 
b/libstdc++-v3/scripts/create_testsuite_files
index 2686c87273d..156304c2ad2 100755
--- a/libstdc++-v3/scripts/create_testsuite_files
+++ b/libstdc++-v3/scripts/create_testsuite_files
@@ -11,7 +11,7 @@
 # existing files are listed in "testsuite_files" in the output
 # directory.  Subsequent runs pull the list from that file, allowing
 # users to trim the list down to problematic tests, or just run
-# paticular directories or sub-directories of tests.
+# particular directories or sub-directories of tests.
 #
 # Selecting individual tests can also be done with RUNTESTFLAGS, but
 # that doesn't really do all that we are trying to accomplish here.


Re: [PATCH] Add baseline symbols for riscv64-linux-gnu

2018-07-16 Thread Jonathan Wakely

On 16/07/18 16:37 -0700, Jim Wilson wrote:

On Mon, Jul 16, 2018 at 3:24 AM, Andreas Schwab  wrote:

* config/abi/post/riscv64-linux-gnu/baseline_symbols.txt: New file.



I'm not familiar with the details of these baseline symbol files.

When I try running "make new-abi-baseline" on my Fedora riscv64-linux
system using top of tree, I get 35 extra lines in the
baseline_symbols.txt.new file.  It looks like 33 of them are because I
have
OBJECT:0:GLIBCXX_3.4.26
and yours only goes up to 3.4.25.  The other two are TLS entries.

TLS:8:_ZSt11__once_call@@GLIBCXX_3.4.11
TLS:8:_ZSt15__once_callable@@GLIBCXX_3.4.11

Not sure why there are no TLS entries in your file, and two in mine.


I don't know about RISC-V but for other GNU/Linux targets those
symbols are not always present, so should not be listed in the
baseline (otherwise when they're absent you get errors about missing
symbols).


The testsuite does pass with a message about 33 added symbols and 2
undesignated symbols which are the TLS symbols.


The added symbols all have the new GLIBCXX_3.4.26 symbol version, so
are allowed as additions on top of the GLIBCXX_3.4.25 baseline defined
by the baseline_symbols.txt file.

The 3.4.26 version is still "open" and having new symbols added to it,
so it makes sense for the baseline to only go up to 3.4.25 for now.




[PATCH] Remove unused explicit instantiation of __bind_simple

2018-07-17 Thread Jonathan Wakely

The explicit instantiation of std::call_once used to require an
instantiation of __bind_simple, but call_once was changed by r241031 to
not use __bind_simple. The instantiation of __bind_simple (and the
definitions it uses) are not needed. They should have been removed
instead of doing the changes in r24 that kept them compiling.

The use of std::call_once by _Async_state_common::_M_join can be
simplified to use a pointer instead of reference wrapper. The call_once
symbol isn't exported so the change isn't visible outside the library.

* src/c++11/compatibility-thread-c++0x.cc [_GLIBCXX_SHARED]
(_Async_state_common::_M_join): Simplify use of std::call_once and
corresponding explicit instantiation.
(_Maybe_wrap_member_pointer, _Bind_simple, _Bind_simple_helper)
(__bind_simple): Remove definitions and explicit instantiation that
are not required by exported symbols.

Tested powerpc64le-linux, committed to trunk.


commit 8c615f0dcb66beed4cf0d4d17f4ed640664932cb
Author: Jonathan Wakely 
Date:   Tue Jul 17 13:37:00 2018 +0100

Remove unused explicit instantiation of __bind_simple

The explicit instantiation of std::call_once used to require an
instantiation of __bind_simple, but call_once was changed by r241031 to
not use __bind_simple. The instantiation of __bind_simple (and the
definitions it uses) are not needed. They should have been removed
instead of doing the changes in r24 that kept them compiling.

The use of std::call_once by _Async_state_common::_M_join can be
simplified to use a pointer instead of reference wrapper. The call_once
symbol isn't exported so the change isn't visible outside the library.

* src/c++11/compatibility-thread-c++0x.cc [_GLIBCXX_SHARED]
(_Async_state_common::_M_join): Simplify use of std::call_once and
corresponding explicit instantiation.
(_Maybe_wrap_member_pointer, _Bind_simple, _Bind_simple_helper)
(__bind_simple): Remove definitions and explicit instantiation that
are not required by exported symbols.

diff --git a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc 
b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
index 7abbb59877d..e60c8f9bfd6 100644
--- a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
+++ b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
@@ -109,7 +109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   protected:
 ~_Async_state_common();
 virtual void _M_run_deferred() { _M_join(); }
-void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
+void _M_join() { std::call_once(_M_once, &thread::join, &_M_thread); }
 thread _M_thread;
 once_flag _M_once;
   };
@@ -117,84 +117,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Replaced with inline definition in gcc-4.8.0
   __future_base::_Async_state_common::~_Async_state_common() { _M_join(); }
 
-  template
-struct _Maybe_wrap_member_pointer;
-
-  template
-struct _Maybe_wrap_member_pointer<_Tp _Class::*>
-{
-  typedef _Mem_fn<_Tp _Class::*> type;
-
-  static constexpr type
-  __do_wrap(_Tp _Class::* __pm)
-  { return type(__pm); }
-};
-
-  template
-struct _Bind_simple;
-
-  template
-struct _Bind_simple<_Callable(_Args...)>
-{
-  typedef typename result_of<_Callable(_Args...)>::type result_type;
-
-  template
-explicit
-_Bind_simple(_Tp&& __f, _Up&&... __args)
-: _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...)
-{ }
-
-  _Bind_simple(const _Bind_simple&) = default;
-  _Bind_simple(_Bind_simple&&) = default;
-
-  result_type
-  operator()()
-  {
-typedef typename _Build_index_tuple::__type _Indices;
-return _M_invoke(_Indices());
-  }
-
-private:
-  template
-typename result_of<_Callable(_Args...)>::type
-_M_invoke(_Index_tuple<_Indices...>)
-{
- // std::bind always forwards bound arguments as lvalues,
- // but this type can call functions which only accept rvalues.
-  return std::forward<_Callable>(std::get<0>(_M_bound))(
-  std::forward<_Args>(std::get<_Indices+1>(_M_bound))...);
-}
-
-  std::tuple<_Callable, _Args...> _M_bound;
-};
-
-  template
-struct _Bind_simple_helper
-{
-  typedef _Maybe_wrap_member_pointer::type>
-__maybe_type;
-  typedef typename __maybe_type::type __func_type;
-  typedef _Bind_simple<__func_type(typename decay<_BoundArgs>::type...)>
-   __type;
-};
-
-  // Simplified version of std::bind for internal use, without support for
-  // unbound arguments, placeholders or nested bind expressions.
-  template
-typename _Bind_simple_hel

[PATCH] PR libstdc++/86450 use -Wabi=2 and simplify -Werror use

2018-07-17 Thread Jonathan Wakely

Use -Wabi=2 to fix warnings about -Wabi having no effect on its own.
This requires suppressing two warnings in src/c++11/debug.cc which do
not affect the library ABI.

Previously libstdc++ defaulted to --enable-werror but the -Werror flag
was not actually added unless --enable-maintainer-mode was used. This is
not documented and not the expected behaviour. This removes any special
treatment for maintainer-mode, makes -Werror depend directly on
--enable-werror, and changes the default to --enable-werror=no.

PR libstdc++/86450
* acinclude.m4 (GLIBCXX_CHECK_COMPILER_FEATURES): Don't define WERROR.
(GLIBCXX_EXPORT_FLAGS): Use -Wabi=2 instead of -Wabi.
* configure: Regenerate.
* configure.ac: Change GLIBCXX_ENABLE_WERROR default to "no".
* doc/Makefile.in: Regenerate.
* fragment.am: Set WERROR_FLAG to -Werror instead of $(WERROR).
* include/Makefile.in: Regenerate.
* libsupc++/Makefile.in: Regenerate.
* po/Makefile.in: Regenerate.
* python/Makefile.in: Regenerate.
* src/Makefile.in: Regenerate.
* src/c++11/Makefile.in: Regenerate.
* src/c++11/debug.cc: Use diagnostic pragmas to suppress warnings
from -Wabi=2 that don't affect exported symbols.
* src/c++98/Makefile.in: Regenerate.
* src/filesystem/Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.

Tested powerpc64le-linux, committed to trunk.


commit 0e99fd82ce20499c4da0d0950e7197f14d45311f
Author: Jonathan Wakely 
Date:   Tue Jul 17 00:59:17 2018 +0100

PR libstdc++/86450 use -Wabi=2 and simplify -Werror use

Use -Wabi=2 to fix warnings about -Wabi having no effect on its own.
This requires suppressing two warnings in src/c++11/debug.cc which do
not affect the library ABI.

Previously libstdc++ defaulted to --enable-werror but the -Werror flag
was not actually added unless --enable-maintainer-mode was used. This is
not documented and not the expected behaviour. This removes any special
treatment for maintainer-mode, makes -Werror depend directly on
--enable-werror, and changes the default to --enable-werror=no.

PR libstdc++/86450
* acinclude.m4 (GLIBCXX_CHECK_COMPILER_FEATURES): Don't define 
WERROR.
(GLIBCXX_EXPORT_FLAGS): Use -Wabi=2 instead of -Wabi.
* configure: Regenerate.
* configure.ac: Change GLIBCXX_ENABLE_WERROR default to "no".
* doc/Makefile.in: Regenerate.
* fragment.am: Set WERROR_FLAG to -Werror instead of $(WERROR).
* include/Makefile.in: Regenerate.
* libsupc++/Makefile.in: Regenerate.
* po/Makefile.in: Regenerate.
* python/Makefile.in: Regenerate.
* src/Makefile.in: Regenerate.
* src/c++11/Makefile.in: Regenerate.
* src/c++11/debug.cc: Use diagnostic pragmas to suppress warnings
from -Wabi=2 that don't affect exported symbols.
* src/c++98/Makefile.in: Regenerate.
* src/filesystem/Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index cf5add167e6..bbf3c8df3e1 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -140,13 +140,6 @@ AC_DEFUN([GLIBCXX_CHECK_COMPILER_FEATURES], [
   ac_test_CXXFLAGS="${CXXFLAGS+set}"
   ac_save_CXXFLAGS="$CXXFLAGS"
 
-  # Check for maintainer-mode bits.
-  if test x"$USE_MAINTAINER_MODE" = xno; then
-WERROR=''
-  else
-WERROR='-Werror'
-  fi
-
   # Check for -ffunction-sections -fdata-sections
   AC_MSG_CHECKING([for g++ that supports -ffunction-sections -fdata-sections])
   CXXFLAGS='-g -Werror -ffunction-sections -fdata-sections'
@@ -163,7 +156,6 @@ AC_DEFUN([GLIBCXX_CHECK_COMPILER_FEATURES], [
   AC_MSG_RESULT($ac_fdsections)
 
   AC_LANG_RESTORE
-  AC_SUBST(WERROR)
   AC_SUBST(SECTION_FLAGS)
 ])
 
@@ -733,7 +725,7 @@ AC_DEFUN([GLIBCXX_EXPORT_FLAGS], [
   # OPTIMIZE_CXXFLAGS = -O3 -fstrict-aliasing -fvtable-gc
   AC_SUBST(OPTIMIZE_CXXFLAGS)
 
-  WARN_FLAGS='-Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi'
+  WARN_FLAGS="-Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=2"
   AC_SUBST(WARN_FLAGS)
 ])
 
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 7e1fd84606a..1e0a33fb3ea 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -175,7 +175,7 @@ GLIBCXX_ENABLE_CXX_FLAGS
 GLIBCXX_ENABLE_FULLY_DYNAMIC_STRING([no])
 GLIBCXX_ENABLE_EXTERN_TEMPLATE([yes])
 GLIBCXX_ENABLE_PYTHON
-GLIBCXX_ENABLE_WERROR([yes])
+GLIBCXX_ENABLE_WERROR([no])
 GLIBCXX_ENABLE_VTABLE_VERIFY([no])
 
 # Checks for operating systems support that doesn't require linking.
diff --git a/libstdc++-v3/fragment.am b/libstdc++-v3/fragment.am
inde

Re: [PATCH] Use __builtin_memmove for trivially copy assignable types

2018-07-19 Thread Jonathan Wakely

On 19/07/18 07:59 -0400, Glen Fernandes wrote:

Updated patch to simplify the helper trait, and to include 
instead of  in the unit test for copy_uninitialized:

Use __builtin_memmove for trivially copy assignable types

2018-07-19  Glen Joseph Fernandes  

   * include/bits/stl_algobase.h
   (__is_simple_copy_move): Defined helper.
   (__copy_move_a): Used helper.
   (__copy_move_backward_a): Likewise.
   * testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
   New test.
   * testsuite/25_algorithms/copy/58982.cc: Updated tests.
   * testsuite/25_algorithms/copy_n/58982.cc: Likewise.

Attached: patch.txt

Glen



commit 1af8d465545fda2451928fe100901db37c3e632c
Author: Glen Fernandes 
Date:   Thu Jul 19 07:40:17 2018 -0400

   Use __builtin_memmove for trivially copy assignable types

   2018-07-19  Glen Joseph Fernandes  

   * include/bits/stl_algobase.h
   (__is_simple_copy_move): Defined helper.
   (__copy_move_a): Used helper.
   (__copy_move_backward_a): Likewise.
   * testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
   New test.
   * testsuite/25_algorithms/copy/58982.cc: Updated tests.
   * testsuite/25_algorithms/copy_n/58982.cc: Likewise.

diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index 16a3f83b6..4488207f0 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -72,10 +72,16 @@

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

+  template
+struct __is_simple_copy_move
+{
+  enum { __value = __is_trivially_assignable(_Tp, const _Tp&) };
+};
+
#if __cplusplus < 201103L
  // See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a
  // nutshell, we are partially implementing the resolution of DR 187,
  // when it's safe, i.e., the value_types are equal.
  template
@@ -389,11 +395,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__copy_move_a(_II __first, _II __last, _OI __result)
{
  typedef typename iterator_traits<_II>::value_type _ValueTypeI;
  typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
  typedef typename iterator_traits<_II>::iterator_category _Category;
-  const bool __simple = (__is_trivial(_ValueTypeI)
+  const bool __simple = (__is_simple_copy_move<_ValueTypeI>::__value


Sorry for the delay in reviewing this properly, as I've only just
realised that this introduces undefined behaviour, doesn't it?

It's undefined to use memmove for a type that is not trivially
copyable. All trivial types are trivially copyable, so __is_trivial
was too conservative, but safe (IIRC we used it because there was no
__is_trivially_copyable trait at the time, so __is_trivial was the
best we had).

There are types which are trivially assignable but not trivially
copyable, and it's undefined to use memmove for such types. With your
patch applied I get a warning for this code, where there was none
before:

#include 
#include 

struct T
{
 T() { }
 T(const T&) { }
};

static_assert(std::is_trivially_copy_assignable::value
   && !std::is_trivially_copyable::value,
   "T is only trivially copy assignable, not trivially copyable");

void
test01(T* result)
{
 T t[1];
 std::copy(t, t+1, result);
}


In file included from /home/jwakely/gcc/9/include/c++/9.0.0/memory:62,
from copy.cc:1:
/home/jwakely/gcc/9/include/c++/9.0.0/bits/stl_algobase.h: In instantiation of 
'static _Tp* std::__copy_move<_IsMove, true, 
std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp 
= T; bool _IsMove = false]':
/home/jwakely/gcc/9/include/c++/9.0.0/bits/stl_algobase.h:406:30:   required 
from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = 
T*; _OI = T*]'
/home/jwakely/gcc/9/include/c++/9.0.0/bits/stl_algobase.h:443:30:   required 
from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = 
T*; _OI = T*]'
/home/jwakely/gcc/9/include/c++/9.0.0/bits/stl_algobase.h:476:7:   required 
from '_OI std::copy(_II, _II, _OI) [with _II = T*; _OI = T*]'
copy.cc:18:27:   required from here
/home/jwakely/gcc/9/include/c++/9.0.0/bits/stl_algobase.h:388:23: warning: 
'void* __builtin_memmove(void*, const void*, long unsigned int)' writing to an 
object of non-trivially copyable type 'struct T'; use copy-assignment or 
copy-initialization instead [-Wclass-memaccess]
 __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
 ~^~~
copy.cc:4:8: note: 'struct T' declared here
struct T
   ^


I think the best we can do here is simply replace __is_trivial with
__is_trivially_copyable, which will enable memmove for trivially
copyable types for which !is_trivially_default_constructible_v.




Re: [PATCH] Use __builtin_memmove for trivially copy assignable types

2018-07-19 Thread Jonathan Wakely

On 19/07/18 10:01 -0400, Glen Fernandes wrote:

On Thu, Jul 19, 2018 at 9:25 AM Jonathan Wakely  wrote:

Sorry for the delay in reviewing this properly, as I've only just
realised that this introduces undefined behaviour, doesn't it?

It's undefined to use memmove for a type that is not trivially
copyable. All trivial types are trivially copyable, so __is_trivial
was too conservative, but safe (IIRC we used it because there was no
__is_trivially_copyable trait at the time, so __is_trivial was the
best we had).

There are types which are trivially assignable but not trivially
copyable, and it's undefined to use memmove for such types.


I was still unclear about that, but I forwarded you an e-mail from
Marshall with his answer when I asked whether libc++'s use of
TriviallyCopyAssignable here was incorrect. Let me know if it applies
here, and if not (and that interpretation of the standard is
incorrect), I'll update the patch to do as you suggest and run the
tests again.


While I sympathise with Marshall's position (that std::copy only cares
about assignment not copying) that doesn't make it OK to use memmove
here.

Using memmove for a non-trivially copyable type is undefined. Period.

The fact GCC warns that it's undefined also means GCC might start
optimising based on the assumption that undefined behaviour isn't
reached at runtime. So it could (for example) assume that the input
range must be empty and remove the entire call to std::copy.

For a non-trivially copyable, trivially assignable type I think we
just have to rely on the compiler to transform the assignments into
optimal code (which might end up being a memmove, ironically).

Please do update the patch to use __is_trivially_copyable. I don't
think we need the __is_simple_copy_move helper in that case, just
change two uses of __is_trivial to __is_trivially_copyable.



Re: [PATCH] Use __builtin_memmove for trivially copy assignable types

2018-07-19 Thread Jonathan Wakely

On 19/07/18 10:32 -0400, Glen Fernandes wrote:

On Thu, Jul 19, 2018 at 10:01 AM Glen Fernandes wrote:


I was still unclear about that, but I forwarded you an e-mail from
Marshall with his answer when I asked whether libc++'s use of
TriviallyCopyAssignable here was incorrect. Let me know if it applies
here, and if not (and that interpretation of the standard is
incorrect), I'll update the patch to do as you suggest and run the
tests again.

Glen


Attached: patch.txt

Use __builtin_memmove for trivially copyable types

2018-07-19  Glen Joseph Fernandes  

   * include/bits/stl_algobase.h
   (__copy_move_a): Used __is_trivially_copyable.
   (__copy_move_backward_a): Likewise.

Tested x86_64-pc-linux-gnu.


Ah, that was quick :-)

Can we keep the new test you added in the previous patch? It seems
useful to add anyway.




[PATCH] Simplify the base characteristics for some type traits

2018-07-19 Thread Jonathan Wakely

This removes some seemingly redundant conditions from a few traits. If
__is_trivially_assignable correctly checks the assignable condition as
well as triviality, then we don't need is_assignable explicitly.  Does
anybody see a problem with that

I added some extra tests for cases that had been problematic with
__is_trivially_constructible.

We can definitely do that change for is_trivially_constructible,
because Ville fixed the intrinsic recently (PR 86398)

It also simplifies some others to replace
integral_constant::value> with the equivalent
foo::type, or to replace integral_constant::value>
with the equivalent __not_>::type.

I also started a wholesale replacement of integral_constant
with __bool_constant but backed that out again. It's a fair bit of
churn for not much benefit (the two cases I did change allow better
line wrapping which makes me a happy boy).

* include/std/type_traits (__is_member_object_pointer_helper): Use
__not_>::type instead of integral_constant.
(__is_member_function_pointer_helper): Likewise for
is_function<_Tp>::type.
(is_compund): Likewise for __not_>::type.
(__do_is_nt_destructible_impl): Use __bool_constant and reindent.
(is_trivially_constructible): Remove redundant use of
is_constructible.
(__is_trivially_copy_assignable_impl): Remove redundant use of
is_copy_assignable.
(__is_trivially_move_assignable_impl): Remove redundant use of
is_move_assignable.
(is_trivially_destructible): Use __bool_constant.
* testsuite/20_util/is_trivially_assignable/value.cc: Add some more
tests for scalar types.

Tested powerpc64le-linux.


commit 82960cb6e64ca78b53fb799318087cb23b942079
Author: Jonathan Wakely 
Date:   Thu Jul 19 17:03:33 2018 +0100

Simplify the base characteristics for some type traits

* include/std/type_traits (__is_member_object_pointer_helper): Use
__not_>::type instead of integral_constant.
(__is_member_function_pointer_helper): Likewise for
is_function<_Tp>::type.
(is_compund): Likewise for __not_>::type.
(__do_is_nt_destructible_impl): Use __bool_constant and reindent.
(is_trivially_constructible): Remove redundant use of
is_constructible.
(__is_trivially_copy_assignable_impl): Remove redundant use of
is_copy_assignable.
(__is_trivially_move_assignable_impl): Remove redundant use of
is_move_assignable.
(is_trivially_destructible): Use __bool_constant.
* testsuite/20_util/is_trivially_assignable/value.cc: Add some more
tests for scalar types.

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 4df82bf6d8c..aaa554c6200 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -396,7 +396,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 struct __is_member_object_pointer_helper<_Tp _Cp::*>
-: public integral_constant::value> { };
+: public __not_>::type { };
 
   /// is_member_object_pointer
   template
@@ -411,7 +411,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 struct __is_member_function_pointer_helper<_Tp _Cp::*>
-: public integral_constant::value> { };
+: public is_function<_Tp>::type { };
 
   /// is_member_function_pointer
   template
@@ -603,7 +603,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_compound
   template
 struct is_compound
-: public integral_constant::value> { };
+: public __not_>::type { };
 
   template
 struct __is_member_pointer_helper
@@ -826,8 +826,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   struct __do_is_nt_destructible_impl
   {
 template
-  static integral_constant().~_Tp())>
-__test(int);
+  static __bool_constant().~_Tp())>
+  __test(int);
 
 template
   static false_type __test(...);
@@ -1136,8 +1136,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// is_trivially_constructible
   template
 struct is_trivially_constructible
-: public __and_, __bool_constant<
- __is_trivially_constructible(_Tp, _Args...)>>::type
+: public __bool_constant<__is_trivially_constructible(_Tp, _Args...)>
 { };
 
   /// is_trivially_default_constructible
@@ -1235,9 +1234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 struct __is_trivially_copy_assignable_impl<_Tp, true>
-: public __and_,
-   integral_constant>
+: public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)>
 { };
 
   template
@@ -1256,9 +1253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
 struct __is_trivially_move_assignable_impl<_Tp, true>
-: public __and_,
-   integral_constant>
+: public __boo

Re: [PATCH] Use __builtin_memmove for trivially copy assignable types

2018-07-19 Thread Jonathan Wakely

On 19/07/18 11:04 -0400, Glen Fernandes wrote:

On Thu, Jul 19, 2018 at 10:40 AM Jonathan Wakely  wrote:

On 19/07/18 10:32 -0400, Glen Fernandes wrote:
>Attached: patch.txt
>Use __builtin_memmove for trivially copyable types
>2018-07-19  Glen Joseph Fernandes  
>* include/bits/stl_algobase.h
>(__copy_move_a): Used __is_trivially_copyable.
>(__copy_move_backward_a): Likewise.
>Tested x86_64-pc-linux-gnu.

Ah, that was quick :-)

Can we keep the new test you added in the previous patch? It seems
useful to add anyway.


Affirmative. Attached: patch.txt

Use __builtin_memmove for trivially copyable types

2018-07-19  Glen Joseph Fernandes  

   * include/bits/stl_algobase.h
   (__copy_move_a): Used __is_trivially_copyable.
   (__copy_move_backward_a): Likewise.
   * testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
   New test.


Tested on x86_64-linux and committed to trunk - thanks!




Re: [PATCH] Simplify the base characteristics for some type traits

2018-07-19 Thread Jonathan Wakely

On 19/07/18 21:40 +0300, Ville Voutilainen wrote:

On 19 July 2018 at 20:18, Jonathan Wakely  wrote:

This removes some seemingly redundant conditions from a few traits. If
__is_trivially_assignable correctly checks the assignable condition as
well as triviality, then we don't need is_assignable explicitly.  Does
anybody see a problem with that


It should work; if it doesn't, that's a bug in the compiler. Both
is_constructible
and is_assignable and trivial variants thereof go to the same
"is_xible" code path,
so it should be fair for the library to expect that it all works. In
case it doesn't,
that's something that I will fix in the front-end.


Yeah I agree. I guess my concern is that we introduce a regression and
don't notice for a while that the intrinsic is buggy.

I've committed it now, so we'll see :-)




Re: Optimization for std::to_string()

2018-07-20 Thread Jonathan Wakely

On 20/07/18 12:44 +0300, niXman wrote:


Hi,



Patch in attachments.


Thanks. How did you verify it's an optimization?

The to_string functions always pass at least __n=16 to __to_xstring,
which is larger than the SSO buffer in std::__cxx11::string, and so
forces a memory allocation.

The current code uses alloca and if the result fits in the SSO buffer
there is no allocation. e.g. to_string(99) doesn't allocate from
the heap at all for the new std::__cxx11::string.

For the old COW string this doesn't make much difference, because we
always allocate. Your patch will mean we return a string with excess
capacity, rather than one of exactly capacity()==length(). That isn't
a problem.



Tested on x86_64-linux-gnu.


--
Regards, niXman
___
C++ for Bitcoins: github.com/niXman



Index: libstdc++-v3/include/ext/string_conversions.h
===
--- libstdc++-v3/include/ext/string_conversions.h   (revision 262879)
+++ libstdc++-v3/include/ext/string_conversions.h   (working copy)
@@ -100,19 +100,18 @@
 __builtin_va_list), std::size_t __n,
 const _CharT* __fmt, ...)
{
-  // XXX Eventually the result should be constructed in-place in
-  // the __cxx11 string, likely with the help of internal hooks.
-  _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
- * __n));
+  _String __str(__n, 0);

  __builtin_va_list __args;
  __builtin_va_start(__args, __fmt);

-  const int __len = __convf(__s, __n, __fmt, __args);
+  const std::size_t __len = __convf(&__str[0], __n, __fmt, __args);

  __builtin_va_end(__args);

-  return _String(__s, __s + __len);
+  __str.resize(__len);
+
+  return __str;
}

_GLIBCXX_END_NAMESPACE_VERSION




Re: [PATCH 1/2] condition_variable: Report early wakeup of wait_until as no_timeout

2018-07-20 Thread Jonathan Wakely

On 10/07/18 11:09 +0100, Mike Crowe wrote:

As currently implemented, condition_variable always ultimately waits
against std::chrono::system_clock. This clock can be changed in arbitrary
ways by the user which may result in us waking up too early or too late
when measured against the caller-supplied clock.

We can't (yet) do much about waking up too late[1], but
if we wake up too early we must return cv_status::no_timeout to indicate a
spurious wakeup rather than incorrectly returning cv_status::timeout.


The patch looks good, thanks.

Can we come up with a test for this, using a user-defined clock that
jumps back?



[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41861
---
libstdc++-v3/ChangeLog  | 5 +
libstdc++-v3/include/std/condition_variable | 8 +++-
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index cceef0271ae..ea7875ace9f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,8 @@
+2018-07-09  Mike Crowe 
+   * include/std/condition_variable (wait_until): Only report timeout
+   if we really have timed out when measured against the
+   caller-supplied clock.
+
2018-07-06  François Dumont  

   * include/debug/functions.h (__gnu_debug::__check_string): Move...
diff --git a/libstdc++-v3/include/std/condition_variable 
b/libstdc++-v3/include/std/condition_variable
index 84863a162d6..a2d146a9b09 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -116,7 +116,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const auto __delta = __atime - __c_entry;
   const auto __s_atime = __s_entry + __delta;

-   return __wait_until_impl(__lock, __s_atime);
+   // We might get a timeout when measured against __clock_t but
+   // we need to check against the caller-supplied clock to tell
+   // whether we should return a timeout.
+   if (__wait_until_impl(__lock, __s_atime) == cv_status::timeout)
+ return _Clock::now() < __atime ? cv_status::no_timeout : 
cv_status::timeout;
+   else
+ return cv_status::no_timeout;
  }

template
--
2.11.0

BrightSign considers your privacy to be very important. The emails you send to 
us will be protected and secured. Furthermore, we will only use your email and 
contact information for the reasons you sent them to us and for tracking how 
effectively we respond to your requests.


Re: [PATCH] Explicitly mark _S_ti() as default visibility to work around clang -fvisibility-inlines-hidden bug

2018-07-20 Thread Jonathan Wakely

On 19/07/18 16:58 -0700, Fāng-ruì Sòng via libstdc++ wrote:

clang (including trunk and many older versions) incorrectly marks static local 
variables (__tag) hidden when -fvisibility-inlines-hidden is used.

% cat b.cc
#include 
std::shared_ptr foo(int x) {
return std::make_shared(x);
}
% g++-8 -fvisibility-inlines-hidden -fno-rtti -c b.cc
% readelf -s b.o | grep _S_ti
 163:  1 OBJECT  UNIQUE DEFAULT   67 
_ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag
 164:  8 FUNCWEAK   HIDDEN68 
_ZNSt19_Sp_make_shared_tag5_S_tiEv
% ~/Dev/llvm/static-release/bin/clang++ -fvisibility-inlines-hidden -fno-rtti 
-c b.cc
% readelf -s b.o | grep _S_ti
 129: 16 FUNCWEAK   HIDDEN34 
_ZNSt19_Sp_make_shared_tag5_S_tiEv
 155:  1 OBJECT  WEAK   HIDDEN   202 
_ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag

This can lead to multiple instances of __tag when shares objects are used.
The function
virtual void* std::_Sp_counted_ptr_inplace::_M_get_deleter(const 
std::type_info& __ti) noexcept
may return nullptr and causes std::make_shared() to return nullptr 
(-fvisibility-inlines-hidden -fno-rtti).

After applying this patch (tagging _S_ti() with default visibility to override 
-fvisibility-inlines-hidden)

% readelf -s b.o | grep _S_ti
 129: 16 FUNCWEAK   DEFAULT   34 
_ZNSt19_Sp_make_shared_tag5_S_tiEv
 155:  1 OBJECT  WEAK   DEFAULT  202 
_ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag


This issue caused 10+ check-all tests of a -DUSE_SHARED_LLVM=On build of llvm 
(compiled with clang trunk) to SIGSEGV (because std::make_shared returned 
nullptr) and this patch fixes it.


  * include/bits/shared_ptr_base.h (_S_ti): Use
  _GLIBCXX_VISIBILITY(default)



Thanks, I've tested this and committed it to trunk.

I think we want this on gcc-8-branch too, but it's too late for the
8.2 release now.



--
宋方睿



From 6da8cec298766ce043d9c6dcda7b87142228dafb Mon Sep 17 00:00:00 2001
From: Fangrui Song 
Date: Thu, 19 Jul 2018 16:40:26 -0700
Subject: [PATCH 1/1] Explicitly mark _S_ti() as default visibility to work
around clang -fvisibility-inlines-hidden bug

clang (including trunk and many older versions) incorrectly marks static
local variables (__tag) hidden when -fvisibility-inlines-hidden is used.
This can lead to multiple instances of __tag when shares objects are used.

   * include/bits/shared_ptr_base.h (_S_ti): Use
   _GLIBCXX_VISIBILITY(default)
---
libstdc++-v3/include/bits/shared_ptr_base.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h 
b/libstdc++-v3/include/bits/shared_ptr_base.h
index f3994da158f..870aeb9bfda 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -508,7 +508,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  friend class _Sp_counted_ptr_inplace;

static const type_info&
-_S_ti() noexcept
+_S_ti() noexcept _GLIBCXX_VISIBILITY(default)
{
  alignas(type_info) static constexpr _Sp_make_shared_tag __tag;
  return reinterpret_cast(__tag);
--
2.18.0





[PATCH] PR libstdc++/86603 Move __cpp_lib_list_remove_return_type macro

2018-07-20 Thread Jonathan Wakely

This should only be defined for C++2a not C++17.

PR libstdc++/86603
* include/std/version: Move __cpp_lib_list_remove_return_type macro.

Tested powerpc64le-linux, committed to trunk.


commit c457458395791eff165618b7bd04f6a71d99188d
Author: Jonathan Wakely 
Date:   Fri Jul 20 11:15:50 2018 +0100

PR libstdc++/86603 Move __cpp_lib_list_remove_return_type macro

This should only be defined for C++2a not C++17.

PR libstdc++/86603
* include/std/version: Move __cpp_lib_list_remove_return_type macro.

diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index a70c73fd12b..0c26d9b6a7b 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -105,7 +105,6 @@
 #define __cpp_lib_is_swappable 201603
 #define __cpp_lib_launder 201606
 #define __cpp_lib_lcm 201606
-#define __cpp_lib_list_remove_return_type 201806L
 #define __cpp_lib_logical_traits 201510
 #define __cpp_lib_make_from_tuple 201606
 #define __cpp_lib_map_insertion 201411
@@ -127,6 +126,7 @@
 
 #if __cplusplus > 201703L
 // c++2a
+#define __cpp_lib_list_remove_return_type 201806L
 #endif // C++2a
 #endif // C++17
 #endif // C++14


Re: [PATCH 1/2] condition_variable: Report early wakeup of wait_until as no_timeout

2018-07-20 Thread Jonathan Wakely

On 20/07/18 12:30 +0100, Mike Crowe wrote:

On Friday 20 July 2018 at 11:53:38 +0100, Jonathan Wakely wrote:

On 10/07/18 11:09 +0100, Mike Crowe wrote:
> As currently implemented, condition_variable always ultimately waits
> against std::chrono::system_clock. This clock can be changed in arbitrary
> ways by the user which may result in us waking up too early or too late
> when measured against the caller-supplied clock.
>
> We can't (yet) do much about waking up too late[1], but
> if we wake up too early we must return cv_status::no_timeout to indicate a
> spurious wakeup rather than incorrectly returning cv_status::timeout.

The patch looks good, thanks.

Can we come up with a test for this, using a user-defined clock that
jumps back?


That's a good idea. I'll do that.


Thanks.

There are "broken" clocks in testsuite/30_threads/this_thread/60421.cc
and testsuite/30_threads/timed_mutex/try_lock_until/57641.cc but I'm
not sure if either of them is reusable. A custom one for this test
should be reasonably easy.



[PATCH] PR libstdc++/86595 add missing noexcept

2018-07-20 Thread Jonathan Wakely

PR libstdc++/86595
* include/bits/fs_dir.h (directory_entry::refresh(error_code&)): Add
noexcept.

Tested powerpc64le-linux, committed to trunk.


commit c857adf35f9849ddda1148c65813aba86acb5c6a
Author: Jonathan Wakely 
Date:   Fri Jul 20 12:35:05 2018 +0100

PR libstdc++/86595 add missing noexcept

PR libstdc++/86595
* include/bits/fs_dir.h (directory_entry::refresh(error_code&)): Add
noexcept.

diff --git a/libstdc++-v3/include/bits/fs_dir.h 
b/libstdc++-v3/include/bits/fs_dir.h
index 6b332e171cf..cf7a3c29376 100644
--- a/libstdc++-v3/include/bits/fs_dir.h
+++ b/libstdc++-v3/include/bits/fs_dir.h
@@ -138,8 +138,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   refresh(__ec);
 }
 
-void refresh() { _M_type = symlink_status().type(); }
-void refresh(error_code& __ec) { _M_type = symlink_status(__ec).type(); }
+void
+refresh()
+{ _M_type = symlink_status().type(); }
+
+void
+refresh(error_code& __ec) noexcept
+{ _M_type = symlink_status(__ec).type(); }
 
 // observers
 const filesystem::path& path() const noexcept { return _M_path; }


Re: Optimization for std::to_string()

2018-07-20 Thread Jonathan Wakely

On 20/07/18 13:51 +0300, niXman wrote:

Jonathan Wakely 2018-07-20 13:05:

On 20/07/18 12:44 +0300, niXman wrote:



Thanks. How did you verify it's an optimization?

Optimization is that there is no superfluous copying into string.


The to_string functions always pass at least __n=16 to __to_xstring,
which is larger than the SSO buffer in std::__cxx11::string, and so
forces a memory allocation.

I didn't think about this...


Avoiding an unconditional dynamic allocation is the main advantage of
using alloca.




[PATCH] PR libstdc++/70940 optimize pmr::resource_adaptor for allocators using malloc

2018-07-23 Thread Jonathan Wakely

pmr::resource_adaptor can avoid allocating an oversized buffer and doing
manual alignment within that buffer when the wrapped allocator is known
to always meet the requested alignment. Specifically, if the allocator
is known to use malloc or new directly, then we can call the allocator
directly for any fundamental alignment.

PR libstdc++/70940
* include/experimental/memory_resource
(__resource_adaptor_common::_AlignMgr::_M_unadjust): Add assertion.
(__resource_adaptor_common::__guaranteed_alignment): New helper to
give maximum alignment an allocator guarantees. Specialize for known
allocators using new and malloc.
(__resource_adaptor_imp::do_allocate): Use __guaranteed_alignment.
(__resource_adaptor_imp::do_deallocate): Likewise.
* testsuite/experimental/memory_resource/new_delete_resource.cc:
Check that new and delete are called with expected sizes.

This wouldn't be a very important optimization, because wrapping
std::allocator in a pmr::resource_adaptor is probably uncommon, but
pmr::resource_adaptor is used to implement
pmr::new_delete_resource() in . (The
C++17 version of pmr::new_delete_resource() just uses aligned new, but
that isn't available in C++14).

Tested powerpc64le-linux, committed to trunk.

Rainer, this is another place where alignof(max_align_t) gets encoded
into the ABI, so is affected by PR 77691 as well.


commit cb814378aad13172dbb4e0630587638e946657f4
Author: Jonathan Wakely 
Date:   Mon Jul 23 19:02:12 2018 +0100

PR libstdc++/70940 optimize pmr::resource_adaptor for allocators using 
malloc

pmr::resource_adaptor can avoid allocating an oversized buffer and doing
manual alignment within that buffer when the wrapped allocator is known
to always meet the requested alignment. Specifically, if the allocator
is known to use malloc or new directly, then we can call the allocator
directly for any fundamental alignment.

PR libstdc++/70940
* include/experimental/memory_resource
(__resource_adaptor_common::_AlignMgr::_M_unadjust): Add assertion.
(__resource_adaptor_common::__guaranteed_alignment): New helper to
give maximum alignment an allocator guarantees. Specialize for known
allocators using new and malloc.
(__resource_adaptor_imp::do_allocate): Use __guaranteed_alignment.
(__resource_adaptor_imp::do_deallocate): Likewise.
* testsuite/experimental/memory_resource/new_delete_resource.cc:
Check that new and delete are called with expected sizes.

diff --git a/libstdc++-v3/include/experimental/memory_resource 
b/libstdc++-v3/include/experimental/memory_resource
index 1965fdcfe73..61273fc2c85 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -36,6 +36,13 @@
 #include 
 #include 
 
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template class malloc_allocator;
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __gnu_cxx
+
 namespace std {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
@@ -307,6 +314,10 @@ namespace pmr {
  __orig_ptr = __ptr - _S_read(__end);
else // (__token_size == sizeof(char*))
  __orig_ptr = _S_read(__end);
+   // The adjustment is always less than the requested alignment,
+   // so if that isn't true now then either the wrong size was passed
+   // to deallocate or the token was overwritten by a buffer overflow:
+   __glibcxx_assert(static_cast(__ptr - __orig_ptr) < _M_align);
return __orig_ptr;
   }
 
@@ -345,6 +356,23 @@ namespace pmr {
  return __val;
}
 };
+
+template
+  struct __guaranteed_alignment : std::integral_constant { };
+
+template
+  struct __guaranteed_alignment<__gnu_cxx::new_allocator<_Tp>>
+  : std::alignment_of::type { };
+
+template
+  struct __guaranteed_alignment<__gnu_cxx::malloc_allocator<_Tp>>
+  : std::alignment_of::type { };
+
+#if _GLIBCXX_USE_ALLOCATOR_NEW
+template
+  struct __guaranteed_alignment>
+  : std::alignment_of::type { };
+#endif
   };
 
   // 8.7.1 __resource_adaptor_imp
@@ -392,7 +420,7 @@ namespace pmr {
   virtual void*
   do_allocate(size_t __bytes, size_t __alignment) override
   {
-   if (__alignment == 1)
+   if (__alignment <= __guaranteed_alignment<_Alloc>::value)
  return _M_alloc.allocate(__bytes);
 
const _AlignMgr __mgr(__bytes, __alignment);
@@ -407,7 +435,7 @@ namespace pmr {
   override
   {
auto __ptr = static_cast(__p);
-   if (__alignment == 1)
+   if (__alignment <= __guaranteed_alignment<_Alloc>::value)
  {
_M_alloc.deallocate(__ptr, __bytes);
return;
diff --git 
a/libstdc++-v3/testsuite/experimental/m

[PATCH] Reorder conditions in uses-allocator construction helper

2018-07-24 Thread Jonathan Wakely

The erased_type condition is only true for code using the Library
Fundamentals TS, so assume it's less common and only check it after
checking for convertibility.

This does mean for types using erased_type the more expensive
convertibility check is done first, but such types are rare.

* include/bits/uses_allocator.h (__is_erased_or_convertible): Reorder
conditions. Add comments.
* testsuite/20_util/uses_allocator/69293_neg.cc: Adjust dg-error line.
* testsuite/20_util/uses_allocator/cons_neg.cc: Likewise.
* testsuite/20_util/scoped_allocator/69293_neg.cc: Likewise.

Tested powerpc64le-linux, committed to trunk.


commit baf0d8cca17bc1223580b416c501f4b74bbca9b3
Author: redi 
Date:   Tue Jul 24 13:03:25 2018 +

Reorder conditions in uses-allocator construction helper

The erased_type condition is only true for code using the Library
Fundamentals TS, so assume it's less common and only check it after
checking for convertibility.

This does mean for types using erased_type the more expensive
convertibility check is done first, but such types are rare.

* include/bits/uses_allocator.h (__is_erased_or_convertible): 
Reorder
conditions. Add comments.
* testsuite/20_util/uses_allocator/69293_neg.cc: Adjust dg-error 
line.
* testsuite/20_util/uses_allocator/cons_neg.cc: Likewise.
* testsuite/20_util/scoped_allocator/69293_neg.cc: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@262945 
138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/libstdc++-v3/include/bits/uses_allocator.h 
b/libstdc++-v3/include/bits/uses_allocator.h
index 820a2a59894..3ef2830bebc 100644
--- a/libstdc++-v3/include/bits/uses_allocator.h
+++ b/libstdc++-v3/include/bits/uses_allocator.h
@@ -36,11 +36,15 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+  // This is used for std::experimental::erased_type from Library Fundamentals.
   struct __erased_type { };
 
+  // This also supports the "type-erased allocator" protocol from the
+  // Library Fundamentals TS, where allocator_type is erased_type.
+  // The second condition will always be false for types not using the TS.
   template
 using __is_erased_or_convertible
-  = __or_, is_convertible<_Alloc, _Tp>>;
+  = __or_, is_same<_Tp, __erased_type>>;
 
   /// [allocator.tag]
   struct allocator_arg_t { explicit allocator_arg_t() = default; };
diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc 
b/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc
index 621ff47c7a3..168079fd5f9 100644
--- a/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc
@@ -46,5 +46,5 @@ test01()
   scoped_alloc sa;
   auto p = sa.allocate(1);
   sa.construct(p);  // this is required to be ill-formed
-  // { dg-error "static assertion failed" "" { target *-*-* } 90 }
+  // { dg-error "static assertion failed" "" { target *-*-* } 94 }
 }
diff --git a/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc 
b/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc
index 348ed41a7bc..eaf432491c6 100644
--- a/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc
@@ -44,5 +44,5 @@ test01()
 {
   alloc_type a;
   std::tuple t(std::allocator_arg, a); // this is required to be ill-formed
-  // { dg-error "static assertion failed" "" { target *-*-* } 90 }
+  // { dg-error "static assertion failed" "" { target *-*-* } 94 }
 }
diff --git a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc 
b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc
index 8894e389cec..bb8c38d1e49 100644
--- a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc
@@ -43,4 +43,4 @@ void test01()
 
   tuple t(allocator_arg, a, 1);
 }
-// { dg-error "static assertion failed" "" { target *-*-* } 90 }
+// { dg-error "static assertion failed" "" { target *-*-* } 94 }


[PATCH] PR libstdc++/70966 fix lifetime bug for default resource

2018-07-24 Thread Jonathan Wakely

Similar to what I did for the new_delete_resource and
null_memory_resource objects, this makes the atomic
immortal. This ensure it can still be used after static destructors
start running.

PR libstdc++/70966
* include/experimental/memory_resource (__get_default_resource): Use
placement new to create an object with dynamic storage duration.

Tested powerpc64le-linux, committed to trunk.


commit 5e51f3630b506d993737c95c65b251acaa433076
Author: Jonathan Wakely 
Date:   Mon Jul 23 23:30:38 2018 +0100

PR libstdc++/70966 fix lifetime bug for default resource

PR libstdc++/70966
* include/experimental/memory_resource (__get_default_resource): Use
placement new to create an object with dynamic storage duration.

diff --git a/libstdc++-v3/include/experimental/memory_resource 
b/libstdc++-v3/include/experimental/memory_resource
index 61273fc2c85..83379d1367a 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -459,12 +459,6 @@ namespace pmr {
 };
 
   // Global memory resources
-  inline std::atomic&
-  __get_default_resource()
-  {
-static atomic _S_default_resource(new_delete_resource());
-return _S_default_resource;
-  }
 
   inline memory_resource*
   new_delete_resource() noexcept
@@ -499,6 +493,16 @@ namespace pmr {
   }
 
   // The default memory resource
+
+  inline std::atomic&
+  __get_default_resource()
+  {
+using type = atomic;
+alignas(type) static unsigned char __buf[sizeof(type)];
+static type* __r = new(__buf) type(new_delete_resource());
+return *__r;
+  }
+
   inline memory_resource*
   get_default_resource() noexcept
   { return __get_default_resource().load(); }


[PATCH] Make __resource_adaptor_imp usable with C++17 memory_resource

2018-07-24 Thread Jonathan Wakely

By making the memory_resource base class a template parameter the
__resource_adaptor_imp can be used to adapt an allocator into a
std::pmr::memory_resource instead of experimental::pmr::memory_resource.

No uses for this in the library but somebody might want to do it, and
it costs us nothing to support.

* include/experimental/memory_resource: Adjust comments and
whitespace.
(__resource_adaptor_imp): Add second template parameter for type of
memory resource base class.
(memory_resource): Define default constructor, destructor, copy
constructor and copy assignment operator as defaulted.

Tested powerpc64le-linux, committed to trunk.

commit ce04fa1c00b40a938cc25a264836a2e30149056e
Author: Jonathan Wakely 
Date:   Tue Jul 24 12:24:53 2018 +0100

Make __resource_adaptor_imp usable with C++17 memory_resource

By making the memory_resource base class a template parameter the
__resource_adaptor_imp can be used to adapt an allocator into a
std::pmr::memory_resource instead of experimental::pmr::memory_resource.

* include/experimental/memory_resource: Adjust comments and
whitespace.
(__resource_adaptor_imp): Add second template parameter for type of
memory resource base class.
(memory_resource): Define default constructor, destructor, copy
constructor and copy assignment operator as defaulted.

diff --git a/libstdc++-v3/include/experimental/memory_resource 
b/libstdc++-v3/include/experimental/memory_resource
index 83379d1367a..7ce64457a11 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -29,12 +29,12 @@
 #ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
 #define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1
 
-#include 
+#include   // align, uses_allocator, __uses_alloc
+#include // pair, 
experimental::erased_type
+#include   // atomic
 #include 
-#include 
-#include 
 #include 
-#include 
+#include 
 
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
@@ -51,39 +51,41 @@ inline namespace fundamentals_v2 {
 namespace pmr {
 #define __cpp_lib_experimental_memory_resources 201402L
 
-  class memory_resource;
-
-  template 
-class polymorphic_allocator;
-
-  template 
-class __resource_adaptor_imp;
-
-  template 
-using resource_adaptor = __resource_adaptor_imp<
-  typename allocator_traits<_Alloc>::template rebind_alloc>;
-
-  template 
-struct __uses_allocator_construction_helper;
-
-  // Global memory resources
-  memory_resource* new_delete_resource() noexcept;
-  memory_resource* null_memory_resource() noexcept;
-
-  // The default memory resource
-  memory_resource* get_default_resource() noexcept;
-  memory_resource* set_default_resource(memory_resource* __r) noexcept;
-
   // Standard memory resources
 
   // 8.5 Class memory_resource
+  class memory_resource;
+
+  // 8.6 Class template polymorphic_allocator
+  template
+class polymorphic_allocator;
+
+  template
+class __resource_adaptor_imp;
+
+  // 8.7 Alias template resource_adaptor
+  template
+using resource_adaptor = __resource_adaptor_imp<
+  typename allocator_traits<_Alloc>::template rebind_alloc>;
+
+  // 8.8 Global memory resources
+  memory_resource* new_delete_resource() noexcept;
+  memory_resource* null_memory_resource() noexcept;
+  memory_resource* get_default_resource() noexcept;
+  memory_resource* set_default_resource(memory_resource* __r) noexcept;
+
+  // TODO 8.9 Pool resource classes
+
   class memory_resource
   {
-  protected:
 static constexpr size_t _S_max_align = alignof(max_align_t);
 
   public:
-virtual ~memory_resource() { }
+memory_resource() = default;
+memory_resource(const memory_resource&) = default;
+virtual ~memory_resource() = default;
+
+memory_resource& operator=(const memory_resource&) = default;
 
 void*
 allocate(size_t __bytes, size_t __alignment = _S_max_align)
@@ -109,18 +111,15 @@ namespace pmr {
   };
 
   inline bool
-  operator==(const memory_resource& __a,
-const memory_resource& __b) noexcept
+  operator==(const memory_resource& __a, const memory_resource& __b) noexcept
   { return &__a == &__b || __a.is_equal(__b); }
 
   inline bool
-  operator!=(const memory_resource& __a,
-const memory_resource& __b) noexcept
+  operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
   { return !(__a == __b); }
 
 
-  // 8.6 Class template polymorphic_allocator
-  template 
+  template
 class polymorphic_allocator
 {
   using __uses_alloc1_ = __uses_alloc1;
@@ -134,14 +133,15 @@ namespace pmr {
   template
void
_M_construct(__uses_alloc1_, _Tp1* __p, _Args&&...  __args)
-   { ::new(__p) _Tp1(a

[PATCH] Minor refactoring in header

2018-07-24 Thread Jonathan Wakely

* include/std/bit (__countl_zero, __countr_zero, __popcount): Use
local variables for number of digits instead of type aliases.
(__log2p1): Remove redundant branch also checked in __countl_zero.

Tested powerpc64le-linux, committed to trunk.


commit b5cb477ecf9e98d10f4608bd2d94f57ee3bd48e5
Author: Jonathan Wakely 
Date:   Tue Jul 24 14:10:01 2018 +0100

Minor refactoring in  header

* include/std/bit (__countl_zero, __countr_zero, __popcount): Use
local variables for number of digits instead of type aliases.
(__log2p1): Remove redundant branch also checked in __countl_zero.

diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index a23f2ba60d1..0aebac28758 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -62,45 +62,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 constexpr int
 __countl_zero(_Tp __x) noexcept
 {
-  using __limits = numeric_limits<_Tp>;
+  constexpr auto _Nd = numeric_limits<_Tp>::digits;
 
   if (__x == 0)
-return __limits::digits;
+return _Nd;
 
-  using __limits_ull = numeric_limits;
-  using __limits_ul = numeric_limits;
-  using __limits_u = numeric_limits;
+  constexpr auto _Nd_ull = numeric_limits::digits;
+  constexpr auto _Nd_ul = numeric_limits::digits;
+  constexpr auto _Nd_u = numeric_limits::digits;
 
-  if _GLIBCXX17_CONSTEXPR (__limits::digits <= __limits_u::digits)
+  if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
{
- constexpr int __diff = __limits_u::digits - __limits::digits;
+ constexpr int __diff = _Nd_u - _Nd;
  return __builtin_clz(__x) - __diff;
}
-  else if _GLIBCXX17_CONSTEXPR (__limits::digits <= __limits_ul::digits)
+  else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
{
- constexpr int __diff = __limits_ul::digits - __limits::digits;
+ constexpr int __diff = _Nd_ul - _Nd;
  return __builtin_clzl(__x) - __diff;
}
-  else if _GLIBCXX17_CONSTEXPR (__limits::digits <= __limits_ull::digits)
+  else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
{
- constexpr int __diff = __limits_ull::digits - __limits::digits;
+ constexpr int __diff = _Nd_ull - _Nd;
  return __builtin_clzll(__x) - __diff;
}
-  else // (__limits::digits > __limits_ull::digits)
+  else // (_Nd > _Nd_ull)
{
- static_assert(__limits::digits <= (2 * __limits_ull::digits),
+ static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
 
- unsigned long long __high = __x >> __limits_ull::digits;
+ unsigned long long __high = __x >> _Nd_ull;
  if (__high != 0)
{
- constexpr int __diff
-   = (2 * __limits_ull::digits) - __limits::digits;
+ constexpr int __diff = (2 * _Nd_ull) - _Nd;
  return __builtin_clzll(__high) - __diff;
}
- unsigned long long __low = __x & __limits_ull::max();
- return (__limits::digits - __limits_ull::digits)
-   + __builtin_clzll(__low);
+ constexpr auto __max_ull = numeric_limits::max();
+ unsigned long long __low = __x & __max_ull;
+ return (_Nd - _Nd_ull) + __builtin_clzll(__low);
}
 }
 
@@ -117,31 +116,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 constexpr int
 __countr_zero(_Tp __x) noexcept
 {
-  using __limits = numeric_limits<_Tp>;
+  constexpr auto _Nd = numeric_limits<_Tp>::digits;
 
   if (__x == 0)
-return __limits::digits;
+return _Nd;
 
-  using __limits_ull = numeric_limits;
-  using __limits_ul = numeric_limits;
-  using __limits_u = numeric_limits;
+  constexpr auto _Nd_ull = numeric_limits::digits;
+  constexpr auto _Nd_ul = numeric_limits::digits;
+  constexpr auto _Nd_u = numeric_limits::digits;
 
-  if _GLIBCXX17_CONSTEXPR (__limits::digits <= __limits_u::digits)
+  if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
return __builtin_ctz(__x);
-  else if _GLIBCXX17_CONSTEXPR (__limits::digits <= __limits_ul::digits)
+  else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
return __builtin_ctzl(__x);
-  else if _GLIBCXX17_CONSTEXPR (__limits::digits <= __limits_ull::digits)
+  else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
return __builtin_ctzll(__x);
-  else // (__limits::digits > __limits_ull::digits)
+  else // (_Nd > _Nd_ull)
{
- static_assert(__limits::digits <= (2 * __limits_ull::digits),
+ static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
 
- unsigned long long __low = __x & __limits_ull::max();
+ constexpr auto __max

[PATCH] PR libstdc++/86658 fix __niter_wrap to not copy invalid iterators

2018-07-24 Thread Jonathan Wakely

An output iterator passed as the unused first argument to __niter_wrap
might have already been invalidated, so don't copy it.

PR libstdc++/86658
* include/bits/stl_algobase.h (__niter_wrap<_Iterator>): Pass unused
parameter by reference, to avoid copying invalid iterators.
* testsuite/25_algorithms/copy/86658.cc: New test.

Tested powerpc64le-linux, committed to trunk.

commit e2dcaf432a8fa6e8e9d96b03003ece28fa3f1ca6
Author: Jonathan Wakely 
Date:   Tue Jul 24 21:33:54 2018 +0100

PR libstdc++/86658 fix __niter_wrap to not copy invalid iterators

An output iterator passed as the unused first argument to __niter_wrap
might have already been invalidated, so don't copy it.

PR libstdc++/86658
* include/bits/stl_algobase.h (__niter_wrap<_Iterator>): Pass unused
parameter by reference, to avoid copying invalid iterators.
* testsuite/25_algorithms/copy/86658.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index f0130bc4123..b1ecd83ddb7 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -288,7 +288,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // No need to wrap, iterator already has the right type.
   template
 inline _Iterator
-__niter_wrap(_Iterator, _Iterator __res)
+__niter_wrap(const _Iterator&, _Iterator __res)
 { return __res; }
 
   // All of these auxiliary structs serve two purposes.  (1) Replace
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/86658.cc 
b/libstdc++-v3/testsuite/25_algorithms/copy/86658.cc
new file mode 100644
index 000..600747a823d
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/86658.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2018 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-do run }
+
+#define _GLIBCXX_DEBUG
+#include 
+#include 
+
+void
+test01()
+{
+  int i[1] = { 1 };
+  std::vector v(1);
+  std::copy(i, i+1, std::inserter(v, v.end()));
+}
+
+int
+main()
+{
+  test01();
+}


[PATCH] Add initial version of C++17 header

2018-07-24 Thread Jonathan Wakely

This is missing the synchronized_pool_resource and
unsynchronized_pool_resource classes but is otherwise complete.

This is a new implementation, not based on the existing code in
, but memory_resource and
polymorphic_allocator ended up looking almost the same anyway.

The constant_init kluge in src/c++17/memory_resource.cc is apparently
due to Richard Smith and ensures that the objects are constructed during
constant initialiation phase and not destroyed (because the
constant_init destructor doesn't destroy the union member and the
storage is not reused).

* config/abi/pre/gnu.ver: Export new symbols.
* configure: Regenerate.
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/precompiled/stdc++.h: Include  for C++17.
* include/std/memory_resource: New header.
(memory_resource, polymorphic_allocator, new_delete_resource)
(null_memory_resource, set_default_resource, get_default_resource)
(pool_options, monotonic_buffer_resource): Define.
* src/Makefile.am: Add c++17 directory.
* src/Makefile.in: Regenerate.
* src/c++11/Makefile.am: Fix comment.
* src/c++17/Makefile.am: Add makefile for new sub-directory.
* src/c++17/Makefile.in: Generate.
* src/c++17/memory_resource.cc: New.
(newdel_res_t, null_res_t, constant_init, newdel_res, null_res)
(default_res, new_delete_resource, null_memory_resource)
(set_default_resource, get_default_resource): Define.
* testsuite/20_util/memory_resource/1.cc: New test.
* testsuite/20_util/memory_resource/2.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/1.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/allocate.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/deallocate.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/release.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/upstream_resource.cc:
New test.
* testsuite/20_util/polymorphic_allocator/1.cc: New test.
* testsuite/20_util/polymorphic_allocator/resource.cc: New test.
* testsuite/20_util/polymorphic_allocator/select.cc: New test.
* testsuite/util/testsuite_allocator.h (__gnu_test::memory_resource):
Define concrete memory resource for testing.
(__gnu_test::default_resource_mgr): Define RAII helper for changing
default resource.

Tested powerpc64le-linux, committed to trunk.



commit 05c7ae80dbd59fcef5d583eac15181afbc07a116
Author: Jonathan Wakely 
Date:   Tue Jul 24 14:19:19 2018 +0100

Add initial version of C++17  header

This is missing the synchronized_pool_resource and
unsynchronized_pool_resource classes but is otherwise complete.

This is a new implementation, not based on the existing code in
, but memory_resource and
polymorphic_allocator ended up looking almost the same anyway.

The constant_init kluge in src/c++17/memory_resource.cc is apparently
due to Richard Smith and ensures that the objects are constructed during
constant initialiation phase and not destroyed (because the
constant_init destructor doesn't destroy the union member and the
storage is not reused).

* config/abi/pre/gnu.ver: Export new symbols.
* configure: Regenerate.
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/precompiled/stdc++.h: Include  for C++17.
* include/std/memory_resource: New header.
(memory_resource, polymorphic_allocator, new_delete_resource)
(null_memory_resource, set_default_resource, get_default_resource)
(pool_options, monotonic_buffer_resource): Define.
* src/Makefile.am: Add c++17 directory.
* src/Makefile.in: Regenerate.
* src/c++11/Makefile.am: Fix comment.
* src/c++17/Makefile.am: Add makefile for new sub-directory.
* src/c++17/Makefile.in: Generate.
* src/c++17/memory_resource.cc: New.
(newdel_res_t, null_res_t, constant_init, newdel_res, null_res)
(default_res, new_delete_resource, null_memory_resource)
(set_default_resource, get_default_resource): Define.
* testsuite/20_util/memory_resource/1.cc: New test.
* testsuite/20_util/memory_resource/2.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/1.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/allocate.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/deallocate.cc: New 
test.
* testsuite/20_util/monotonic_buffer_resource/release.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/upstream_resource.cc:
New test.
* testsuite/20_util/polymorphic_allocator

[PATCH] Move std::unique_lock definition to a separate header

2018-07-25 Thread Jonathan Wakely

This will allow std::mutex and std::lock_guard to be used elsewhere in
the library without pulling in the whole of .

Previously the whole of  was conditional on the
_GLIBCXX_USE_C99_STDINT_TR1 macro, but only the std::unique_lock members
that use  facilities should depend on that. std::mutex only
needs to depend on _GLIBCXX_HAS_GTHREADS and std::lock_guard can be
defined unconditionally.

Some parts of  and  are based on code in
 which dates from 2003. However, the std::unique_lock
implementation was added in 2008 by r135007, without using any earlier
code. Therefore the new header file has copyright years 2008-2018.

* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/bits/std_mutex.h [!_GLIBCXX_USE_C99_STDINT_TR1] (mutex)
(lock_guard): Define independent of _GLIBCXX_USE_C99_STDINT_TR1.
(unique_lock): Move definition to ...
* include/bits/unique_lock.h: New header.
[!_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock): Define unconditionally.
[_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock(mutex_type&, time_point))
(unique_lock(mutex_type&, duration), unique_lock::try_lock_until)
(unique_lock::try_lock_for): Define only when  is usable.
* include/std/condition_variable: Include .
* include/std/mutex: Likewise.

Tested powerpc64le-linux, committed to trunk.


commit c84285a3a0e3d252d3f8e1ffec6dd56997a87fe8
Author: Jonathan Wakely 
Date:   Wed Jul 25 10:50:33 2018 +0100

Move std::unique_lock definition to a separate header

This will allow std::mutex and std::lock_guard to be used elsewhere in
the library without pulling in the whole of .

Previously the whole of  was conditional on the
_GLIBCXX_USE_C99_STDINT_TR1 macro, but only the std::unique_lock members
that use  facilities should depend on that. std::mutex only
needs to depend on _GLIBCXX_HAS_GTHREADS and std::lock_guard can be
defined unconditionally.

Some parts of  and  are based on code in
 which dates from 2003. However, the std::unique_lock
implementation was added in 2008 by r135007, without using any earlier
code. Therefore the new header file has copyright years 2008-2018.

* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/bits/std_mutex.h [!_GLIBCXX_USE_C99_STDINT_TR1] (mutex)
(lock_guard): Define independent of _GLIBCXX_USE_C99_STDINT_TR1.
(unique_lock): Move definition to ...
* include/bits/unique_lock.h: New header.
[!_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock): Define 
unconditionally.
[_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock(mutex_type&, time_point))
(unique_lock(mutex_type&, duration), unique_lock::try_lock_until)
(unique_lock::try_lock_for): Define only when  is usable.
* include/std/condition_variable: Include .
* include/std/mutex: Likewise.

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 9daa8856e70..70db3cb6260 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -199,6 +199,7 @@ bits_headers = \
${bits_srcdir}/stringfwd.h \
${bits_srcdir}/string_view.tcc \
${bits_srcdir}/uniform_int_dist.h \
+   ${bits_srcdir}/unique_lock.h \
${bits_srcdir}/unique_ptr.h \
${bits_srcdir}/unordered_map.h \
${bits_srcdir}/unordered_set.h \
diff --git a/libstdc++-v3/include/bits/std_mutex.h 
b/libstdc++-v3/include/bits/std_mutex.h
index 34d22907a06..41a9b30636a 100644
--- a/libstdc++-v3/include/bits/std_mutex.h
+++ b/libstdc++-v3/include/bits/std_mutex.h
@@ -39,9 +39,6 @@
 #include 
 #include 
 #include 
-#include  // for std::swap
-
-#ifdef _GLIBCXX_USE_C99_STDINT_TR1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -174,200 +171,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   mutex_type&  _M_device;
 };
 
-  /** @brief A movable scoped lock type.
-   *
-   * A unique_lock controls mutex ownership within a scope. Ownership of the
-   * mutex can be delayed until after construction and can be transferred
-   * to another unique_lock by move construction or move assignment. If a
-   * mutex lock is owned when the destructor runs ownership will be released.
-   */
-  template
-class unique_lock
-{
-public:
-  typedef _Mutex mutex_type;
-
-  unique_lock() noexcept
-  : _M_device(0), _M_owns(false)
-  { }
-
-  explicit unique_lock(mutex_type& __m)
-  : _M_device(std::__addressof(__m)), _M_owns(false)
-  {
-   lock();
-   _M_owns = true;
-  }
-
-  unique_lock(mutex_type& __m, defer_lock_t) noexcept
-  : _M_device(std::__addressof(__m)), _M_owns(false)
-  { }
-
-  unique_lock(mutex_type& __m, try_to_lock_t)
-  : _M_device(std::__addressof(__

Re: [PATCH] Add initial version of C++17 header

2018-07-25 Thread Jonathan Wakely

On 24/07/18 22:12 +0100, Jonathan Wakely wrote:

This is missing the synchronized_pool_resource and
unsynchronized_pool_resource classes but is otherwise complete.

This is a new implementation, not based on the existing code in
, but memory_resource and
polymorphic_allocator ended up looking almost the same anyway.

The constant_init kluge in src/c++17/memory_resource.cc is apparently
due to Richard Smith and ensures that the objects are constructed during
constant initialiation phase and not destroyed (because the
constant_init destructor doesn't destroy the union member and the
storage is not reused).

* config/abi/pre/gnu.ver: Export new symbols.
* configure: Regenerate.
* include/Makefile.am: Add new  header.
* include/Makefile.in: Regenerate.
* include/precompiled/stdc++.h: Include  for C++17.
* include/std/memory_resource: New header.
(memory_resource, polymorphic_allocator, new_delete_resource)
(null_memory_resource, set_default_resource, get_default_resource)
(pool_options, monotonic_buffer_resource): Define.
* src/Makefile.am: Add c++17 directory.
* src/Makefile.in: Regenerate.
* src/c++11/Makefile.am: Fix comment.
* src/c++17/Makefile.am: Add makefile for new sub-directory.
* src/c++17/Makefile.in: Generate.
* src/c++17/memory_resource.cc: New.
(newdel_res_t, null_res_t, constant_init, newdel_res, null_res)
(default_res, new_delete_resource, null_memory_resource)
(set_default_resource, get_default_resource): Define.
* testsuite/20_util/memory_resource/1.cc: New test.
* testsuite/20_util/memory_resource/2.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/1.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/allocate.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/deallocate.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/release.cc: New test.
* testsuite/20_util/monotonic_buffer_resource/upstream_resource.cc:
New test.
* testsuite/20_util/polymorphic_allocator/1.cc: New test.
* testsuite/20_util/polymorphic_allocator/resource.cc: New test.
* testsuite/20_util/polymorphic_allocator/select.cc: New test.
* testsuite/util/testsuite_allocator.h (__gnu_test::memory_resource):
Define concrete memory resource for testing.
(__gnu_test::default_resource_mgr): Define RAII helper for changing
default resource.

Tested powerpc64le-linux, committed to trunk.


I missed a change to acinclude.m4 that should have gone with this
patch. Now also committed to trunk.


commit cdaaa2b47d3fa093c741086e86d631d420a93663
Author: Jonathan Wakely 
Date:   Wed Jul 25 11:52:19 2018 +0100

Add new src/c++17 directory to list in acinclude.m4

* acinclude.m4 (glibcxx_SUBDIRS): Add src/c++17.
* src/Makefile.am: Add comment.
* src/c++17/Makefile.in: Regenerate.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index bbf3c8df3e1..6d68e907426 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/filesystem doc po testsuite python])
+  m4_define([glibcxx_SUBDIRS],[include libsupc++ src src/c++98 src/c++11 src/c++17 src/filesystem 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/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 09edcdbc471..9a2fe297ddb 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -28,6 +28,7 @@ else
 filesystem_dir =
 endif
 
+## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
 SUBDIRS = c++98 c++11 c++17 $(filesystem_dir)
 
 # Cross compiler support.


Re: optimize std::vector move assignment

2018-07-25 Thread Jonathan Wakely

On 25/07/18 14:38 +0200, Marc Glisse wrote:

Hello,

I talked about this last year 
(https://gcc.gnu.org/ml/gcc-patches/2017-04/msg01063.html and thread), 
this tweaks std::vector move assignment to help gcc generate better 
code for it.


Ah yes, thank for revisiting it.


For this code

#include 
#include 
typedef std::vector V;
void f(V&a,V&b){a=std::move(b);}

with -O2 -fdump-tree-optimized on powerpc64le-unknown-linux-gnu, we 
currently have


 _5 = MEM[(int * &)a_3(D)];
 MEM[(int * &)a_3(D)] = 0B;
 MEM[(int * &)a_3(D) + 8] = 0B;
 MEM[(int * &)a_3(D) + 16] = 0B;
 _6 = MEM[(int * &)b_2(D)];
 MEM[(int * &)a_3(D)] = _6;
 MEM[(int * &)b_2(D)] = 0B;
 _7 = MEM[(int * &)a_3(D) + 8];
 _8 = MEM[(int * &)b_2(D) + 8];
 MEM[(int * &)a_3(D) + 8] = _8;
 MEM[(int * &)b_2(D) + 8] = _7;
 _9 = MEM[(int * &)a_3(D) + 16];
 _10 = MEM[(int * &)b_2(D) + 16];
 MEM[(int * &)a_3(D) + 16] = _10;
 MEM[(int * &)b_2(D) + 16] = _9;
 if (_5 != 0B)

with the patch, we go down to

 _3 = MEM[(const struct _Vector_impl_data &)a_4(D)]._M_start;
 _5 = MEM[(const struct _Vector_impl_data &)b_2(D)]._M_start;
 MEM[(struct _Vector_impl_data *)a_4(D)]._M_start = _5;
 _6 = MEM[(const struct _Vector_impl_data &)b_2(D)]._M_finish;
 MEM[(struct _Vector_impl_data *)a_4(D)]._M_finish = _6;
 _7 = MEM[(const struct _Vector_impl_data &)b_2(D)]._M_end_of_storage;
 MEM[(struct _Vector_impl_data *)a_4(D)]._M_end_of_storage = _7;
 MEM[(struct _Vector_impl_data *)b_2(D)]._M_start = 0B;
 MEM[(struct _Vector_impl_data *)b_2(D)]._M_finish = 0B;
 MEM[(struct _Vector_impl_data *)b_2(D)]._M_end_of_storage = 0B;
 if (_3 != 0B)

removing 2 reads and 3 writes. At -O3 we also get more vectorization.

The main idea is to give the compiler more type information. 
Currently, the only type information the compiler cares about is the 
type used for a memory read/write. Using std::swap as before, the 
reads/writes are done on int&. Doing it directly, they are done on 
_Vector_impl_data::_M_start, a more precise information. Maybe some 
day the compiler will get stricter and be able to deduce the same 
information, but not yet.


The second point is to rotate { new, old, tmp } in an order that's 
simpler for the compiler. I was going to remove the swaps and use 
_M_copy_data directly, but since doing the swaps in a different order 
works...


_M_copy_data is not really needed, we could add a defaulted assignment 
operator, or remove the move constructor (and call a new _M_clear() 
from the 2 users), etc. However, it seemed the least intrusive, the 
least likely to have weird consequences.


Yes, the alternative would be:

--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -100,14 +100,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   : _M_start(__x._M_start), _M_finish(__x._M_finish),
 _M_end_of_storage(__x._M_end_of_storage)
   { __x._M_start = __x._M_finish = __x._M_end_of_storage = pointer(); }
+
+   _Vector_impl_data(const _Vector_impl_data&) = default;
+   _Vector_impl_data& oeprator=(const _Vector_impl_data&) = default;
#endif

   void
   _M_swap_data(_Vector_impl_data& __x) _GLIBCXX_NOEXCEPT
   {
- std::swap(_M_start, __x._M_start);
- std::swap(_M_finish, __x._M_finish);
- std::swap(_M_end_of_storage, __x._M_end_of_storage);
+ _Vector_impl_data __tmp = *this;
+ *this = __x;
+ __x = __tmp;
   }
  };

Your _M_copy_data seems fine. It avoids unintentional copies, because
the copy constructor and copy assignment operator remain deleted (at
least in C++11).

I didn't add a testcase because I don't see any dg-final 
scan-tree-dump in the libstdc++ testsuite. The closest would be 
g++.dg/pr83239.C, g++.dg/vect/pr64410.cc, 
g++.dg/vect/pr33426-ivdep-4.cc that include , but from 
previous experience (already with vector), adding libstdc++ testcases 
to the C++ testsuite is not very popular.


Yes, C++ tests using std::vector are sometimes a bit fragile.

I don't see any reason we can't use scan-tree-dump in the libstdc++
testsuite, if you wanted to add one. We do have other dg-final tests.



Index: libstdc++-v3/include/bits/stl_vector.h
===
--- libstdc++-v3/include/bits/stl_vector.h  (revision 262948)
+++ libstdc++-v3/include/bits/stl_vector.h  (working copy)
@@ -96,25 +96,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ }

#if __cplusplus >= 201103L
_Vector_impl_data(_Vector_impl_data&& __x) noexcept
: _M_start(__x._M_start), _M_finish(__x._M_finish),
  _M_end_of_storage(__x._M_end_of_storage)
{ __x._M_start = __x._M_finish = __x._M_end_of_storage = pointer(); }
#endif

void
+   _M_copy_data(_Vector_impl_data const& __x) _GLIBCXX_NOEXCEPT
+   {
+ _M_start = __x._M_start;
+ _M_finish = __x._M_finish;
+ _M_end_of_storage = __x._M_end_of_storage;
+   }
+
+   void
_M_swap_data(_Vector_impl_da

Re: [PATCH] Make __resource_adaptor_imp usable with C++17 memory_resource

2018-07-25 Thread Jonathan Wakely

On 24/07/18 14:06 +0100, Jonathan Wakely wrote:

By making the memory_resource base class a template parameter the
__resource_adaptor_imp can be used to adapt an allocator into a
std::pmr::memory_resource instead of experimental::pmr::memory_resource.

No uses for this in the library but somebody might want to do it, and
it costs us nothing to support.

* include/experimental/memory_resource: Adjust comments and
whitespace.
(__resource_adaptor_imp): Add second template parameter for type of
memory resource base class.
(memory_resource): Define default constructor, destructor, copy
constructor and copy assignment operator as defaulted.

Tested powerpc64le-linux, committed to trunk.




commit ce04fa1c00b40a938cc25a264836a2e30149056e
Author: Jonathan Wakely 
Date:   Tue Jul 24 12:24:53 2018 +0100

   Make __resource_adaptor_imp usable with C++17 memory_resource

   By making the memory_resource base class a template parameter the
   __resource_adaptor_imp can be used to adapt an allocator into a
   std::pmr::memory_resource instead of experimental::pmr::memory_resource.

   * include/experimental/memory_resource: Adjust comments and
   whitespace.
   (__resource_adaptor_imp): Add second template parameter for type of
   memory resource base class.
   (memory_resource): Define default constructor, destructor, copy
   constructor and copy assignment operator as defaulted.

diff --git a/libstdc++-v3/include/experimental/memory_resource 
b/libstdc++-v3/include/experimental/memory_resource
index 83379d1367a..7ce64457a11 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -29,12 +29,12 @@
#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE
#define _GLIBCXX_EXPERIMENTAL_MEMORY_RESOURCE 1

-#include 
+#include // align, uses_allocator, __uses_alloc
+#include   // pair, experimental::erased_type
+#include // atomic
#include 
-#include 
-#include 
#include 
-#include 
+#include 


I should not have removed  here, it's needed for
std::max_align_t.

Committed to trunk as obvious.


commit 5258907ab3e829b75a70872e9d6f627461c84176
Author: Jonathan Wakely 
Date:   Wed Jul 25 18:20:29 2018 +0100

Add missing header for std::max_align_t

* include/experimental/memory_resource: Include  header.

diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index 7ce64457a11..61c9ce0a14a 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -32,7 +32,8 @@
 #include 			// align, uses_allocator, __uses_alloc
 #include 		// pair, experimental::erased_type
 #include 			// atomic
-#include 
+#include // placement new
+#include 			// max_align_t
 #include 
 #include 
 


Re: Share ebo helper throughout lib

2018-07-25 Thread Jonathan Wakely

On 25/07/18 21:42 +0200, François Dumont wrote:

Hi

    It has already been noticed that there are 2 ebo helpers in the 
lib. Here is a patch to use 1.



    * include/bits/ebo_helper.h: New.
    * include/Makefile.am: Add latter.
    * include/Makefile.in: Regenerate.
    * include/bits/hashtable_policy.h: Adapt.
    * include/bits/shared_ptr_base.h: Adapt.


I think we want an extra template parameter which is used for a tag
type, to guarantee that the two uses (in hash tables and in shared
ptr) can never conflict and produce ambiguous bases.

i.e.

 template
   struct _Ebo_helper;

and:

using _Sp_ebo_helper = __detail::_Ebo_helper<_Nm, _Tp, _Sp_counted_base<>>;

(for example).




Re: Share ebo helper throughout lib

2018-07-25 Thread Jonathan Wakely

On 25/07/18 21:53 +0200, Marc Glisse wrote:

On Wed, 25 Jul 2018, François Dumont wrote:

    It has already been noticed that there are 2 ebo helpers in the 
lib. Here is a patch to use 1.



    * include/bits/ebo_helper.h: New.
    * include/Makefile.am: Add latter.
    * include/Makefile.in: Regenerate.
    * include/bits/hashtable_policy.h: Adapt.
    * include/bits/shared_ptr_base.h: Adapt.

Tested under linux x86_64.

Ok to commit ?


I don't think we support [[no_unique_address]] yet, but assuming we 
soon will and we enable it also for C++03 (at least with the 
__attribute__ syntax and/or in system headers), do you know if some 


Yes, I hope we'll have that soon.

similar helper will still be necessary, with a simpler implementation, 
or if the attribute will magically get rid of it?


We'll be able to replace some uses of EBO with the attribute
(specifically, in std::tuple). In some places we'll want to only apply
the attribute under the same conditions as we currently use the EBO,
because otherwise we'd change the layout ("compressing" the member
using the attribute where we previously didn't compress it).

In some cases that will be OK because it's an internal implementation
detail, or because we can replace e.g. _Sp_counted_deleter with
_Sp_counted_deleter_v2. In other cases we must avoid any layout change
(e.g. std::tuple).

Concretely, we probably don't want to change the layout of the
hashtable types. We could change the layout for shared_ptr
_Sp_counted_xxx types (gaining some additional space savings for final
types that currently can't be EBO'd) as long as we rename them to
avoid the linker trying to combine incompatible definitions. So on
that basis, maybe we don't want to bother changing the _Sp_ebo_helper
for now.




  1   2   3   4   5   6   7   8   9   10   >