[PATCH][_Hashtable] Avoid redundant usage of rehash policy

2023-09-17 Thread François Dumont via Gcc-patches

libstdc++: [_Hashtable] Avoid redundant usage of rehash policy

Bypass usage of __detail::__distance_fwd and check for need to rehash 
when assigning an initializer_list to

an unordered_multimap or unordered_multiset.

libstdc++-v3/ChangeLog:

    * include/bits/hashtable_policy.h
    (_Insert_base<>::_M_insert_range(_InputIte, _InputIte, _NodeGen&)): 
New.
    (_Insert_base<>::_M_insert_range(_InputIte, _InputIte, true_type)): 
Use latter.
    (_Insert_base<>::_M_insert_range(_InputIte, _InputIte, 
false_type)): Likewise.

    * include/bits/hashtable.h
(_Hashtable<>::operator=(initializer_list)): Likewise.
    (_Hashtable<>::_Hashtable(_InputIte, _InputIte, size_type, const 
_Hash&, const _Equal&,

    const allocator_type&, false_type)): Likewise.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 4c12dc895b2..c544094847d 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -614,7 +614,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	if (_M_bucket_count < __l_bkt_count)
 	  rehash(__l_bkt_count);
 
-	this->_M_insert_range(__l.begin(), __l.end(), __roan, __unique_keys{});
+	this->_M_insert_range(__l.begin(), __l.end(), __roan);
 	return *this;
   }
 
@@ -1254,8 +1254,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
 
 	__alloc_node_gen_t __node_gen(*this);
-	for (; __f != __l; ++__f)
-	  _M_insert(*__f, __node_gen, __uks);
+	this->_M_insert_range(__f, __l, __node_gen);
   }
 
   template
 	void
 	_M_insert_range(_InputIterator __first, _InputIterator __last,
-			const _NodeGetter&, true_type __uks);
+			const _NodeGetter&);
 
-  template
+  template
 	void
 	_M_insert_range(_InputIterator __first, _InputIterator __last,
-			const _NodeGetter&, false_type __uks);
+			true_type __uks);
+
+  template
+	void
+	_M_insert_range(_InputIterator __first, _InputIterator __last,
+			false_type __uks);
 
 public:
   using iterator = _Node_iterator<_Value, __constant_iterators::value,
@@ -966,11 +971,7 @@ namespace __detail
   template
 	void
 	insert(_InputIterator __first, _InputIterator __last)
-	{
-	  __hashtable& __h = _M_conjure_hashtable();
-	  __node_gen_type __node_gen(__h);
-	  return _M_insert_range(__first, __last, __node_gen, __unique_keys{});
-	}
+	{ _M_insert_range(__first, __last, __unique_keys{}); }
 };
 
   template::
   _M_insert_range(_InputIterator __first, _InputIterator __last,
-		  const _NodeGetter& __node_gen, true_type __uks)
+		  const _NodeGetter& __node_gen)
   {
 	__hashtable& __h = _M_conjure_hashtable();
 	for (; __first != __last; ++__first)
-	  __h._M_insert(*__first, __node_gen, __uks);
+	  __h._M_insert(*__first, __node_gen, __unique_keys{});
   }
 
   template
-template
+template
+  void
+  _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
+		   _Hash, _RangeHash, _Unused,
+		   _RehashPolicy, _Traits>::
+  _M_insert_range(_InputIterator __first, _InputIterator __last,
+		  true_type /* __uks */)
+  {
+	__hashtable& __h = _M_conjure_hashtable();
+	__node_gen_type __node_gen(__h);
+	_M_insert_range(__first, __last, __node_gen);
+  }
+
+  template
+template
   void
   _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
 		   _Hash, _RangeHash, _Unused,
 		   _RehashPolicy, _Traits>::
   _M_insert_range(_InputIterator __first, _InputIterator __last,
-		  const _NodeGetter& __node_gen, false_type __uks)
+		  false_type /* __uks */)
   {
 	using __rehash_type = typename __hashtable::__rehash_type;
 	using __rehash_state = typename __hashtable::__rehash_state;
@@ -1020,8 +1038,8 @@ namespace __detail
 	if (__do_rehash.first)
 	  __h._M_rehash(__do_rehash.second, __saved_state);
 
-	for (; __first != __last; ++__first)
-	  __h._M_insert(*__first, __node_gen, __uks);
+	__node_gen_type __node_gen(__h);
+	_M_insert_range(__first, __last, __node_gen);
   }
 
   /**


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

2023-09-13 Thread François Dumont via Gcc-patches

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

diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 347d468ea86..86b32fb15f2 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -327,18 +327,22 @@ namespace __detail
 
   __gnu_cxx::__aligned_buffer<_Value> _M_storage;
 
+  [[__gnu__::__always_inline__]]
   _Value*
   _M_valptr() noexcept
   { return _M_storage._M_ptr(); }
 
+  [[__gnu__::__always_inline__]]
   const _Value*
   _M_valptr() const noexcept
   { return _M_storage._M_ptr(); }
 
+  [[__gnu__::__always_inline__]]
   _Value&
   _M_v() noexcept
   { return *_M_valptr(); }
 
+  [[__gnu__::__always_inline__]]
   const _Value&
   _M_v() const noexcept
   { return *_M_valptr(); }


[committed] Limit header synopsis test to normal namespace

2023-09-13 Thread François Dumont via Gcc-patches

Committed as trivial.

    libstdc++: Limit  synopsis test to normal namespace

    libstdc++-v3/ChangeLog

    * testsuite/19_diagnostics/stacktrace/synopsis.cc: Add
    { dg-require-normal-namespace "" }.

François
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc
index ece5d526fb9..21c94f34a13 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc
@@ -1,6 +1,7 @@
 // { dg-options "-std=gnu++23" }
 // { dg-do compile { target c++23 } }
 // { dg-require-effective-target stacktrace }
+// { dg-require-normal-namespace "" }
 
 #include 
 


Re: [PATCH][_GLIBCXX_INLINE_VERSION] Fix friend declarations

2023-09-13 Thread François Dumont via Gcc-patches

It's working and what's I've committed.

Thanks

On 12/09/2023 19:04, Jonathan Wakely wrote:

On Tue, 12 Sept 2023 at 17:47, Jonathan Wakely  wrote:

On Wed, 23 Aug 2023 at 18:35, François Dumont via Libstdc++
 wrote:

Hi

The few tests that are failing in versioned namespace mode are due to
those friend declarations.

This is a fix proposal even if I considered 2 other options:

1. Make __format::_Arg_store a struct and so do not bother with friend
declarations.

2. Consider it as a compiler bug and do nothing. In this case I think we
might still need this patch to avoid a non-working format library in
versioned namespace mode in gcc 14 if compiler bug is not fixed.

It definitely is a compiler bug, this is PR c++/59256.

Please add a comment to the new macro definition, so we remember to
remove it when it's not needed:


#if _GLIBCXX_INLINE_VERSION
// Needed because of PR c++/59526
# define _GLIBCXX_STD_V std::__8
#else
# define _GLIBCXX_STD_V std
#endif


OK with that change, thanks.

Actually, are you sure the friend std::basic_format_args declaration
needs to change?

I only see errors for the friend function, not the friend class. So
this seems to fix it:

--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3437,7 +3437,13 @@ namespace __format

   template
friend auto
-   std::make_format_args(_Argz&&...) noexcept;
+#if _GLIBCXX_INLINE_VERSION
+   // Needed for PR c++/59526
+   std::__8::
+#else
+   std::
+#endif
+   make_format_args(_Argz&&...) noexcept;

   // For a sufficiently small number of arguments we only store values.
   // basic_format_args can get the types from the _Args pack.







I can also define _GLIBCXX_STD_V at  level to limit impact.

  libstdc++: [_GLIBCXX_INLINE_VERSION] Fix  friend declarations

  GCC do not consider the inline namespace in friend declarations. We
need
  to explicit this namespace.

  libstdc++-v3/ChangeLog:

  * include/bits/c++config (_GLIBCXX_STD_V): New macro giving
current
  std namespace with optionally the version namespace.
  * include/std/format (std::__format::_Arg_store): Use
latter on friend
  declarations.

Tested under versioned mode.

Ok to commit ?

François


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

2023-09-11 Thread François Dumont via Gcc-patches



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:

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




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

2023-09-10 Thread François Dumont via Gcc-patches
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 ?


    libstdc++: Add constexpr qualification to _Hash_node::_M_next()

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:

    * 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: TC 

Ok to commit and backport to GCC 11, 12, 13 branches ?

François

diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index 347d468ea86..101c5eb639c 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -327,18 +327,22 @@ namespace __detail
 
   __gnu_cxx::__aligned_buffer<_Value> _M_storage;
 
+  [[__gnu__::__always_inline__]]
   _Value*
   _M_valptr() noexcept
   { return _M_storage._M_ptr(); }
 
+  [[__gnu__::__always_inline__]]
   const _Value*
   _M_valptr() const noexcept
   { return _M_storage._M_ptr(); }
 
+  [[__gnu__::__always_inline__]]
   _Value&
   _M_v() noexcept
   { return *_M_valptr(); }
 
+  [[__gnu__::__always_inline__]]
   const _Value&
   _M_v() const noexcept
   { return *_M_valptr(); }
@@ -372,7 +376,7 @@ namespace __detail
 : _Hash_node_base
 , _Hash_node_value<_Value, _Cache_hash_code>
 {
-  _Hash_node*
+  constexpr _Hash_node*
   _M_next() const noexcept
   { return static_cast<_Hash_node*>(this->_M_nxt); }
 };


Re: [PATCH][_GLIBCXX_INLINE_VERSION] Fix friend declarations

2023-09-07 Thread François Dumont via Gcc-patches

Hi

Any news regarding this problem ?

François

On 23/08/2023 19:35, François Dumont wrote:

Hi

The few tests that are failing in versioned namespace mode are due to 
those friend declarations.


This is a fix proposal even if I considered 2 other options:

1. Make __format::_Arg_store a struct and so do not bother with friend 
declarations.


2. Consider it as a compiler bug and do nothing. In this case I think 
we might still need this patch to avoid a non-working format library 
in versioned namespace mode in gcc 14 if compiler bug is not fixed.


I can also define _GLIBCXX_STD_V at  level to limit impact.

    libstdc++: [_GLIBCXX_INLINE_VERSION] Fix  friend declarations

    GCC do not consider the inline namespace in friend declarations. 
We need

    to explicit this namespace.

    libstdc++-v3/ChangeLog:

    * include/bits/c++config (_GLIBCXX_STD_V): New macro 
giving current

    std namespace with optionally the version namespace.
    * include/std/format (std::__format::_Arg_store): Use 
latter on friend

    declarations.

Tested under versioned mode.

Ok to commit ?

François


Re: [PATCH][Hashtable] Performance optimization through use of insertion hint

2023-09-07 Thread François Dumont via Gcc-patches



On 01/09/2023 10:59, Jonathan Wakely wrote:

On Tue, 29 Aug 2023 at 20:52, François Dumont via Libstdc++
 wrote:

Hi

Any feedback regarding this patch ?

This is a fairly large patch


I've decided to split it, at least in 2.

So just ignore this one, I'll submit new ones once abi issue is fixed.


  and before we make any more changes to
unordered containers we have an ABI break to fix:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111050



François

On 24/07/2023 13:02, François Dumont wrote:

libstdc++: [_Hashtable] Make more use of insertion hint


 When inserting an element into an empty bucket we currently insert
the new node
 after the before-begin node so in first position. The drawback of
doing this is
 that we are forced to update the bucket that was containing this
before-begin
 node to point to the newly inserted node. To do so we need at best
to do a modulo
 to find this bucket and when hash code is not cached also compute it.

 To avoid this side effect it is better to insert after the last
node. Adding
 a member to keep track of this last node would be an abi breaking
change. Still we
 can ask the user to maintain and provide this last node as an
insertion hint.

 Adapt range insertion methods to try to detect the last node and
then use it as
 the insertion hint.

 libstdc++-v3/ChangeLog:

 * include/bits/hashtable_policy.h:
 (_Insert_base::try_emplace): Adapt to use hint.
 (_Insert_base::_M_insert_range): Try to detect container
last node and use it
 as hint for insertions.
 (_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
 (_Hashtable<>::_M_insert_bucket_begin): Add hint parameter
and use it when inserting
 into an empty bucket if hint is the last container node.
 (_Hashtable<>::_InsertInfo): New struct.
 (_Hashtable<>::_M_get_insert_info): New, return latter.
 (_Hashtable<>::_M_insert_multi_node): Add _InsertInfo
parameter.
 (_Hashtable<>::_M_insert_unique_node): Add __node_ptr hint
parameter.
 (_Hashtable<>::_M_emplace_unique(__node_ptr, _Args&&...)):
New.
 (_Hashtable<>::_M_emplace_multi(__node_ptr, _Args&&...)):
New.
 (_Hashtable<>::_M_emplace()): Adapt to use latters.
 (_Hashtable<>::_M_insert_unique): Add __node_ptr parameter.
 (_Hashtable<>::_M_insert_unique_aux): Add __node_ptr
parameter.
 (_Hashtable<>::_M_insert(__node_ptr, _Arg&&, const
_NodeGenerator&, true_type)):
 Use latter.
 (_Hashtable<>::_M_reinsert_node(const_iterator,
node_type&&)):
 Add hint parameter, adapt to use it.
 (_Hashtable<>::_M_reinsert_node_multi): Use hint parameter
if available to extract
 hash code.
 (_Hashtable<>::_M_compute_hash_code(const _Hash&,
__node_ptr, __node_ptr,
 const key_type&)): New.
(_Hashtable<>::_M_compute_hash_code<_H2>(const _H2&, __node_ptr,
__node_ptr,
 const key_type&)): New.
 (_Hashtable<>::_M_merge_unique): Adapt to use latter.
Implement small size
 optimization.
 (_Hashtable<>::_M_get_insert_info(const _Hash&,
__node_ptr, __node_ptr,
 const key_type&)): New.
(_Hashtable<>::_M_get_insert_info<_H2>(const _H2&, __node_ptr,
__node_ptr,
 const key_type&)): New.
 (_Hashtable<>::_M_merge_multi): Adapt to use latter.
 * include/bits/unordered_map.h
(unordered_map<>::insert(node_type&&)): Pass cend as
 hint.
 (unordered_map<>::insert(const_iterator, node_type&&)):
Adapt to use hint.
 * include/bits/unordered_set.h
(unordered_set<>::insert(node_type&&)): Pass cend as
 hint.
 (unordered_set<>::insert(const_iterator, node_type&&)):
Adapt to use hint.
 *
testsuite/23_containers/unordered_multimap/insert/hint.cc: Adapt
implementation
 specific tests.

Tested under linux x86_64.

Here is the performance results of this patch, before:

unordered_multiset_hint.cc-threadhash code NOT cached 200
insertions w/o hint  94r   94u0s 191999712mem0pf
unordered_multiset_hint.cc-threadhash code NOT cached 200
insertions with perfect hint  95r   94u0s 191999712mem 0pf
unordered_multiset_hint.cc-threadhash code NOT cached 200
insertions with bad hint  94r   94u0s 191999712mem0pf
unordered_multiset_hint.cc-threadhash code NOT cached 200
range insertions  88r   88u0s 191999712mem0pf
unordered_multiset_hint.cc-threadhash code cached 200
insertions w/o hint  91r   91u0s 191999712mem0pf
unordered_multiset_hint.cc-threadhash code cached 

Re: [PATCH][Hashtable] Performance optimization through use of insertion hint

2023-08-29 Thread François Dumont via Gcc-patches

Hi

Any feedback regarding this patch ?

François

On 24/07/2023 13:02, François Dumont wrote:

libstdc++: [_Hashtable] Make more use of insertion hint


    When inserting an element into an empty bucket we currently insert 
the new node
    after the before-begin node so in first position. The drawback of 
doing this is
    that we are forced to update the bucket that was containing this 
before-begin
    node to point to the newly inserted node. To do so we need at best 
to do a modulo

    to find this bucket and when hash code is not cached also compute it.

    To avoid this side effect it is better to insert after the last 
node. Adding
    a member to keep track of this last node would be an abi breaking 
change. Still we
    can ask the user to maintain and provide this last node as an 
insertion hint.


    Adapt range insertion methods to try to detect the last node and 
then use it as

    the insertion hint.

    libstdc++-v3/ChangeLog:

    * include/bits/hashtable_policy.h:
    (_Insert_base::try_emplace): Adapt to use hint.
    (_Insert_base::_M_insert_range): Try to detect container 
last node and use it

    as hint for insertions.
    (_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
    (_Hashtable<>::_M_insert_bucket_begin): Add hint parameter 
and use it when inserting

    into an empty bucket if hint is the last container node.
    (_Hashtable<>::_InsertInfo): New struct.
    (_Hashtable<>::_M_get_insert_info): New, return latter.
    (_Hashtable<>::_M_insert_multi_node): Add _InsertInfo 
parameter.
    (_Hashtable<>::_M_insert_unique_node): Add __node_ptr hint 
parameter.
    (_Hashtable<>::_M_emplace_unique(__node_ptr, _Args&&...)): 
New.
    (_Hashtable<>::_M_emplace_multi(__node_ptr, _Args&&...)): 
New.

    (_Hashtable<>::_M_emplace()): Adapt to use latters.
    (_Hashtable<>::_M_insert_unique): Add __node_ptr parameter.
    (_Hashtable<>::_M_insert_unique_aux): Add __node_ptr 
parameter.
    (_Hashtable<>::_M_insert(__node_ptr, _Arg&&, const 
_NodeGenerator&, true_type)):

    Use latter.
    (_Hashtable<>::_M_reinsert_node(const_iterator, 
node_type&&)):

    Add hint parameter, adapt to use it.
    (_Hashtable<>::_M_reinsert_node_multi): Use hint parameter 
if available to extract

    hash code.
    (_Hashtable<>::_M_compute_hash_code(const _Hash&, 
__node_ptr, __node_ptr,

    const key_type&)): New.
(_Hashtable<>::_M_compute_hash_code<_H2>(const _H2&, __node_ptr, 
__node_ptr,

    const key_type&)): New.
    (_Hashtable<>::_M_merge_unique): Adapt to use latter. 
Implement small size

    optimization.
    (_Hashtable<>::_M_get_insert_info(const _Hash&, 
__node_ptr, __node_ptr,

    const key_type&)): New.
(_Hashtable<>::_M_get_insert_info<_H2>(const _H2&, __node_ptr, 
__node_ptr,

    const key_type&)): New.
    (_Hashtable<>::_M_merge_multi): Adapt to use latter.
    * include/bits/unordered_map.h 
(unordered_map<>::insert(node_type&&)): Pass cend as

    hint.
    (unordered_map<>::insert(const_iterator, node_type&&)): 
Adapt to use hint.
    * include/bits/unordered_set.h 
(unordered_set<>::insert(node_type&&)): Pass cend as

    hint.
    (unordered_set<>::insert(const_iterator, node_type&&)): 
Adapt to use hint.
    * 
testsuite/23_containers/unordered_multimap/insert/hint.cc: Adapt 
implementation

    specific tests.

Tested under linux x86_64.

Here is the performance results of this patch, before:

unordered_multiset_hint.cc-thread    hash code NOT cached 200 
insertions w/o hint      94r   94u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code NOT cached 200 
insertions with perfect hint      95r   94u    0s 191999712mem 0pf
unordered_multiset_hint.cc-thread    hash code NOT cached 200 
insertions with bad hint      94r   94u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code NOT cached 200 
range insertions      88r   88u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code cached 200 
insertions w/o hint      91r   91u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code cached 200 
insertions with perfect hint      92r   93u    0s 191999712mem 0pf
unordered_multiset_hint.cc-thread    hash code cached 200 
insertions with bad hint      93r   93u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code cached 200 range 
insertions      88r   88u    0s 191999712mem    0pf
unordered_set_hint.cc-thread    hash code NOT cached 200 
insertions w/o hint      

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-24 Thread François Dumont via Gcc-patches

I've now prepared the patch to support following config:

--disable-libstdcxx-dual-abi --with-default-libstdcxx-abi=new

and so detected yet another problem with src/c++98/compatibility.cc. We 
need basic_istream<>::ignore(streamsize) definitions that rely here but 
not the rest of it.


François

On 17/08/2023 19:17, François Dumont wrote:


Another fix to define __cow_string(const std::string&) in 
cxx11-stdexcept.cc even if ! _GLIBCXX_USE_DUAL_ABI.


On 13/08/2023 21:51, François Dumont wrote:


Here is another version with enhanced sizeof/alignof static_assert in 
string-inst.cc for the std::__cow_string definition from . 
The assertions in cow-stdexcept.cc are now checking the definition 
which is in the same file.


On 13/08/2023 15:27, François Dumont wrote:


Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted 
to let you know that I tried to put COW std::basic_string into a 
nested __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more 
impact on string-inst.cc so I preferred the macro substitution approach.


There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
unrelated with my changes. I'll propose fixes in coming days.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode. To do 
support
    a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.


    The main change is that std::__cow_string is now defined 
whenever _GLIBCXX_USE_DUAL_ABI
    or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in

    case of dual abi and a subset of it when it's not.

    On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
    and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
std::__sso_string is a typedef for the
    cow std::string implementation when dual abi is disabled and cow 
string is being used.


    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
Default to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
[!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define 
empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move 
cow-local_init.cc, cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
    including . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that

    __cow_string definition in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
    Move static_assert to check std::_cow_string abi layout 
to...

    * src/c++11/string-inst.cc: 

[PATCH][_GLIBCXX_INLINE_VERSION] Fix friend declarations

2023-08-23 Thread François Dumont via Gcc-patches

Hi

The few tests that are failing in versioned namespace mode are due to 
those friend declarations.


This is a fix proposal even if I considered 2 other options:

1. Make __format::_Arg_store a struct and so do not bother with friend 
declarations.


2. Consider it as a compiler bug and do nothing. In this case I think we 
might still need this patch to avoid a non-working format library in 
versioned namespace mode in gcc 14 if compiler bug is not fixed.


I can also define _GLIBCXX_STD_V at  level to limit impact.

    libstdc++: [_GLIBCXX_INLINE_VERSION] Fix  friend declarations

    GCC do not consider the inline namespace in friend declarations. We 
need

    to explicit this namespace.

    libstdc++-v3/ChangeLog:

    * include/bits/c++config (_GLIBCXX_STD_V): New macro giving 
current

    std namespace with optionally the version namespace.
    * include/std/format (std::__format::_Arg_store): Use 
latter on friend

    declarations.

Tested under versioned mode.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 0a41cdd29a9..a917fb58225 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -449,6 +449,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
 // of some nested namespace within it corresponding to the active mode.
 // _GLIBCXX_STD_A
 // _GLIBCXX_STD_C
+// _GLIBCXX_STD_V
 //
 // Macros for opening/closing conditional namespaces.
 // _GLIBCXX_BEGIN_NAMESPACE_ALGO
@@ -477,6 +478,12 @@ _GLIBCXX_END_NAMESPACE_VERSION
 # define _GLIBCXX_END_NAMESPACE_ALGO
 #endif
 
+#if _GLIBCXX_INLINE_VERSION
+# define _GLIBCXX_STD_V std::__8
+#else
+# define _GLIBCXX_STD_V std
+#endif
+
 // GLIBCXX_ABI Deprecated
 // Define if compatibility should be provided for -mlong-double-64.
 #undef _GLIBCXX_LONG_DOUBLE_COMPAT
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index f3d9ae152f9..94417c321e4 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3429,11 +3429,11 @@ namespace __format
   template
 class __format::_Arg_store
 {
-  friend std::basic_format_args<_Context>;
+  friend _GLIBCXX_STD_V::basic_format_args<_Context>;
 
   template
 	friend auto
-	std::make_format_args(_Argz&&...) noexcept;
+	_GLIBCXX_STD_V::make_format_args(_Argz&&...) noexcept;
 
   // For a sufficiently small number of arguments we only store values.
   // basic_format_args can get the types from the _Args pack.


Re: [PATCH] Fix tests sensitive to internal library allocations

2023-08-23 Thread François Dumont via Gcc-patches



On 21/08/2023 23:26, Jonathan Wakely wrote:

On Mon, 21 Aug 2023 at 21:20, François Dumont  wrote:

Here is the updated and tested patch.

OK for trunk, thanks.

We could consider it for the branches too (I'm going to remove the
global strings on the gcc-13 branch tomorrow).


It's not fixing anything so I don't think it worth it but let me know if 
you want me to do so.





Re: [PATCH] Fix tests sensitive to internal library allocations

2023-08-21 Thread François Dumont via Gcc-patches

Here is the updated and tested patch.

On 21/08/2023 20:07, Jonathan Wakely wrote:

On Mon, 21 Aug 2023 at 18:05, François Dumont via Libstdc++
 wrote:

Hi

Here is a propocal to fix tests sensitive to libstdc++ internal allocations.

Surely the enter() and exit() calls should be a constructor and destructor?

The constructor could use count() to get the count, and then restore
it in the destructor. Something like:

--- a/libstdc++-v3/testsuite/util/replacement_memory_operators.h
+++ b/libstdc++-v3/testsuite/util/replacement_memory_operators.h
@@ -75,12 +75,30 @@ namespace __gnu_test
   counter& cntr = get();
   cntr._M_increments = cntr._M_decrements = 0;
 }
+
+struct scope
+{
+  scope() : _M_count(counter::count()) { }
+  ~scope() { counter::get()._M_count = _M_count; }
+
+private:
+  std::size_t _M_count;
+
+#if __cplusplus >= 201103L
+  scope(const scope&) = delete;
+  scope& operator=(const scope&) = delete;
+#else
+  scope(const scope&);
+  scope& operator=(const scope&);
+#endif
+};
   };

   template
 bool
 check_new(Alloc a = Alloc())
 {
+  __gnu_test::counter::scope s;
   __gnu_test::counter::exceptions(false);
   __gnu_test::counter::reset();
   (void) a.allocate(10);







Tested by restoring allocation in tzdb.cc.

As announced I'm also adding a test to detect such allocations. If it is
ok let me know if you prefer to see it in a different place.

The test is a good idea. I think 17_intro/no_library_allocation.cc
would be a better place for it.


  libstdc++: Fix tests relying on operator new/delete overload

  Fix tests that are checking for an allocation plan. They are failing if
  an allocation is taking place outside the test.

  libstdc++-v3/ChangeLog

  * testsuite/util/replacement_memory_operators.h
  (counter::_M_pre_enter_count): New.
  (counter::enter, counter::exit): New static methods to call
on main() enter/exit.
  * testsuite/23_containers/unordered_map/96088.cc (main):
  Call __gnu_test::counter::enter/exit.
  * testsuite/23_containers/unordered_multimap/96088.cc
(main): Likewise.
  * testsuite/23_containers/unordered_multiset/96088.cc
(main): Likewise.
  * testsuite/23_containers/unordered_set/96088.cc (main):
Likewise.
  * testsuite/ext/malloc_allocator/deallocate_local.cc
(main): Likewise.
  * testsuite/ext/new_allocator/deallocate_local.cc (main):
Likewise.
  * testsuite/ext/throw_allocator/deallocate_local.cc (main):
Likewise.
  * testsuite/ext/pool_allocator/allocate_chunk.cc (started):
New global.
  (operator new(size_t)): Check started.
  (main): Set/Unset started.
  * testsuite/ext/no_library_allocation.cc: New test case.

Ok to commit ?

Françoisdiff --git a/libstdc++-v3/testsuite/17_intro/no_library_allocation.cc b/libstdc++-v3/testsuite/17_intro/no_library_allocation.cc
new file mode 100644
index 000..278d4757c93
--- /dev/null
+++ b/libstdc++-v3/testsuite/17_intro/no_library_allocation.cc
@@ -0,0 +1,8 @@
+#include 
+#include 
+
+int main()
+{
+  VERIFY( __gnu_test::counter::count() == 0 );
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
index c6d50c20fbf..cdf00c93d80 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
@@ -268,6 +268,7 @@ test03()
 int
 main()
 {
+  __gnu_test::counter::scope s;
   test01();
   test02();
   test11();
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
index 214bc91a559..d8b9a40c174 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
@@ -61,6 +61,7 @@ test02()
 int
 main()
 {
+  __gnu_test::counter::scope s;
   test01();
   test02();
   return 0;
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
index 838ce8d5bc5..db17cda0ddd 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
@@ -61,6 +61,7 @@ test02()
 int
 main()
 {
+  __gnu_test::counter::scope s;
   test01();
   test02();
   return 0;
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
index 0f7dce2b38c..831f2aa1210 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
@@ -269,6 +269,7 @@ test03()
 int
 main()
 {
+  __gnu_test::counter::scope s;
   test01();
   

[PATCH] Fix tests sensitive to internal library allocations

2023-08-21 Thread François Dumont via Gcc-patches

Hi

Here is a propocal to fix tests sensitive to libstdc++ internal allocations.

Tested by restoring allocation in tzdb.cc.

As announced I'm also adding a test to detect such allocations. If it is 
ok let me know if you prefer to see it in a different place.


    libstdc++: Fix tests relying on operator new/delete overload

    Fix tests that are checking for an allocation plan. They are failing if
    an allocation is taking place outside the test.

    libstdc++-v3/ChangeLog

    * testsuite/util/replacement_memory_operators.h
    (counter::_M_pre_enter_count): New.
    (counter::enter, counter::exit): New static methods to call 
on main() enter/exit.

    * testsuite/23_containers/unordered_map/96088.cc (main):
    Call __gnu_test::counter::enter/exit.
    * testsuite/23_containers/unordered_multimap/96088.cc 
(main): Likewise.
    * testsuite/23_containers/unordered_multiset/96088.cc 
(main): Likewise.
    * testsuite/23_containers/unordered_set/96088.cc (main): 
Likewise.
    * testsuite/ext/malloc_allocator/deallocate_local.cc 
(main): Likewise.
    * testsuite/ext/new_allocator/deallocate_local.cc (main): 
Likewise.
    * testsuite/ext/throw_allocator/deallocate_local.cc (main): 
Likewise.
    * testsuite/ext/pool_allocator/allocate_chunk.cc (started): 
New global.

    (operator new(size_t)): Check started.
    (main): Set/Unset started.
    * testsuite/ext/no_library_allocation.cc: New test case.

Ok to commit ?

François
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
index c6d50c20fbf..bcae891e5ec 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
@@ -268,6 +268,7 @@ test03()
 int
 main()
 {
+  __gnu_test::counter::enter();
   test01();
   test02();
   test11();
@@ -275,5 +276,6 @@ main()
   test21();
   test22();
   test03();
+  __gnu_test::counter::exit();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
index 214bc91a559..9f16ad68218 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
@@ -61,7 +61,9 @@ test02()
 int
 main()
 {
+  __gnu_test::counter::enter();
   test01();
   test02();
+  __gnu_test::counter::exit();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
index 838ce8d5bc5..b34cfe67092 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
@@ -61,7 +61,9 @@ test02()
 int
 main()
 {
+  __gnu_test::counter::enter();
   test01();
   test02();
+  __gnu_test::counter::exit();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
index 0f7dce2b38c..d5717fcec2b 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
@@ -269,6 +269,7 @@ test03()
 int
 main()
 {
+  __gnu_test::counter::enter();
   test01();
   test02();
   test11();
@@ -277,5 +278,6 @@ main()
   test22();
   test23();
   test03();
+  __gnu_test::counter::exit();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc
index 79b583bd716..3aa65f298b1 100644
--- a/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc
+++ b/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc
@@ -27,6 +27,7 @@ typedef std::basic_string string_t;
 
 int main()
 {
+  __gnu_test::counter::enter();
   {
 string_t s;
 s += "bayou bend";
@@ -34,5 +35,7 @@ int main()
 
   if (__gnu_test::counter::count() != 0)
 throw std::runtime_error("count not zero");
+
+  __gnu_test::counter::exit();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
index fcde46e6e10..ac4996698c7 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
@@ -27,6 +27,7 @@ typedef std::basic_string string_t;
 
 int main()
 {
+  __gnu_test::counter::enter();
   {
 string_t s;
 s += "bayou bend";
@@ -34,5 +35,7 @@ int main()
 
   if (__gnu_test::counter::count() != 0)
 throw std::runtime_error("count not zero");
+
+  __gnu_test::counter::exit();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/ext/no_library_allocation.cc b/libstdc++-v3/testsuite/ext/no_library_allocation.cc
new 

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-19 Thread François Dumont via Gcc-patches

Here is a rebased patch following the resize_and_overwrite change.

I confirm that tests are now fixed after the change in tzdb.cc.

I'll prepare a fix for those tests still but preparing also a test to 
detect allocations in the lib.


François

On 17/08/2023 21:44, Jonathan Wakely wrote:

On Thu, 17 Aug 2023 at 20:37, Jonathan Wakely  wrote:

On Thu, 17 Aug 2023 at 19:59, Jonathan Wakely  wrote:

On Thu, 17 Aug 2023 at 18:40, François Dumont  wrote:


On 17/08/2023 19:22, Jonathan Wakely wrote:

On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
 wrote:

Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted to
let you know that I tried to put COW std::basic_string into a nested
__cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
string-inst.cc so I preferred the macro substitution approach.

I was thinking of implementing the necessary special members functions
of __cow_string directly, so they are ABI compatible with the COW
std::basic_string but don't actually reuse the code. That would mean
we don't need to compile and instantiate the whole COW string just to
use a few members from it. But that can be done later, the macro
approach seems OK for now.

You'll see that when cow_string.h is included while
_GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the
basic_string definition. Initially it was to avoid to have to include
basic_string.tcc but it is also a lot of useless code indeed.



There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
unrelated with my changes. I'll propose fixes in coming days.

Which tests? I run the entire testsuite with
-D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
failures.

I'll review the patch ASAP, thanks for working on it.


So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI &&
!_GLIBCXX_USE_CXX11_ABI. They are:

23_containers/unordered_map/96088.cc
23_containers/unordered_multimap/96088.cc
23_containers/unordered_multiset/96088.cc
23_containers/unordered_set/96088.cc
ext/debug_allocator/check_new.cc
ext/malloc_allocator/check_new.cc
ext/malloc_allocator/deallocate_local.cc
ext/new_allocator/deallocate_local.cc
ext/pool_allocator/allocate_chunk.cc
ext/throw_allocator/deallocate_local.cc

Ah yes, they fail for !USE_DUAL_ABI builds, I wonder why.

/home/test/src/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/96088.
cc:44: void test01(): Assertion '__gnu_test::counter::count() == 3' failed.
FAIL: 23_containers/unordered_map/96088.cc execution test

It's due to this global object in src/c++20/tzdb.cc:
1081const string tzdata_file = "/tzdata.zi";

When the library uses COW strings that requires an allocation before
main, which uses the replacement operator new in the tests, which
fails to allocate. For example, in 22_locale/locale/cons/12352.cc we
have this function used by operator new:

int times_to_fail = 0;

void* allocate(std::size_t n)
{
   if (!times_to_fail--)
 return 0;

The counter is initially zero, so if we try to allocate before it gets
set to a non-zero value in test01() then we fail.

The test should not assume no allocations before main() begins. The
simplest way to do that is with another global that says "we have
started testing" e.g.

--- a/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12352.cc
@@ -26,11 +26,12 @@
  #include 
  #include 

+bool tests_started = false;
  int times_to_fail = 0;

  void* allocate(std::size_t n)
  {
-  if (!times_to_fail--)
+  if (tests_started && !times_to_fail--)
  return 0;

void* ret = std::malloc(n ? n : 1);
@@ -106,6 +107,8 @@ void operator delete[](void* p, const
std::nothrow_t&) throw()
  // libstdc++/12352
  void test01(int iters)
  {
+  tests_started = true;
+
for (int j = 0; j < iters; ++j)
  {
for (int i = 0; i < 100; ++i)


This way the replacement operator new doesn't start intentionally
failing until we ask it to do so.

I'll replace the global std::string objects with std::string_view
objects, so that they don't allocate even if the library only uses COW
strings.

We should still fix those tests though.
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index b25378eaace..322f1e42611 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -4875,12 +4875,16 @@ dnl
 AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [
   GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string])
   if test x$enable_symvers = xgnu-versioned-namespace; then
-# gnu-versioned-namespace is incompatible with the dual ABI.
-enable_libstdcxx_dual_abi="no"
-  fi
-  if test x"$enable_libstdcxx_dual_abi" != xyes; then
+# gnu-versioned-namespace is incompatible with the dual ABI...
 

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-17 Thread François Dumont via Gcc-patches



On 17/08/2023 19:22, Jonathan Wakely wrote:

On Sun, 13 Aug 2023 at 14:27, François Dumont via Libstdc++
 wrote:

Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted to
let you know that I tried to put COW std::basic_string into a nested
__cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on
string-inst.cc so I preferred the macro substitution approach.

I was thinking of implementing the necessary special members functions
of __cow_string directly, so they are ABI compatible with the COW
std::basic_string but don't actually reuse the code. That would mean
we don't need to compile and instantiate the whole COW string just to
use a few members from it. But that can be done later, the macro
approach seems OK for now.


You'll see that when cow_string.h is included while 
_GLIBCXX_USE_CXX11_ABI == 1 then I am hiding a big part of the 
basic_string definition. Initially it was to avoid to have to include 
basic_string.tcc but it is also a lot of useless code indeed.






There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are
unrelated with my changes. I'll propose fixes in coming days.

Which tests? I run the entire testsuite with
-D_GLIBCXX_USE_CXX11_ABI=0 several times per day and I'm not seeing
failures.

I'll review the patch ASAP, thanks for working on it.

So far the only issue I found are in the mode !_GLIBCXX_USE_DUAL_ABI && 
!_GLIBCXX_USE_CXX11_ABI. They are:


23_containers/unordered_map/96088.cc
23_containers/unordered_multimap/96088.cc
23_containers/unordered_multiset/96088.cc
23_containers/unordered_set/96088.cc
ext/debug_allocator/check_new.cc
ext/malloc_allocator/check_new.cc
ext/malloc_allocator/deallocate_local.cc
ext/new_allocator/deallocate_local.cc
ext/pool_allocator/allocate_chunk.cc
ext/throw_allocator/deallocate_local.cc

but not sure I'll try to fix those in this context.

François



Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-17 Thread François Dumont via Gcc-patches
Another fix to define __cow_string(const std::string&) in 
cxx11-stdexcept.cc even if ! _GLIBCXX_USE_DUAL_ABI.


On 13/08/2023 21:51, François Dumont wrote:


Here is another version with enhanced sizeof/alignof static_assert in 
string-inst.cc for the std::__cow_string definition from . 
The assertions in cow-stdexcept.cc are now checking the definition 
which is in the same file.


On 13/08/2023 15:27, François Dumont wrote:


Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted 
to let you know that I tried to put COW std::basic_string into a 
nested __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more 
impact on string-inst.cc so I preferred the macro substitution approach.


There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
unrelated with my changes. I'll propose fixes in coming days.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode. To do support
    a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.


    The main change is that std::__cow_string is now defined whenever 
_GLIBCXX_USE_DUAL_ABI
    or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in

    case of dual abi and a subset of it when it's not.

    On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
    and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
std::__sso_string is a typedef for the
    cow std::string implementation when dual abi is disabled and cow 
string is being used.


    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
Default to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
[!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
    including . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that

    __cow_string definition in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.

    Move static_assert to check std::_cow_string abi layout to...
    * src/c++11/string-inst.cc: ...here.
    (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
following _GLIBCXX_USE_CXX11_ABI

    value.
    [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
    Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
Include .
    Define basic_string as __std_cow_string for the 

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-13 Thread François Dumont via Gcc-patches
Here is another version with enhanced sizeof/alignof static_assert in 
string-inst.cc for the std::__cow_string definition from . 
The assertions in cow-stdexcept.cc are now checking the definition which 
is in the same file.


On 13/08/2023 15:27, François Dumont wrote:


Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted 
to let you know that I tried to put COW std::basic_string into a 
nested __cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more 
impact on string-inst.cc so I preferred the macro substitution approach.


There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
unrelated with my changes. I'll propose fixes in coming days.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode. To do support
    a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.


    The main change is that std::__cow_string is now defined whenever 
_GLIBCXX_USE_DUAL_ABI
    or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in

    case of dual abi and a subset of it when it's not.

    On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
    and _GLIBCXX_USE_CXX11_ABI is false. Meaning that 
std::__sso_string is a typedef for the
    cow std::string implementation when dual abi is disabled and cow 
string is being used.


    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
Default to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
    including . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that

    __cow_string definition in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.

    Move static_assert to check std::_cow_string abi layout to...
    * src/c++11/string-inst.cc: ...here.
    (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
following _GLIBCXX_USE_CXX11_ABI

    value.
    [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
    Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. 
Include .
    Define basic_string as __std_cow_string for the current 
translation unit.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * 

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-13 Thread François Dumont via Gcc-patches

Here is the fixed patch tested in all 3 modes:

- _GLIBCXX_USE_DUAL_ABI

- !_GLIBCXX_USE_DUAL_ABI && !_GLIBCXX_USE_CXX11_ABI

- !_GLIBCXX_USE_DUAL_ABI && _GLIBCXX_USE_CXX11_ABI

I don't know what you have in mind for the change below but I wanted to 
let you know that I tried to put COW std::basic_string into a nested 
__cow namespace when _GLIBCXX_USE_CXX11_ABI. But it had more impact on 
string-inst.cc so I preferred the macro substitution approach.


There are some test failing when !_GLIBCXX_USE_CXX11_ABI that are 
unrelated with my changes. I'll propose fixes in coming days.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode. To do support
    a new configuration mode where !_GLIBCXX_USE_DUAL_ABI and 
_GLIBCXX_USE_CXX11_ABI.


    The main change is that std::__cow_string is now defined whenever 
_GLIBCXX_USE_DUAL_ABI
    or _GLIBCXX_USE_CXX11_ABI is true. Implementation is using 
available std::string in

    case of dual abi and a subset of it when it's not.

    On the other side std::__sso_string is defined only when 
_GLIBCXX_USE_DUAL_ABI is true
    and _GLIBCXX_USE_CXX11_ABI is false. Meaning that std::__sso_string 
is a typedef for the
    cow std::string implementation when dual abi is disabled and cow 
string is being used.


    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default 
to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before
    including . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that

    __cow_string definition in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.

    Move static_assert to check std::_cow_string abi layout to...
    * src/c++11/string-inst.cc: ...here.
    (_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS): Define 
following _GLIBCXX_USE_CXX11_ABI

    value.
    [_GLIBCXX_USE_CXX11_ABI && 
!_GLIBCXX_DEFINING_CXX11_ABI_INSTANTIATIONS]:
    Define _GLIBCXX_DEFINING_COW_STRING_INSTANTIATIONS. Include 
.
    Define basic_string as __std_cow_string for the current 
translation unit.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * 

Re: [PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-10 Thread François Dumont via Gcc-patches
I hadn't tested the most basic default configuration and it is failing, 
I need some more time yet.


François


On 10/08/2023 07:13, François Dumont wrote:

Hi

I've eventually completed this work.

This evolution will allow to build libstdc++ without dual abi and 
using cxx11 abi. For the moment such a config is only accessible 
through the --enable-symvers=gnu-versioned-namespace configuration.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode.

    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
Default to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
    . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string definition

    in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-string-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cxx11-ios_failure.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.

    [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
    * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
    * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.

    * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet>, 
std::use_facet>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet>, 
std::has_facet>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_getistreambuf_iterator>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_putostreambuf_iterator>): Instantiate.
    * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured

    _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.

    [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct): Instantiate.
    

[PATCH] sso-string@gnu-versioned-namespace [PR83077]

2023-08-09 Thread François Dumont via Gcc-patches

Hi

I've eventually completed this work.

This evolution will allow to build libstdc++ without dual abi and using 
cxx11 abi. For the moment such a config is only accessible through the 
--enable-symvers=gnu-versioned-namespace configuration.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi [PR83077]

    Use cxx11 abi when activating versioned namespace mode.

    libstdcxx-v3/ChangeLog:

    PR libstdc++/83077
    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default 
to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11):

    Define empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG):

    Likewise.
    * include/bits/cow_string.h [!_GLIBCXX_USE_CXX11_ABI]: 
Define a light version of COW

    basic_string as __std_cow_string for use in stdexcept.
    * include/std/stdexcept [_GLIBCXX_USE_CXX11_ABI]: Define 
__cow_string.

    (__cow_string(const char*)): New.
    (__cow_string::c_str()): New.
    * python/libstdcxx/v6/printers.py 
(StdStringPrinter::__init__): Set self.new_string to True

    when std::__8::basic_string type is found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this. Also move cow-local_init.cc, 
cxx11-hash_tr1.cc,

    cxx11-ios_failure.cc entries to...
    (sources): ...this.
    (extra_string_inst_sources): Move cow-fstream-inst.cc, 
cow-sstream-inst.cc, cow-string-inst.cc,
    cow-string-io-inst.cc, cow-wtring-inst.cc, 
cow-wstring-io-inst.cc, cxx11-locale-inst.cc,

    cxx11-wlocale-inst.cc entries to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc [_GLIBCXX_USE_CXX11_ABI]: 
Include .
    [_GLIBCXX_USE_DUAL_ABI || 
_GLIBCXX_USE_CXX11_ABI](__cow_string): Redefine before including
    . Define 
_GLIBCXX_DEFINE_STDEXCEPT_INSTANTIATIONS so that __cow_string definition

    in  is skipped.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.

    [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
    * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
    * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.

    * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet>, 
std::use_facet>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet>, 
std::has_facet>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_getistreambuf_iterator>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_putostreambuf_iterator>): Instantiate.
    * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured

    _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.

    [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](time_putostreambuf_iterator>): Instantiate.
    

[committed][_GLIBCXX_INLINE_VERSION] Add __cxa_call_terminate symbol export

2023-08-06 Thread François Dumont via Gcc-patches

libstdc++: [_GLIBCXX_INLINE_VERSION] Add __cxa_call_terminate symbol export

libstdc++-v3/ChangeLog:

    * config/abi/pre/gnu-versioned-namespace.ver: Add __cxa_call_terminate
    symbol export.
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index d7ef127cf02..267ab8fc719 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -164,6 +164,7 @@ CXXABI_2.0 {
 __cxa_begin_catch;
 __cxa_begin_cleanup;
 __cxa_call_unexpected;
+__cxa_call_terminate;
 __cxa_current_exception_type;
 __cxa_deleted_virtual;
 __cxa_demangle;


[committed] Fix several preprocessor directives

2023-07-30 Thread François Dumont via Gcc-patches

Committed as obvious.

    libstdc++: Fix several preprocessor directives

    A wrong usage of #define in place of a #error seems to have been 
replicated

    at different places in source files.

    libstdc++-v3/ChangeLog:

    * src/c++11/compatibility-ldbl-facets-aliases.h: Replace 
#define with

    proper #error.
    * src/c++11/locale-inst-monetary.h: Likewise.
    * src/c++11/locale-inst-numeric.h: Likewise.

François
diff --git a/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h b/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
index 70c9342d88a..faf8221b273 100644
--- a/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
+++ b/libstdc++-v3/src/c++11/compatibility-ldbl-facets-aliases.h
@@ -23,11 +23,11 @@
 // .
 
 #ifndef C
-#define "This file should not be compiled directly, only included"
+# error "This file should not be compiled directly, only included"
 #endif
 
 #ifndef _GLIBCXX_LONG_DOUBLE_COMPAT
-#define "This file should only be used for _GLIBCXX_LONG_DOUBLE_COMPAT builds"
+# error "This file should only be used for _GLIBCXX_LONG_DOUBLE_COMPAT builds"
 #endif
 
 // XXX GLIBCXX_ABI Deprecated
diff --git a/libstdc++-v3/src/c++11/locale-inst-monetary.h b/libstdc++-v3/src/c++11/locale-inst-monetary.h
index d8fecf26596..954de1f52cf 100644
--- a/libstdc++-v3/src/c++11/locale-inst-monetary.h
+++ b/libstdc++-v3/src/c++11/locale-inst-monetary.h
@@ -23,7 +23,7 @@
 // .
 
 #ifndef C
-#define "This file should not be compiled directly, only included"
+# error "This file should not be compiled directly, only included"
 #endif
 
 #include "facet_inst_macros.h"
diff --git a/libstdc++-v3/src/c++11/locale-inst-numeric.h b/libstdc++-v3/src/c++11/locale-inst-numeric.h
index c77ee9e8d38..b917fe5802e 100644
--- a/libstdc++-v3/src/c++11/locale-inst-numeric.h
+++ b/libstdc++-v3/src/c++11/locale-inst-numeric.h
@@ -23,7 +23,7 @@
 // .
 
 #ifndef C
-#define "This file should not be compiled directly, only included"
+# error "This file should not be compiled directly, only included"
 #endif
 
 #include "facet_inst_macros.h"


[PATCH][Hashtable] Performance optimization through use of insertion hint

2023-07-24 Thread François Dumont via Gcc-patches

    libstdc++: [_Hashtable] Make more use of insertion hint


    When inserting an element into an empty bucket we currently insert 
the new node
    after the before-begin node so in first position. The drawback of 
doing this is
    that we are forced to update the bucket that was containing this 
before-begin
    node to point to the newly inserted node. To do so we need at best 
to do a modulo

    to find this bucket and when hash code is not cached also compute it.

    To avoid this side effect it is better to insert after the last 
node. Adding
    a member to keep track of this last node would be an abi breaking 
change. Still we
    can ask the user to maintain and provide this last node as an 
insertion hint.


    Adapt range insertion methods to try to detect the last node and 
then use it as

    the insertion hint.

    libstdc++-v3/ChangeLog:

    * include/bits/hashtable_policy.h:
    (_Insert_base::try_emplace): Adapt to use hint.
    (_Insert_base::_M_insert_range): Try to detect container 
last node and use it

    as hint for insertions.
    (_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
    (_Hashtable<>::_M_insert_bucket_begin): Add hint parameter 
and use it when inserting

    into an empty bucket if hint is the last container node.
    (_Hashtable<>::_InsertInfo): New struct.
    (_Hashtable<>::_M_get_insert_info): New, return latter.
    (_Hashtable<>::_M_insert_multi_node): Add _InsertInfo 
parameter.
    (_Hashtable<>::_M_insert_unique_node): Add __node_ptr hint 
parameter.

    (_Hashtable<>::_M_emplace_unique(__node_ptr, _Args&&...)): New.
    (_Hashtable<>::_M_emplace_multi(__node_ptr, _Args&&...)): New.
    (_Hashtable<>::_M_emplace()): Adapt to use latters.
    (_Hashtable<>::_M_insert_unique): Add __node_ptr parameter.
    (_Hashtable<>::_M_insert_unique_aux): Add __node_ptr parameter.
    (_Hashtable<>::_M_insert(__node_ptr, _Arg&&, const 
_NodeGenerator&, true_type)):

    Use latter.
    (_Hashtable<>::_M_reinsert_node(const_iterator, node_type&&)):
    Add hint parameter, adapt to use it.
    (_Hashtable<>::_M_reinsert_node_multi): Use hint parameter 
if available to extract

    hash code.
    (_Hashtable<>::_M_compute_hash_code(const _Hash&, 
__node_ptr, __node_ptr,

    const key_type&)): New.
(_Hashtable<>::_M_compute_hash_code<_H2>(const _H2&, __node_ptr, __node_ptr,
    const key_type&)): New.
    (_Hashtable<>::_M_merge_unique): Adapt to use latter. 
Implement small size

    optimization.
    (_Hashtable<>::_M_get_insert_info(const _Hash&, __node_ptr, 
__node_ptr,

    const key_type&)): New.
(_Hashtable<>::_M_get_insert_info<_H2>(const _H2&, __node_ptr, __node_ptr,
    const key_type&)): New.
    (_Hashtable<>::_M_merge_multi): Adapt to use latter.
    * include/bits/unordered_map.h 
(unordered_map<>::insert(node_type&&)): Pass cend as

    hint.
    (unordered_map<>::insert(const_iterator, node_type&&)): 
Adapt to use hint.
    * include/bits/unordered_set.h 
(unordered_set<>::insert(node_type&&)): Pass cend as

    hint.
    (unordered_set<>::insert(const_iterator, node_type&&)): 
Adapt to use hint.
    * 
testsuite/23_containers/unordered_multimap/insert/hint.cc: Adapt 
implementation

    specific tests.

Tested under linux x86_64.

Here is the performance results of this patch, before:

unordered_multiset_hint.cc-thread    hash code NOT cached 200 
insertions w/o hint      94r   94u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code NOT cached 200 
insertions with perfect hint      95r   94u    0s 191999712mem 0pf
unordered_multiset_hint.cc-thread    hash code NOT cached 200 
insertions with bad hint      94r   94u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code NOT cached 200 range 
insertions      88r   88u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code cached 200 insertions 
w/o hint      91r   91u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code cached 200 insertions 
with perfect hint      92r   93u    0s 191999712mem 0pf
unordered_multiset_hint.cc-thread    hash code cached 200 insertions 
with bad hint      93r   93u    0s 191999712mem    0pf
unordered_multiset_hint.cc-thread    hash code cached 200 range 
insertions      88r   88u    0s 191999712mem    0pf
unordered_set_hint.cc-thread    hash code NOT cached 200 insertions 
w/o hint      94r   95u    0s 191999712mem    0pf
unordered_set_hint.cc-thread    hash code NOT cached 200 

Re: [PATCH v3 1/3] c++, libstdc++: Implement __is_arithmetic built-in trait

2023-07-22 Thread François Dumont via Gcc-patches



On 18/07/2023 08:27, Ken Matsui via Libstdc++ wrote:

This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_arithmetic.
* g++.dg/ext/is_arithmetic.C: New test.
* g++.dg/tm/pr46567.C (__is_arithmetic): Rename to ...
(__is_arith): ... this.
* g++.dg/torture/pr57107.C: Likewise.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_arithmetic): Rename to ...
(__is_arith): ... this.
* include/c_global/cmath: Use __is_arith instead.
* include/c_std/cmath: Likewise.
* include/tr1/cmath: Likewise.

Signed-off-by: Ken Matsui 
---
  gcc/cp/constraint.cc|  3 ++
  gcc/cp/cp-trait.def |  1 +
  gcc/cp/semantics.cc |  4 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 ++
  gcc/testsuite/g++.dg/ext/is_arithmetic.C| 33 ++
  gcc/testsuite/g++.dg/tm/pr46567.C   |  6 +--
  gcc/testsuite/g++.dg/torture/pr57107.C  |  4 +-
  libstdc++-v3/include/bits/cpp_type_traits.h |  4 +-
  libstdc++-v3/include/c_global/cmath | 48 ++---
  libstdc++-v3/include/c_std/cmath| 24 +--
  libstdc++-v3/include/tr1/cmath  | 24 +--
  11 files changed, 99 insertions(+), 55 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 8cf0f2d0974..bd517d08843 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3754,6 +3754,9 @@ diagnose_trait_expr (tree expr, tree args)
  case CPTK_IS_AGGREGATE:
inform (loc, "  %qT is not an aggregate", t1);
break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
  case CPTK_IS_TRIVIALLY_COPYABLE:
inform (loc, "  %qT is not trivially copyable", t1);
break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..a95aeeaf778 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, 
"__is_trivially_assignable", 2)
  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
  DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
  DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
  DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
  /* FIXME Added space to avoid direct usage in GCC 13.  */
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..4531f047d73 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12118,6 +12118,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_UNION:
return type_code1 == UNION_TYPE;
  
+case CPTK_IS_ARITHMETIC:

+  return ARITHMETIC_TYPE_P (type1);
+
  case CPTK_IS_ASSIGNABLE:
return is_xible (MODIFY_EXPR, type1, type2);
  
@@ -12296,6 +12299,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_ENUM:
  case CPTK_IS_UNION:
  case CPTK_IS_SAME:
+case CPTK_IS_ARITHMETIC:
break;
  
  case CPTK_IS_LAYOUT_COMPATIBLE:

diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..3d63b0101d1 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
  #if !__has_builtin (__remove_cvref)
  # error "__has_builtin (__remove_cvref) failed"
  #endif
+#if !__has_builtin (__is_arithmetic)
+# error "__has_builtin (__is_arithmetic) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_arithmetic.C 
b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
new file mode 100644
index 000..fd35831f646
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_arithmetic, void, false);
+
+SA_TEST_CATEGORY(__is_arithmetic, char, true);
+SA_TEST_CATEGORY(__is_arithmetic, signed char, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned char, true);

Re: [PATCH v2 3/3] libstdc++: Optimize is_fundamental performance by __is_arithmetic built-in

2023-07-22 Thread François Dumont via Gcc-patches
It seems rather logical cause std::disjunction is supposed to avoid 
instantiations but in case of:


std::disjunction, std::is_null_pointer<_Tp>>

you'll avoid std::is_null_pointer instantiation only for 'void' type and 
at the price of instantiating std::disjunction so 2 instantiations at 
best but most of the time 3, clearly useless here.


On 18/07/2023 08:24, Ken Matsui wrote:

Hi,

I took a benchmark for this.

https://github.com/ken-matsui/gcc-benches/blob/main/is_fundamental-disjunction.md#mon-jul-17-105937-pm-pdt-2023

template
struct is_fundamental
: public std::bool_constant<__is_arithmetic(_Tp)
 || std::is_void<_Tp>::value
 || std::is_null_pointer<_Tp>::value>
{ };

is faster than:

template
struct is_fundamental
: public std::bool_constant<__is_arithmetic(_Tp)
 || std::disjunction,
 std::is_null_pointer<_Tp>
 >::value>
{ };

Time: -32.2871%
Peak Memory: -18.5071%
Total Memory: -20.1991%

Sincerely,
Ken Matsui

On Sun, Jul 16, 2023 at 9:49 PM Ken Matsui  wrote:

On Sun, Jul 16, 2023 at 5:41 AM François Dumont  wrote:


On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote:

This patch optimizes the performance of the is_fundamental trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

   * include/std/type_traits (is_fundamental_v): Use __is_arithmetic
   built-in trait.
   (is_fundamental): Likewise. Optimize the original implementation.

Signed-off-by: Ken Matsui 
---
   libstdc++-v3/include/std/type_traits | 21 +
   1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7ebbe04c77b..cf24de2fcac 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -668,11 +668,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   #endif

 /// is_fundamental
+#if __has_builtin(__is_arithmetic)
+  template
+struct is_fundamental
+: public __bool_constant<__is_arithmetic(_Tp)
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
+{ };

What about doing this ?

template
  struct is_fundamental
  : public __bool_constant<__is_arithmetic(_Tp)
   || __or_,
   is_null_pointer<_Tp>>::value>
  { };

Based on your benches it seems that builtin __is_arithmetic is much better that 
std::is_arithmetic. But __or_ could still avoid instantiation of 
is_null_pointer.


Let me take a benchmark for this later.


Re: [PATCH v2 2/3] libstdc++: Optimize is_arithmetic performance by __is_arithmetic built-in

2023-07-22 Thread François Dumont via Gcc-patches



On 17/07/2023 06:48, Ken Matsui wrote:

On Sun, Jul 16, 2023 at 5:32 AM François Dumont  wrote:


On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote:

This patch optimizes the performance of the is_arithmetic trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

   * include/std/type_traits (is_arithmetic): Use __is_arithmetic
   built-in trait.
   (is_arithmetic_v): Likewise.

Signed-off-by: Ken Matsui 
---
   libstdc++-v3/include/std/type_traits | 14 ++
   1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 0e7a9c9c7f3..7ebbe04c77b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -655,10 +655,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { };

 /// is_arithmetic
+#if __has_builtin(__is_arithmetic)
+  template
+struct is_arithmetic
+: public __bool_constant<__is_arithmetic(_Tp)>
+{ };
+#else
 template
   struct is_arithmetic
   : public __or_, is_floating_point<_Tp>>::type
   { };
+#endif

 /// is_fundamental
 template
@@ -3198,8 +3205,15 @@ template 
 inline constexpr bool is_reference_v<_Tp&> = true;
   template 
 inline constexpr bool is_reference_v<_Tp&&> = true;
+
+#if __has_builtin(__is_arithmetic)
+template 
+  inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+#else
   template 
 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
   template 
 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
   template 

Same remark as the one I did for __is_pointer in cpp_type_traits.h. You
could implement it as:

template
  struct __is_arithmetic_t
  : public __truth_type<__is_arithmetic(_Tp)>
  { };

François


Thank you for your review! This is from the type_traits header, so the
name should be as-is.


Here I meant that current libstdc++ implementation of 
std::__is_arithmetic in cpp_type_traits.h should also make use of the 
builtin __is_arithmetic that you are introducing. That is to say replace 
this:


  template
    struct __is_arithmetic
    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
    { };

by:

#if __has_builtin(__is_arithmetic)

  template
    struct __is_arithmetic_t
    : public __truth_type<__is_arithmetic<_Tp>>
    { };

#else

  template
    struct __is_arithmetic_t
    : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
    { };

#endif

if you replace '__is_arithmetic' by '__is_arithmetic_t' for the 
libstdc++, just adapt to the name you eventually adopt.





Re: [PATCH v2 3/3] libstdc++: Optimize is_fundamental performance by __is_arithmetic built-in

2023-07-16 Thread François Dumont via Gcc-patches



On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote:

This patch optimizes the performance of the is_fundamental trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_fundamental_v): Use __is_arithmetic
built-in trait.
(is_fundamental): Likewise. Optimize the original implementation.

Signed-off-by: Ken Matsui 
---
  libstdc++-v3/include/std/type_traits | 21 +
  1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7ebbe04c77b..cf24de2fcac 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -668,11 +668,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  #endif
  
/// is_fundamental

+#if __has_builtin(__is_arithmetic)
+  template
+struct is_fundamental
+: public __bool_constant<__is_arithmetic(_Tp)
+ || is_void<_Tp>::value
+ || is_null_pointer<_Tp>::value>
+{ };


What about doing this ?

  template
struct is_fundamental
: public __bool_constant<__is_arithmetic(_Tp)
 || __or_,
  is_null_pointer<_Tp>>::value>
{ };

Based on your benches it seems that builtin __is_arithmetic is much better that 
std::is_arithmetic. But __or_ could still avoid instantiation of 
is_null_pointer.



Re: [PATCH v2 2/3] libstdc++: Optimize is_arithmetic performance by __is_arithmetic built-in

2023-07-16 Thread François Dumont via Gcc-patches



On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote:

This patch optimizes the performance of the is_arithmetic trait by
dispatching to the new __is_arithmetic built-in trait.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_arithmetic): Use __is_arithmetic
built-in trait.
(is_arithmetic_v): Likewise.

Signed-off-by: Ken Matsui 
---
  libstdc++-v3/include/std/type_traits | 14 ++
  1 file changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 0e7a9c9c7f3..7ebbe04c77b 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -655,10 +655,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  { };
  
/// is_arithmetic

+#if __has_builtin(__is_arithmetic)
+  template
+struct is_arithmetic
+: public __bool_constant<__is_arithmetic(_Tp)>
+{ };
+#else
template
  struct is_arithmetic
  : public __or_, is_floating_point<_Tp>>::type
  { };
+#endif
  
/// is_fundamental

template
@@ -3198,8 +3205,15 @@ template 
inline constexpr bool is_reference_v<_Tp&> = true;
  template 
inline constexpr bool is_reference_v<_Tp&&> = true;
+
+#if __has_builtin(__is_arithmetic)
+template 
+  inline constexpr bool is_arithmetic_v = __is_arithmetic(_Tp);
+#else
  template 
inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
+#endif
+
  template 
inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
  template 


Same remark as the one I did for __is_pointer in cpp_type_traits.h. You 
could implement it as:


  template
    struct __is_arithmetic_t
    : public __truth_type<__is_arithmetic(_Tp)>
    { };

François




Re: [PATCH v2 1/3] c++, libstdc++: Implement __is_arithmetic built-in trait

2023-07-16 Thread François Dumont via Gcc-patches



On 15/07/2023 06:55, Ken Matsui via Libstdc++ wrote:

This patch implements built-in trait for std::is_arithmetic.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_arithmetic.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_arithmetic.
* g++.dg/ext/is_arithmetic.C: New test.
* g++.dg/tm/pr46567.C (__is_arithmetic): Rename to ...
(is_arithmetic): ... this.
* g++.dg/torture/pr57107.C: Likewise.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_arithmetic): Rename to ...
(is_arithmetic): ... this.
* include/c_global/cmath: Use is_arithmetic instead.
* include/c_std/cmath: Likewise.
* include/tr1/cmath: Likewise.

Signed-off-by: Ken Matsui 
---
  gcc/cp/constraint.cc|  3 ++
  gcc/cp/cp-trait.def |  1 +
  gcc/cp/semantics.cc |  4 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 ++
  gcc/testsuite/g++.dg/ext/is_arithmetic.C| 33 ++
  gcc/testsuite/g++.dg/tm/pr46567.C   |  6 +--
  gcc/testsuite/g++.dg/torture/pr57107.C  |  4 +-
  libstdc++-v3/include/bits/cpp_type_traits.h |  4 +-
  libstdc++-v3/include/c_global/cmath | 48 ++---
  libstdc++-v3/include/c_std/cmath| 24 +--
  libstdc++-v3/include/tr1/cmath  | 24 +--
  11 files changed, 99 insertions(+), 55 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 8cf0f2d0974..bd517d08843 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3754,6 +3754,9 @@ diagnose_trait_expr (tree expr, tree args)
  case CPTK_IS_AGGREGATE:
inform (loc, "  %qT is not an aggregate", t1);
break;
+case CPTK_IS_ARITHMETIC:
+  inform (loc, "  %qT is not an arithmetic type", t1);
+  break;
  case CPTK_IS_TRIVIALLY_COPYABLE:
inform (loc, "  %qT is not trivially copyable", t1);
break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..a95aeeaf778 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, 
"__is_trivially_assignable", 2)
  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
  DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
  DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (IS_ARITHMETIC, "__is_arithmetic", 1)
  DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
  /* FIXME Added space to avoid direct usage in GCC 13.  */
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..4531f047d73 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12118,6 +12118,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_UNION:
return type_code1 == UNION_TYPE;
  
+case CPTK_IS_ARITHMETIC:

+  return ARITHMETIC_TYPE_P (type1);
+
  case CPTK_IS_ASSIGNABLE:
return is_xible (MODIFY_EXPR, type1, type2);
  
@@ -12296,6 +12299,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_ENUM:
  case CPTK_IS_UNION:
  case CPTK_IS_SAME:
+case CPTK_IS_ARITHMETIC:
break;
  
  case CPTK_IS_LAYOUT_COMPATIBLE:

diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..3d63b0101d1 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
  #if !__has_builtin (__remove_cvref)
  # error "__has_builtin (__remove_cvref) failed"
  #endif
+#if !__has_builtin (__is_arithmetic)
+# error "__has_builtin (__is_arithmetic) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_arithmetic.C 
b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
new file mode 100644
index 000..fd35831f646
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT)  \
+  SA(TRAIT(TYPE) == EXPECT);   \
+  SA(TRAIT(const TYPE) == EXPECT); \
+  SA(TRAIT(volatile TYPE) == EXPECT);  \
+  SA(TRAIT(const volatile TYPE) == EXPECT)
+
+SA_TEST_CATEGORY(__is_arithmetic, void, false);
+
+SA_TEST_CATEGORY(__is_arithmetic, char, true);
+SA_TEST_CATEGORY(__is_arithmetic, signed char, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned char, 

Re: [PATCH 1/2] c++, libstdc++: implement __is_pointer built-in trait

2023-07-11 Thread François Dumont via Gcc-patches



On 10/07/2023 07:23, Ken Matsui via Libstdc++ wrote:

This patch implements built-in trait for std::is_pointer.

gcc/cp/ChangeLog:

* cp-trait.def: Define __is_pointer.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_POINTER.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Test existence of __is_pointer.
* g++.dg/ext/is_pointer.C: New test.
* g++.dg/tm/pr46567.C (__is_pointer): Rename to ...
(is_pointer): ... this.
* g++.dg/torture/20070621-1.C: Likewise.
* g++.dg/torture/pr57107.C: Likewise.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h (__is_pointer): Rename to ...
(is_pointer): ... this.
* include/bits/deque.tcc: Use is_pointer instead.
* include/bits/stl_algobase.h: Likewise.

Signed-off-by: Ken Matsui 
---
  gcc/cp/constraint.cc|  3 ++
  gcc/cp/cp-trait.def |  1 +
  gcc/cp/semantics.cc |  4 ++
  gcc/testsuite/g++.dg/ext/has-builtin-1.C|  3 ++
  gcc/testsuite/g++.dg/ext/is_pointer.C   | 51 +
  gcc/testsuite/g++.dg/tm/pr46567.C   | 22 -
  gcc/testsuite/g++.dg/torture/20070621-1.C   |  4 +-
  gcc/testsuite/g++.dg/torture/pr57107.C  |  4 +-
  libstdc++-v3/include/bits/cpp_type_traits.h |  6 +--
  libstdc++-v3/include/bits/deque.tcc |  6 +--
  libstdc++-v3/include/bits/stl_algobase.h|  6 +--
  11 files changed, 86 insertions(+), 24 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 8cf0f2d0974..30266204eb5 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3751,6 +3751,9 @@ diagnose_trait_expr (tree expr, tree args)
  case CPTK_IS_UNION:
inform (loc, "  %qT is not a union", t1);
break;
+case CPTK_IS_POINTER:
+  inform (loc, "  %qT is not a pointer", t1);
+  break;
  case CPTK_IS_AGGREGATE:
inform (loc, "  %qT is not an aggregate", t1);
break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..b7c263e9a77 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, 
"__is_trivially_assignable", 2)
  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1)
  DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
  DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
+DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1)
  DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, 
"__reference_constructs_from_temporary", 2)
  DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, 
"__reference_converts_from_temporary", 2)
  /* FIXME Added space to avoid direct usage in GCC 13.  */
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8fb47fd179e..68f8a4fe85b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12118,6 +12118,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree 
type2)
  case CPTK_IS_UNION:
return type_code1 == UNION_TYPE;
  
+case CPTK_IS_POINTER:

+  return TYPE_PTR_P (type1);
+
  case CPTK_IS_ASSIGNABLE:
return is_xible (MODIFY_EXPR, type1, type2);
  
@@ -12296,6 +12299,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)

  case CPTK_IS_ENUM:
  case CPTK_IS_UNION:
  case CPTK_IS_SAME:
+case CPTK_IS_POINTER:
break;
  
  case CPTK_IS_LAYOUT_COMPATIBLE:

diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C 
b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index f343e153e56..9dace5cbd48 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
  #if !__has_builtin (__remove_cvref)
  # error "__has_builtin (__remove_cvref) failed"
  #endif
+#if !__has_builtin (__is_pointer)
+# error "__has_builtin (__is_pointer) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_pointer.C 
b/gcc/testsuite/g++.dg/ext/is_pointer.C
new file mode 100644
index 000..d6e39565950
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_pointer.C
@@ -0,0 +1,51 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+SA(!__is_pointer(int));
+SA(__is_pointer(int*));
+SA(__is_pointer(int**));
+
+SA(__is_pointer(const int*));
+SA(__is_pointer(const int**));
+SA(__is_pointer(int* const));
+SA(__is_pointer(int** const));
+SA(__is_pointer(int* const* const));
+
+SA(__is_pointer(volatile int*));
+SA(__is_pointer(volatile int**));
+SA(__is_pointer(int* volatile));
+SA(__is_pointer(int** volatile));
+SA(__is_pointer(int* volatile* volatile));
+
+SA(__is_pointer(const volatile int*));
+SA(__is_pointer(const volatile int**));
+SA(__is_pointer(const int* volatile));
+SA(__is_pointer(volatile int* const));
+SA(__is_pointer(int* const volatile));

[PATCH] Reimplement __gnu_cxx::__ops operators

2023-06-14 Thread François Dumont via Gcc-patches
I think we all agree that __gnu_cxx::__ops needed to be reimplemented, 
here it is.


Note that I kept the usage of std::ref in ,  and .

    libstdc++: Reimplement __gnu_cxx::__ops operators

    Replace functors using iterators as input to adopt functors that
    are matching the same Standard expectations as the ones imposed on
    predicates used in predicates-aware algos. Doing so we need far less
    functors. It impose that iterators are dereference at algo level and
    not in the functors anymore.

    libstdc++-v3/ChangeLog:

    * include/std/functional (_Not_fn): Move to...
    * include/bits/predefined_ops.h: ...here, and expose a version
    in pre-C++14 mode.
    (__not_fn): New, use latter.
    (_Iter_less_iter, _Iter_less_val, _Val_less_iter, 
_Iter_equal_to_iter)
    (_Iter_equal_to_val, _Iter_comp_iter, _Iter_comp_val, 
_Val_comp_iter)
    (_Iter_equals_val, _Iter_equals_iter, _Iter_pred, 
_Iter_comp_val)

    (_Iter_comp_to_val, _Iter_comp_to_iter, _Iter_negate): Remove.
    (__iter_less_iter, __iter_less_val, __iter_comp_val, 
__val_less_iter)
    (__val_comp_iter, __iter_equal_to_iter, 
__iter_equal_to_val, __iter_comp_iter)
    (__val_comp_iter, __iter_equals_val, __iter_comp_iter, 
__pred_iter): Remove.

    (_Less, _Equal_to, _Equal_to_val, _Comp_val): New.
    (__less, __equal_to, __comp_val): New.
    * include/bits/stl_algo.h: Adapt all algos to use new 
__gnu_cxx::__ops operators.
    When possible use std::move to pass predicates between 
routines.

    * include/bits/stl_algobase.h: Likewise.
    * include/bits/stl_heap.h: Likewise.
    * include/std/deque: Cleanup usage of __gnu_cxx::__ops 
operators.

    * include/std/string: Likewise.
    * include/std/vector: Likewise.

Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h
index e9933373ed9..dc8920ed5f8 100644
--- a/libstdc++-v3/include/bits/predefined_ops.h
+++ b/libstdc++-v3/include/bits/predefined_ops.h
@@ -32,376 +32,170 @@
 
 #include 
 
+#if __cplusplus >= 201103L
+# include 
+#endif
+
 namespace __gnu_cxx
 {
 namespace __ops
 {
-  struct _Iter_less_iter
+  struct _Less
   {
-template
+template
   _GLIBCXX14_CONSTEXPR
   bool
-  operator()(_Iterator1 __it1, _Iterator2 __it2) const
-  { return *__it1 < *__it2; }
+  operator()(const _Lhs& __lhs, const _Rhs& __rhs) const
+  { return __lhs < __rhs; }
   };
 
   _GLIBCXX14_CONSTEXPR
-  inline _Iter_less_iter
-  __iter_less_iter()
-  { return _Iter_less_iter(); }
-
-  struct _Iter_less_val
-  {
-#if __cplusplus >= 201103L
-constexpr _Iter_less_val() = default;
-#else
-_Iter_less_val() { }
-#endif
-
-_GLIBCXX20_CONSTEXPR
-explicit
-_Iter_less_val(_Iter_less_iter) { }
-
-template
-  _GLIBCXX20_CONSTEXPR
-  bool
-  operator()(_Iterator __it, _Value& __val) const
-  { return *__it < __val; }
-  };
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_less_val
-  __iter_less_val()
-  { return _Iter_less_val(); }
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_less_val
-  __iter_comp_val(_Iter_less_iter)
-  { return _Iter_less_val(); }
-
-  struct _Val_less_iter
-  {
-#if __cplusplus >= 201103L
-constexpr _Val_less_iter() = default;
-#else
-_Val_less_iter() { }
-#endif
-
-_GLIBCXX20_CONSTEXPR
-explicit
-_Val_less_iter(_Iter_less_iter) { }
-
-template
-  _GLIBCXX20_CONSTEXPR
-  bool
-  operator()(_Value& __val, _Iterator __it) const
-  { return __val < *__it; }
-  };
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Val_less_iter
-  __val_less_iter()
-  { return _Val_less_iter(); }
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Val_less_iter
-  __val_comp_iter(_Iter_less_iter)
-  { return _Val_less_iter(); }
-
-  struct _Iter_equal_to_iter
-  {
-template
-  _GLIBCXX20_CONSTEXPR
-  bool
-  operator()(_Iterator1 __it1, _Iterator2 __it2) const
-  { return *__it1 == *__it2; }
-  };
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_equal_to_iter
-  __iter_equal_to_iter()
-  { return _Iter_equal_to_iter(); }
+  inline _Less
+  __less()
+  { return _Less(); }
 
-  struct _Iter_equal_to_val
+  struct _Equal_to
   {
-template
+template
   _GLIBCXX20_CONSTEXPR
   bool
-  operator()(_Iterator __it, _Value& __val) const
-  { return *__it == __val; }
+  operator()(const _Lhs& __lhs, const _Rhs& __rhs) const
+  { return __lhs == __rhs; }
   };
 
   _GLIBCXX20_CONSTEXPR
-  inline _Iter_equal_to_val
-  __iter_equal_to_val()
-  { return _Iter_equal_to_val(); }
-
-  _GLIBCXX20_CONSTEXPR
-  inline _Iter_equal_to_val
-  __iter_comp_val(_Iter_equal_to_iter)
-  { return _Iter_equal_to_val(); }
-
-  template
-struct _Iter_comp_iter
-{
-  _Compare _M_comp;
-
-  explicit 

Re: [PATCH v5 6/6] libstdc++: make std::is_object dispatch to new built-in traits

2023-06-13 Thread François Dumont via Gcc-patches



On 13/06/2023 00:22, Ken Matsui via Libstdc++ wrote:

This patch gets std::is_object to dispatch to new built-in traits,
__is_function, __is_reference, and __is_void.

libstdc++-v3/ChangeLog:
* include/std/type_traits (is_object): Use new built-in traits,
__is_function, __is_reference, and __is_void.
(__is_object): Define this built-in-like macro.
(is_object_v): Use built-in traits through the build-in-like macro.

Signed-off-by: Ken Matsui 
---
  libstdc++-v3/include/std/type_traits | 19 +++
  1 file changed, 19 insertions(+)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 780fcc00135..93335f94385 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -682,11 +682,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  { };
  
/// is_object

+#if __has_builtin(__is_function) && __has_builtin(__is_reference) \
+&& __has_builtin(__is_void)
+
+#define __is_object(_Tp) \
+  (!(__is_function(_Tp) || __is_reference(_Tp) || __is_void(_Tp)))


Is this evaluation order random ? Are all those builtin functions 
performances equivalent ?


I would have felt that __is_void is the simplest/fastest cause only for 
'void' so would have put it first.



+
+  template
+struct is_object
+: public __bool_constant<__is_object(_Tp)>
+{ };
+#else
template
  struct is_object
  : public __not_<__or_, is_reference<_Tp>,
is_void<_Tp>>>::type
  { };
+#endif
  
template

  struct is_member_pointer;
@@ -3235,8 +3247,15 @@ template 
inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
  template 
inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
+
+#ifdef __is_object
+template 
+  inline constexpr bool is_object_v = __is_object(_Tp);
+#else
  template 
inline constexpr bool is_object_v = is_object<_Tp>::value;
+#endif
+
  template 
inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
  template 


Re: [PATCH v4 2/6] libstdc++: use new built-in trait __is_reference for std::is_reference

2023-06-12 Thread François Dumont via Gcc-patches

Same remark for all your alike patches.

On 11/06/2023 04:43, Ken Matsui via Libstdc++ wrote:

This patch gets std::is_reference to dispatch to new built-in trait
__is_reference.

libstdc++-v3/ChangeLog:

* include/std/type_traits (is_reference): Use __is_reference built-in
trait.
(is_reference_v): Likewise.

Signed-off-by: Ken Matsui 
---
  libstdc++-v3/include/std/type_traits | 13 -
  1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 0e7a9c9c7f3..b2eb4bd3e7f 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -639,6 +639,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Composite type categories.
  
/// is_reference

+#if __has_builtin(__is_reference)

Here you are checking __has_builtin(__is_reference)...

+  template
+struct is_reference
+: public __bool_constant<__is_reference(_Tp)>
+{ };
+#else
template
  struct is_reference
  : public false_type
@@ -653,6 +659,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  struct is_reference<_Tp&&>
  : public true_type
  { };
+#endif
  
/// is_arithmetic

template
@@ -3193,11 +3200,7 @@ template 
  template 
inline constexpr bool is_function_v = is_function<_Tp>::value;
  template 
-  inline constexpr bool is_reference_v = false;
-template 
-  inline constexpr bool is_reference_v<_Tp&> = true;
-template 
-  inline constexpr bool is_reference_v<_Tp&&> = true;
+  inline constexpr bool is_reference_v = __is_reference(_Tp);

...but not here, why ?



Re: [committed] libstdc++: Update list of known symbol versions for abi-check

2023-06-06 Thread François Dumont via Gcc-patches



On 06/06/2023 17:59, Jonathan Wakely via Libstdc++ wrote:

Tested x86_64-linux and powerpc64le-linux. Pushed to trunk.

-- >8 --

Add the recently added CXXABI_1.3.15 version. Also remove two "frozen"
versions from the latestp list, as no more symbols should be added to
those now.

libstdc++-v3/ChangeLog:

* testsuite/util/testsuite_abi.cc (check_version): Add
CXXABI_1.3.15 symver and make it the latestp. Remove
GLIBCXX_IEEE128_3.4.31 and GLIBCXX_LDBL_3.4.31 from latestp.
---
  libstdc++-v3/testsuite/util/testsuite_abi.cc | 7 ++-
  1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc 
b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index cea6c217433..59615dd701e 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -233,7 +233,7 @@ check_version(symbol& test, bool added)
known_versions.push_back("CXXABI_1.3.11");
known_versions.push_back("CXXABI_1.3.12");
known_versions.push_back("CXXABI_1.3.13");
-  known_versions.push_back("CXXABI_1.3.14");
+  known_versions.push_back("CXXABI_1.3.15");


Did you really want to remove CXXABI_1.3.14 here ? ChangeLog says you 
just add CXXABI_1.3.15.




Re: [PATCH] Move std::search into algobase.h

2023-06-02 Thread François Dumont via Gcc-patches

Ok, push done.

Even after full rebuild those tests are still UNRESOLVED on my system.

Yes, I also noticed that I could remove this check. I'll propose it later.

François

On 02/06/2023 09:43, Jonathan Wakely wrote:

On Fri, 2 Jun 2023 at 08:33, François Dumont wrote:

I haven't been able to reproduce so far.

Here is however a patch that I think will fix the problem. At
least failing tests are UNRESOLVED on my system.

    libstdc++: Fix broken _GLIBCXX_PARALLEL mode

    Add missing  include in .


This fixes the broken parallel mode.


    Detect availability of  in tests needing it to make
them UNSUPPORTED
    rather than PASS when header is missing.

    libstdc++-v3/ChangeLog:

    * include/parallel/algobase.h: Include
.
    * testsuite/lib/libstdc++.exp
(check_effective_target_omp): New.
    * testsuite/17_intro/headers/c++2011/parallel_mode.cc:
    Add { dg-require-effective-target omp }.
    * testsuite/17_intro/headers/c++2014/parallel_mode.cc:
Likewise.
    * testsuite/17_intro/headers/c++2017/parallel_mode.cc:
Likewise.

Ok to commit ?


Please just add the #include to parallel/algobase.h for now.

The effective-target keyword seems reasonable, but "omp" is not a good 
name. And if we add that dg-require-effective-target to those tests 
then they don't need to repeat the check in the test itself:

#if __has_include()

So please just add the #include and then we can revisit the 
effective-target separately.




On 01/06/2023 23:57, Jonathan Wakely wrote:

On Thu, 1 Jun 2023, 21:37 François Dumont via Libstdc++,
mailto:libstdc%2b...@gcc.gnu.org>> wrote:

Now I've install OMP and try to rebuild lib to reproduce the
failure.


You shouldn't need to install anything, just build gcc and don't
configure it with --disable-libgomp


I haven't used --disable-libgomp. But maybe when I run configure
the 1st time it tried to detect OMP install and failed to find it
as I just installed it.


I don't know what you mean, because GCC doesn't depend on "OMP". GCC 
includes its own OpenMP implementation, and installs its own libgomp 
runtime library to support the -fopenmp flag. It doesn't depend on 
anything else.


Which OS are you testing on?



Re: [PATCH] Move std::search into algobase.h

2023-06-02 Thread François Dumont via Gcc-patches

I haven't been able to reproduce so far.

Here is however a patch that I think will fix the problem. At least 
failing tests are UNRESOLVED on my system.


    libstdc++: Fix broken _GLIBCXX_PARALLEL mode

    Add missing  include in .

    Detect availability of  in tests needing it to make them 
UNSUPPORTED

    rather than PASS when header is missing.

    libstdc++-v3/ChangeLog:

    * include/parallel/algobase.h: Include .
    * testsuite/lib/libstdc++.exp (check_effective_target_omp): 
New.

    * testsuite/17_intro/headers/c++2011/parallel_mode.cc:
    Add { dg-require-effective-target omp }.
    * testsuite/17_intro/headers/c++2014/parallel_mode.cc: 
Likewise.
    * testsuite/17_intro/headers/c++2017/parallel_mode.cc: 
Likewise.


Ok to commit ?


On 01/06/2023 23:57, Jonathan Wakely wrote:



On Thu, 1 Jun 2023, 21:37 François Dumont via Libstdc++, 
mailto:libstdc%2b...@gcc.gnu.org>> wrote:


It's of course not as easy as I thought.

I would never have detected this problem on my system because I'm
missing omp.h.

I've implemented and added a:

// { dg-require-effective-target omp }

so that now those tests are UNRESOLVED rather than PASS.

Now I've install OMP and try to rebuild lib to reproduce the failure.


You shouldn't need to install anything, just build gcc and don't 
configure it with --disable-libgomp


I haven't used --disable-libgomp. But maybe when I run configure the 1st 
time it tried to detect OMP install and failed to find it as I just 
installed it.


I'll tried to rebuild everything to see if I can eventually have those 
tests PASS.


François
diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h
index 4e4cc0fa0f2..9e5b86558e4 100644
--- a/libstdc++-v3/include/parallel/algobase.h
+++ b/libstdc++-v3/include/parallel/algobase.h
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2011/parallel_mode.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2011/parallel_mode.cc
index ccad7694083..7e5c2999c7a 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2011/parallel_mode.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2011/parallel_mode.cc
@@ -18,6 +18,7 @@
 // { dg-options "-std=gnu++11" }
 // { dg-do compile { target c++11 } }
 // { dg-require-normal-mode "" }
+// { dg-require-effective-target omp }
 
 #if __has_include()
 # define _GLIBCXX_PARALLEL 1
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2014/parallel_mode.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2014/parallel_mode.cc
index 604dbda7c32..bc828de0ed6 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2014/parallel_mode.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2014/parallel_mode.cc
@@ -18,6 +18,7 @@
 // { dg-options "-std=gnu++14" }
 // { dg-do compile { target c++14 } }
 // { dg-require-normal-mode "" }
+// { dg-require-effective-target omp }
 
 #if __has_include()
 # define _GLIBCXX_PARALLEL 1
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2017/parallel_mode.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2017/parallel_mode.cc
index 0fa7fae8d27..7c829249645 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2017/parallel_mode.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2017/parallel_mode.cc
@@ -17,6 +17,7 @@
 
 // { dg-do compile { target c++17 } }
 // { dg-require-normal-mode "" }
+// { dg-require-effective-target omp }
 
 #if __has_include()
 # define _GLIBCXX_PARALLEL 1
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index c83147ce99a..0207a15c57e 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1421,6 +1421,14 @@ proc check_effective_target_tzdb { } {
 }]
 }
 
+# Return 1 if OMP is available.
+proc check_effective_target_omp { } {
+return [check_v3_target_prop_cached et_omp {
+	set cond "__has_include()"
+	return [v3_check_preprocessor_condition omp $cond]
+}]
+}
+
 set additional_prunes ""
 
 if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \


Re: [PATCH] Move std::search into algobase.h

2023-06-01 Thread François Dumont via Gcc-patches

It's of course not as easy as I thought.

I would never have detected this problem on my system because I'm 
missing omp.h.


I've implemented and added a:

// { dg-require-effective-target omp }

so that now those tests are UNRESOLVED rather than PASS.

Now I've install OMP and try to rebuild lib to reproduce the failure.

To be continued tomorrow...

On 01/06/2023 14:05, Jonathan Wakely wrote:



On Thu, 1 Jun 2023 at 12:52, Rainer Orth  
wrote:


Jonathan Wakely via Gcc-patches  writes:

> On Wed, 31 May 2023 at 18:39, François Dumont via Libstdc++ <
> libstd...@gcc.gnu.org > wrote:
>
>> libstdc++: Reduce  inclusion to 
>>
>>
>> Move the std::search definition from stl_algo.h to
stl_algobase.h and use
>> the later in .
>>
>> For consistency also move std::__parallel::search and
associated helpers
>> from
>>  to  so that
>> std::__parallel::search
>> is accessible along with std::search.
>>
>> libstdc++-v3/ChangeLog:
>>
>>              * include/bits/stl_algo.h
>>              (std::__search, std::search(_FwdIt1, _FwdIt1, _FwdIt2,
>> _FwdIt2, _BinPred)): Move...
>>              * include/bits/stl_algobase.h: ...here.
>>              * include/std/functional: Replace 
include by
>> .
>>              * include/parallel/algo.h
(std::__parallel::search<_FIt1,
>> _FIt2, _BinaryPred>)
>> (std::__parallel::__search_switch<_FIt1, _FIt2,
>> _BinaryPred, _ItTag1, _ItTag2>):
>>              Move...
>>              * include/parallel/algobase.h: ...here.
>>              * include/std/functional: Remove  and
>> 
>>              includes. Include .
>>
>> Tested under Linux x86_64.
>>
>> Ok to commit ?
>>
>
> OK

This seems to have caused

+FAIL: 17_intro/headers/c++2011/parallel_mode.cc (test for excess
errors)
+FAIL: 17_intro/headers/c++2014/parallel_mode.cc (test for excess
errors)

on i386-pc-solaris2.11:


I think it affects all targets.


Excess errors:

/var/gcc/regression/master/11.4-gcc-gas/build/i386-pc-solaris2.11/libstdc++-v3/include/parallel/algobase.h:496:
error: '__search_template' is not a member of '__gnu_parallel';
did you mean '__find_template'?

        Rainer

-- 
-

Rainer Orth, Center for Biotechnology, Bielefeld University



Re: [PATCH] Move std::search into algobase.h

2023-06-01 Thread François Dumont via Gcc-patches
Sorry, I had fully tested the move from bits/stl_algo.h to
bits/stl_algobase.h.

But it appears that the script I used to run the tests after the other move
has not done what I expected.

I'll provide the patch shortly.


Le jeu. 1 juin 2023 à 14:06, Jonathan Wakely  a écrit :

>
>
> On Thu, 1 Jun 2023 at 12:52, Rainer Orth 
> wrote:
>
>> Jonathan Wakely via Gcc-patches  writes:
>>
>> > On Wed, 31 May 2023 at 18:39, François Dumont via Libstdc++ <
>> > libstd...@gcc.gnu.org> wrote:
>> >
>> >> libstdc++: Reduce  inclusion to 
>> >>
>> >>
>> >> Move the std::search definition from stl_algo.h to stl_algobase.h and
>> use
>> >> the later in .
>> >>
>> >> For consistency also move std::__parallel::search and associated
>> helpers
>> >> from
>> >>  to  so that
>> >> std::__parallel::search
>> >> is accessible along with std::search.
>> >>
>> >> libstdc++-v3/ChangeLog:
>> >>
>> >>  * include/bits/stl_algo.h
>> >>  (std::__search, std::search(_FwdIt1, _FwdIt1, _FwdIt2,
>> >> _FwdIt2, _BinPred)): Move...
>> >>  * include/bits/stl_algobase.h: ...here.
>> >>  * include/std/functional: Replace  include by
>> >> .
>> >>  * include/parallel/algo.h (std::__parallel::search<_FIt1,
>> >> _FIt2, _BinaryPred>)
>> >>  (std::__parallel::__search_switch<_FIt1, _FIt2,
>> >> _BinaryPred, _ItTag1, _ItTag2>):
>> >>  Move...
>> >>  * include/parallel/algobase.h: ...here.
>> >>  * include/std/functional: Remove  and
>> >> 
>> >>  includes. Include .
>> >>
>> >> Tested under Linux x86_64.
>> >>
>> >> Ok to commit ?
>> >>
>> >
>> > OK
>>
>> This seems to have caused
>>
>> +FAIL: 17_intro/headers/c++2011/parallel_mode.cc (test for excess errors)
>> +FAIL: 17_intro/headers/c++2014/parallel_mode.cc (test for excess errors)
>>
>> on i386-pc-solaris2.11:
>>
>
> I think it affects all targets.
>
>
>>
>> Excess errors:
>> /var/gcc/regression/master/11.4-gcc-gas/build/i386-pc-solaris2.11/libstdc++-v3/include/parallel/algobase.h:496:
>> error: '__search_template' is not a member of '__gnu_parallel'; did you
>> mean '__find_template'?
>>
>> Rainer
>>
>> --
>>
>> -
>> Rainer Orth, Center for Biotechnology, Bielefeld University
>>
>>


[PATCH] Move std::search into algobase.h

2023-05-31 Thread François Dumont via Gcc-patches

libstdc++: Reduce  inclusion to 


Move the std::search definition from stl_algo.h to stl_algobase.h and use
the later in .

For consistency also move std::__parallel::search and associated helpers 
from
 to  so that 
std::__parallel::search

is accessible along with std::search.

libstdc++-v3/ChangeLog:

    * include/bits/stl_algo.h
    (std::__search, std::search(_FwdIt1, _FwdIt1, _FwdIt2, 
_FwdIt2, _BinPred)): Move...

    * include/bits/stl_algobase.h: ...here.
    * include/std/functional: Replace  include by 
.
    * include/parallel/algo.h (std::__parallel::search<_FIt1, 
_FIt2, _BinaryPred>)
    (std::__parallel::__search_switch<_FIt1, _FIt2, 
_BinaryPred, _ItTag1, _ItTag2>):

    Move...
    * include/parallel/algobase.h: ...here.
    * include/std/functional: Remove  and 


    includes. Include .

Tested under Linux x86_64.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 54695490166..2c52ed51402 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -140,54 +140,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // count
   // count_if
   // search
-
-  template
-_GLIBCXX20_CONSTEXPR
-_ForwardIterator1
-__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-	 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-	 _BinaryPredicate  __predicate)
-{
-  // Test for empty ranges
-  if (__first1 == __last1 || __first2 == __last2)
-	return __first1;
-
-  // Test for a pattern of length 1.
-  _ForwardIterator2 __p1(__first2);
-  if (++__p1 == __last2)
-	return std::__find_if(__first1, __last1,
-		__gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
-
-  // General case.
-  _ForwardIterator1 __current = __first1;
-
-  for (;;)
-	{
-	  __first1 =
-	std::__find_if(__first1, __last1,
-		__gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
-
-	  if (__first1 == __last1)
-	return __last1;
-
-	  _ForwardIterator2 __p = __p1;
-	  __current = __first1;
-	  if (++__current == __last1)
-	return __last1;
-
-	  while (__predicate(__current, __p))
-	{
-	  if (++__p == __last2)
-		return __first1;
-	  if (++__current == __last1)
-		return __last1;
-	}
-	  ++__first1;
-	}
-  return __first1;
-}
-
   // search_n
 
   /**
@@ -4147,48 +4099,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 			   __gnu_cxx::__ops::__iter_equal_to_iter());
 }
 
-  /**
-   *  @brief Search a sequence for a matching sub-sequence using a predicate.
-   *  @ingroup non_mutating_algorithms
-   *  @param  __first1 A forward iterator.
-   *  @param  __last1  A forward iterator.
-   *  @param  __first2 A forward iterator.
-   *  @param  __last2  A forward iterator.
-   *  @param  __predicate  A binary predicate.
-   *  @return   The first iterator @c i in the range
-   *  @p [__first1,__last1-(__last2-__first2)) such that
-   *  @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range
-   *  @p [0,__last2-__first2), or @p __last1 if no such iterator exists.
-   *
-   *  Searches the range @p [__first1,__last1) for a sub-sequence that
-   *  compares equal value-by-value with the sequence given by @p
-   *  [__first2,__last2), using @p __predicate to determine equality,
-   *  and returns an iterator to the first element of the
-   *  sub-sequence, or @p __last1 if no such iterator exists.
-   *
-   *  @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2)
-  */
-  template
-_GLIBCXX20_CONSTEXPR
-inline _ForwardIterator1
-search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-	   _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-	   _BinaryPredicate  __predicate)
-{
-  // concept requirements
-  __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>)
-  __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>)
-  __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-	typename iterator_traits<_ForwardIterator1>::value_type,
-	typename iterator_traits<_ForwardIterator2>::value_type>)
-  __glibcxx_requires_valid_range(__first1, __last1);
-  __glibcxx_requires_valid_range(__first2, __last2);
-
-  return std::__search(__first1, __last1, __first2, __last2,
-			   __gnu_cxx::__ops::__iter_comp_iter(__predicate));
-}
-
   /**
*  @brief Search a sequence for a number of consecutive values.
*  @ingroup non_mutating_algorithms
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 4a6f8195d98..dd95e94f7e9 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -2150,6 +2150,53 @@ _GLIBCXX_END_NAMESPACE_ALGO
   return __result;
 }
 
+  template
+_GLIBCXX20_CONSTEXPR
+_ForwardIterator1
+

Re: [PATCH] Replace __gnu_cxx::__ops::__negate with std::not_fn

2023-05-23 Thread François Dumont via Gcc-patches



On 22/05/2023 22:55, Jonathan Wakely wrote:



On Mon, 22 May 2023 at 21:51, François Dumont via Libstdc++ 
mailto:libstdc%2b...@gcc.gnu.org>> wrote:


I was thinking that it might be nice to get rid of
predefined_ops.h content.

So here is a start with __negate. Drawback is that stl_algo.h has to
include .


We definitely don't want that. std::not_fn could be move to its own 
header.


But I'm not sure this is a good change anyway, as we can't do it 
unconditionally. Pre-C++17 code would still be using the 
predefined_ops.h function objects, so we can't remove that code. And 
we'll get template bloat from instantiating the algos twice, once with 
the old function objects and once with std::not_fn.


True, what do you advise then ? Should I just forget about it ? 
Introduce a std::__not_fn for pre-C++17 ?


I am studying this last proposal, let me know if it is just impossible 
or a waste of time.




For now I just get rid of stl_algo.h include in
 to rather use stl_algobase.h. But maybe it would be
better
to also isolate std::not_fn in a dedicated header file so that
stl_algo.h do not have to include all .

 libstdc++: Replace __gnu_cxx::__ops::__negate with std::not_fn

 Replace the internal __gnu_cxx::__ops::__negate function and
associated
 __gnu_cxx::__ops::_Iter_negate by the C++17 std::not_fn.

 libstdc++-v3/ChangeLog:

 * include/bits/predefined_ops.h: Include .


No, please don't include  anywhere. If you do that, it means 
 now defines every feature test macro in the entire 
library, which makes it look like you can get smart pointers and 
ranges and constexpr math all from .


Ok, I wasn't aware about the interest of . I see now, limited 
to user code.


I'm testing only the move of std::search to stl_algobase.h to avoid 
stl_algo.h include in . I'll submit it later.


[PATCH] Replace __gnu_cxx::__ops::__negate with std::not_fn

2023-05-22 Thread François Dumont via Gcc-patches

I was thinking that it might be nice to get rid of predefined_ops.h content.

So here is a start with __negate. Drawback is that stl_algo.h has to 
include . For now I just get rid of stl_algo.h include in 
 to rather use stl_algobase.h. But maybe it would be better 
to also isolate std::not_fn in a dedicated header file so that 
stl_algo.h do not have to include all .


    libstdc++: Replace __gnu_cxx::__ops::__negate with std::not_fn

    Replace the internal __gnu_cxx::__ops::__negate function and associated
    __gnu_cxx::__ops::_Iter_negate by the C++17 std::not_fn.

    libstdc++-v3/ChangeLog:

    * include/bits/predefined_ops.h: Include .
    [__cpp_lib_not_fn](__gnu_cxx::__ops::_Iter_negate): Remove.
    [__cpp_lib_not_fn](__gnu_cxx::__ops::__negate): Remove.
    * include/bits/stl_algo.h: Include  for C++17 
and later.

    [__cpp_lib_not_fn](__find_if_not): Use std::not_fn.
    (std::__search, std::search(_FwdIt1, _FwdIt1, _FwdIt2, 
_FwdIt2, _BinPred)): Move...

    * include/bits/stl_algobase.h: ...here.
    * include/std/functional: Replace  include by 
.


Tests still running.

François

diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h
index e9933373ed9..8fdb11ea84b 100644
--- a/libstdc++-v3/include/bits/predefined_ops.h
+++ b/libstdc++-v3/include/bits/predefined_ops.h
@@ -30,6 +30,7 @@
 #ifndef _GLIBCXX_PREDEFINED_OPS_H
 #define _GLIBCXX_PREDEFINED_OPS_H	1
 
+#include 
 #include 
 
 namespace __gnu_cxx
@@ -377,6 +378,7 @@ namespace __ops
 	  _GLIBCXX_MOVE(__comp._M_comp), __it);
 }
 
+#if !__cpp_lib_not_fn
   template
 struct _Iter_negate
 {
@@ -400,6 +402,7 @@ namespace __ops
 inline _Iter_negate<_Predicate>
 __negate(_Iter_pred<_Predicate> __pred)
 { return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); }
+#endif
 
 } // namespace __ops
 } // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 54695490166..849d8a59ec2 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -65,6 +65,10 @@
 #include 
 #endif
 
+#if __cplusplus >= 201703L
+#include  // for std::not_fn.
+#endif
+
 #if _GLIBCXX_HOSTED
 # include   // for _Temporary_buffer
 # if (__cplusplus <= 201103L || _GLIBCXX_USE_DEPRECATED)
@@ -110,7 +114,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		  _Predicate __pred)
 {
   return std::__find_if(__first, __last,
+#if __cpp_lib_not_fn
+			std::not_fn(std::move(__pred)),
+#else
 			__gnu_cxx::__ops::__negate(__pred),
+#endif
 			std::__iterator_category(__first));
 }
 
@@ -140,54 +148,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // count
   // count_if
   // search
-
-  template
-_GLIBCXX20_CONSTEXPR
-_ForwardIterator1
-__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
-	 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
-	 _BinaryPredicate  __predicate)
-{
-  // Test for empty ranges
-  if (__first1 == __last1 || __first2 == __last2)
-	return __first1;
-
-  // Test for a pattern of length 1.
-  _ForwardIterator2 __p1(__first2);
-  if (++__p1 == __last2)
-	return std::__find_if(__first1, __last1,
-		__gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
-
-  // General case.
-  _ForwardIterator1 __current = __first1;
-
-  for (;;)
-	{
-	  __first1 =
-	std::__find_if(__first1, __last1,
-		__gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
-
-	  if (__first1 == __last1)
-	return __last1;
-
-	  _ForwardIterator2 __p = __p1;
-	  __current = __first1;
-	  if (++__current == __last1)
-	return __last1;
-
-	  while (__predicate(__current, __p))
-	{
-	  if (++__p == __last2)
-		return __first1;
-	  if (++__current == __last1)
-		return __last1;
-	}
-	  ++__first1;
-	}
-  return __first1;
-}
-
   // search_n
 
   /**
@@ -4147,48 +4107,6 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 			   __gnu_cxx::__ops::__iter_equal_to_iter());
 }
 
-  /**
-   *  @brief Search a sequence for a matching sub-sequence using a predicate.
-   *  @ingroup non_mutating_algorithms
-   *  @param  __first1 A forward iterator.
-   *  @param  __last1  A forward iterator.
-   *  @param  __first2 A forward iterator.
-   *  @param  __last2  A forward iterator.
-   *  @param  __predicate  A binary predicate.
-   *  @return   The first iterator @c i in the range
-   *  @p [__first1,__last1-(__last2-__first2)) such that
-   *  @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range
-   *  @p [0,__last2-__first2), or @p __last1 if no such iterator exists.
-   *
-   *  Searches the range @p [__first1,__last1) for a sub-sequence that
-   *  compares equal value-by-value with the sequence given by @p
-   *  [__first2,__last2), using @p __predicate to determine equality,
-   *  and returns an iterator to the first element 

[PATCH] _Hashtable implementation cleanup

2023-05-09 Thread François Dumont via Gcc-patches

Hi

Rather than providing a series of patches for _Hashtable I prefer to 
submit them one by one. It will maximize the chances to have some of 
them in gcc 14.


I'm starting with this simple patch to do some cleanup in the current 
implementation to ease compiler optimizations by making some methods 
implicitly inline and avoiding the iterator abstraction when useless.


It is also replacing some faulty usages of __node_type* with __node_ptr. 
It should simplify the patch to make use of allocator custom pointer I 
would like to reactivate.


libstdc++: [_Hashtable] Implement several small methods implicitly inline

Make implementation of 3 simple _Hashtable methods implicitly inline.

Avoid usage of const_iterator abstraction within _Hashtable implementation.

Replace several usages of __node_type* with expected __node_ptr.

libstdc++-v3/ChangeLog:

    * include/bits/hashtable_policy.h
    (_NodeBuilder<>::_S_build): Use __node_ptr.
    (_ReuseOrAllocNode<>): Use __node_ptr in place of __node_type*.
    (_AllocNode<>): Likewise.
    (_Equality<>::_M_equal): Remove const_iterator usages. Only 
preserved
    to call std::is_permutation in the non-unique key 
implementation.
    * include/bits/hashtable.h 
(_Hashtable<>::_M_update_begin()): Capture

    _M_begin() once.
    (_Hashtable<>::_M_bucket_begin(size_type)): Implement 
implicitly inline.

    (_Hashtable<>::_M_insert_bucket_begin): Likewise.
    (_Hashtable<>::_M_remove_bucket_begin): Likewise.
    (_Hashtable<>::_M_compute_hash_code): Use __node_ptr rather 
than

    const_iterator.
    (_Hashtable<>::find): Likewise.
    (_Hashtable<>::_M_emplace): Likewise.
    (_Hashtable<>::_M_insert_unique): Likewise.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index d2ff15320fc..954a1c7a58d 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -401,8 +401,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   _M_update_bbegin()
   {
-	if (_M_begin())
-	  _M_buckets[_M_bucket_index(*_M_begin())] = &_M_before_begin;
+	if (auto __begin = _M_begin())
+	  _M_buckets[_M_bucket_index(*__begin)] = &_M_before_begin;
   }
 
   void
@@ -458,7 +458,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Gets bucket begin, deals with the fact that non-empty buckets contain
   // their before begin node.
   __node_ptr
-  _M_bucket_begin(size_type __bkt) const;
+  _M_bucket_begin(size_type __bkt) const
+  {
+	__node_base_ptr __n = _M_buckets[__bkt];
+	return __n ? static_cast<__node_ptr>(__n->_M_nxt) : nullptr;
+  }
 
   __node_ptr
   _M_begin() const
@@ -831,19 +835,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Insert a node at the beginning of a bucket.
   void
-  _M_insert_bucket_begin(size_type, __node_ptr);
+  _M_insert_bucket_begin(size_type __bkt, __node_ptr __node)
+  {
+	if (_M_buckets[__bkt])
+	  {
+	// Bucket is not empty, we just need to insert the new node
+	// after the bucket before begin.
+	__node->_M_nxt = _M_buckets[__bkt]->_M_nxt;
+	_M_buckets[__bkt]->_M_nxt = __node;
+	  }
+	else
+	  {
+	// The bucket is empty, the new node is inserted at the
+	// beginning of the singly-linked list and the bucket will
+	// contain _M_before_begin pointer.
+	__node->_M_nxt = _M_before_begin._M_nxt;
+	_M_before_begin._M_nxt = __node;
+
+	if (__node->_M_nxt)
+	  // We must update former begin bucket that is pointing to
+	  // _M_before_begin.
+	  _M_buckets[_M_bucket_index(*__node->_M_next())] = __node;
+
+	_M_buckets[__bkt] = &_M_before_begin;
+	  }
+  }
 
   // Remove the bucket first node
   void
   _M_remove_bucket_begin(size_type __bkt, __node_ptr __next_n,
-			 size_type __next_bkt);
+			 size_type __next_bkt)
+  {
+	if (!__next_n || __next_bkt != __bkt)
+	  {
+	// Bucket is now empty
+	// First update next bucket if any
+	if (__next_n)
+	  _M_buckets[__next_bkt] = _M_buckets[__bkt];
+
+	// Second update before begin node if necessary
+	if (&_M_before_begin == _M_buckets[__bkt])
+	  _M_before_begin._M_nxt = __next_n;
+	_M_buckets[__bkt] = nullptr;
+	  }
+  }
 
   // Get the node before __n in the bucket __bkt
   __node_base_ptr
   _M_get_previous_node(size_type __bkt, __node_ptr __n);
 
-  pair
-  _M_compute_hash_code(const_iterator __hint, const key_type& __k) const;
+  pair<__node_ptr, __hash_code>
+  _M_compute_hash_code(__node_ptr __hint, const key_type& __k) const;
 
   // Insert node __n with hash code __code, in bucket __bkt if no
   // rehash (assumes no element with same key already present).
@@ -1153,20 +1195,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 };
 
   // Definitions of class template 

Re: [PATCH] Implement std::advance for istreambuf_iterator using pubseekoff

2023-04-24 Thread François Dumont via Gcc-patches
I had totally forgotten about it myself. The occasion to take a fresh 
look at it.


Here is a new version considering 1st pubseekoff call returned value to 
find out if it can be used. I removed the check/comparison with 2nd call 
result as it's not usable. In new 4_neg.cc test case if I ask to advance 
istreambuf_iterator by 10 the returned pos_type is showing 10 
offset even if it is obviously false. You need to read next byte to see 
that it is eof.


    libstdc++: Implement std::advance for istreambuf_iterator using 
pubseekoff


    If advance increment is smaller than input buffer size just advance 
in this
    buffer thanks to __safe_gbump. If increment is larger check for 
seekoff support
    and use it accordingly. Otherwise fallback on current 
__safe_gbump/underflow loop.


    libstdc++-v3/ChangeLog:

    * include/bits/streambuf_iterator.h (advance): Re-implement
    using streambuf pubseekoff/seekoff when supported.
    * 
testsuite/25_algorithms/advance/istreambuf_iterators/char/4_neg.cc: New

    test case.

Ok to commit when back in stage 1 ?

François


On 31/03/2023 23:03, Jonathan Wakely wrote:

On Tue, 15 Oct 2019 at 21:20, François Dumont wrote:

Here is an update to set _M_sbuf to null if the user advance too much.

Note that in this case the streambuf remains un-modified which is
different from the current implementation. I think it is another
enhancement.

I also change the Debug assertion message for something more dedicated
to std::advance algo.

François

On 10/14/19 10:12 PM, François Dumont wrote:

The same way I proposed to review std::copy overload for
istreambuf_iterator we can implement std::advance using pubseekoff.

It is both a cleaner implementation and avoids yet another friend
declaration.

Looks like I never sent my review of this one, it's been sitting in my
draft mails for years, sorry.

It looks like this will fail if the streambuf doesn't support seeking.
The default behaviour for seekoff is to return -1, in which case
you'll get -1 for both calls to pubseekoff, and new_pos - cur_pos will
be zero, which is not equal to n, so you set the istreambuf_iterator
to end-of-stream. That seems wrong, we could still advance using the
old code (or just call ++ in a loop!)




 * include/std/streambuf
 (advance(istreambuf_iterator<>&, _Distance)): Remove friend
declaration.
 * include/bits/streambuf_iterator.h (__copy_move_a2): Re-implement
using
 streambuf pubseekoff.

Tested under Linux x86_64.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h
index 32285a668fc..4527660e191 100644
--- a/libstdc++-v3/include/bits/streambuf_iterator.h
+++ b/libstdc++-v3/include/bits/streambuf_iterator.h
@@ -479,37 +479,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   __glibcxx_assert(__n > 0);
   __glibcxx_requires_cond(!__i._M_at_eof(),
-			  _M_message(__gnu_debug::__msg_inc_istreambuf)
-			  ._M_iterator(__i));
+			  _M_message(__gnu_debug::__msg_advance_oob)
+			  ._M_iterator(__i)
+			  ._M_integer(__n));
 
   typedef istreambuf_iterator<_CharT>		   __is_iterator_type;
   typedef typename __is_iterator_type::traits_type	   traits_type;
   typedef typename __is_iterator_type::streambuf_type  streambuf_type;
   typedef typename traits_type::int_type		   int_type;
+  typedef typename traits_type::off_type		   off_type;
+  typedef typename streambuf_type::pos_type		   pos_type;
   const int_type __eof = traits_type::eof();
+  const pos_type __npos = pos_type(off_type(-1));
 
   streambuf_type* __sb = __i._M_sbuf;
-  while (__n > 0)
-	{
   streamsize __size = __sb->egptr() - __sb->gptr();
-	  if (__size > __n)
-	{
+  if (__size >= __n)
 	__sb->__safe_gbump(__n);
-	  break;
-	}
-
+  else
+	{
+	  // Check for seekoff support.
+	  if (__sb->pubseekoff(0, ios_base::cur, ios_base::in) != __npos)
+	__sb->pubseekoff(__n, ios_base::cur, ios_base::in);
+	  else
+	{
+	  _GLIBCXX_DEBUG_ONLY(_Distance __n_orig = __n);
+	  for (;;)
+		{
 		  __sb->__safe_gbump(__size);
 		  __n -= __size;
+
+		  if (__n == 0)
+		break;
+
 		  if (traits_type::eq_int_type(__sb->underflow(), __eof))
 		{
-	  __glibcxx_requires_cond(__n == 0,
-_M_message(__gnu_debug::__msg_inc_istreambuf)
-._M_iterator(__i));
+		  __i._M_sbuf = 0;
 		  break;
 		}
+
+		  __size = __sb->egptr() - __sb->gptr();
+		  if (__size > __n)
+		__size = __n;
+		}
+
+	  _GLIBCXX_DEBUG_ONLY(__n = __n_orig);
+	}
 	}
 
   __i._M_c = __eof;
+  __glibcxx_requires_cond(!__i._M_at_eof(),
+			  _M_message(__gnu_debug::__msg_advance_oob)
+			  ._M_iterator(__i)
+			  ._M_integer(__n));
 }
 
 /// @} group iterators
diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/4_neg.cc 

Re: [PATCH] libstdc++: Limit allocations in _Rb_tree 2/2

2023-03-01 Thread François Dumont via Gcc-patches

Just forget about this patch, bad idea.

The key_type might have additional data not used for the comparison. 
This data would not be preserved if we were inserting the already stored 
equivalent key instead of the user provided.



On 22/02/23 07:08, François Dumont wrote:

This one is a refinement for multimap/multiset.

It allows to have share the same key if managed with ref counting like 
the cow string.


    libstdc++: [_Rb_tree] Limit allocations on equal insertions [PR 
96088]


    When inserting the same key several times prefer to insert the new 
entry using the
    current stored key_type instance if this copy is noexcept. 
Otherwise create a new

    key instance from input argument.

    libstdc++-v3/ChangeLog:

    PR libstdc++/96088
    * include/bits/cow_string.h 
(basic_string<>::basic_string(const basic_string&)):

    Add noexcept qualification when allocator is always equal.
    * include/bits/stl_tree.h 
(_Rb_tree<>::_M_get_insert_equal_pos_tr): New.

    (_Rb_tree<>::_M_emplace_equal_tr): New, use latter.
    (_Rb_tree<>::_M_emplace_equal_aux): New, use latter.
(_Rb_tree<>::_M_emplace_equal<_Arg>(_Arg&&)): New, use latter.
    * testsuite/23_containers/multimap/96088.cc (test01): Add 
check on redundant

    insertion.
    (test02): Likewise.
    * testsuite/23_containers/multiset/96088.cc (test01, 
test02): Likewise.


François





Re: [PATCH] Fix std::unordered_map key range insertion

2023-02-26 Thread François Dumont via Gcc-patches

Replying to my own questions.

This use case is not valid from a Standard point of view. So not a bug 
and no need to deal with that before next stage 1.


The question left is either we want to support it ?

François

On 23/02/23 22:14, François Dumont wrote:

Hi

Based on my work on PR 96088 for std::map I imagine this use case of 
inserting a range of keys into an associative container. It behaves as 
operator[] by inserting a default value for each key.


I wonder if the Standard says that it should work. Or maybe we want to 
support it ?


I haven't checked if it used to work before we introduced the 
_ConvertToValueType type. I have no old enough gcc to do so.


It is not supported by std::map neither, even without 
_ConvertToValueType so I guess it was not working for 
std::unordered_map prior to it.


If it can be considered as a bug I'll create a PR.

François





[PATCH] Fix std::unordered_map key range insertion

2023-02-23 Thread François Dumont via Gcc-patches

Hi

Based on my work on PR 96088 for std::map I imagine this use case of 
inserting a range of keys into an associative container. It behaves as 
operator[] by inserting a default value for each key.


I wonder if the Standard says that it should work. Or maybe we want to 
support it ?


I haven't checked if it used to work before we introduced the 
_ConvertToValueType type. I have no old enough gcc to do so.


It is not supported by std::map neither, even without 
_ConvertToValueType so I guess it was not working for std::unordered_map 
prior to it.


If it can be considered as a bug I'll create a PR.

François

diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index cce4e2844cf..4a89d0ee1c8 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -125,15 +125,15 @@ namespace __detail
 	{ return std::forward<_Kt>(__k); }
 };
 
-  template
-struct _ConvertToValueType<_Select1st, _Value>
+  template
+struct _ConvertToValueType<_Select1st, std::pair<_Key, _Value>>
 {
-  constexpr _Value&&
-  operator()(_Value&& __x) const noexcept
+  constexpr std::pair<_Key, _Value>&&
+  operator()(std::pair<_Key, _Value>&& __x) const noexcept
   { return std::move(__x); }
 
-  constexpr const _Value&
-  operator()(const _Value& __x) const noexcept
+  constexpr const std::pair<_Key, _Value>&
+  operator()(const std::pair<_Key, _Value>& __x) const noexcept
   { return __x; }
 
   template
@@ -145,6 +145,26 @@ namespace __detail
 	constexpr const std::pair<_Kt, _Val>&
 	operator()(const std::pair<_Kt, _Val>& __x) const noexcept
 	{ return __x; }
+
+  template
+	using __is_cons = std::is_constructible<_Key, _Kt&&>;
+
+  template
+	using _IFcons = std::enable_if<__is_cons<_Kt>::value>;
+
+  template
+	using _IFconsp = typename _IFcons<_Kt>::type;
+
+  template>
+	std::pair<_Kt, _Value>
+	operator()(_Kt&& __kt) const
+	{
+	  return {
+	std::piecewise_construct,
+	std::forward_as_tuple(std::forward<_Kt>(__kt)),
+	std::tuple<>()
+	  };
+	}
 };
 
   template
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
index 754b529c67c..a3bf6ce5307 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
@@ -264,6 +264,28 @@ test03()
   }
 }
 
+void
+test04()
+{
+  const std::initializer_list strlst =
+{ "long_str_for_dynamic_allocating" };
+  __gnu_test::counter::reset();
+  std::unordered_map> um;
+  um.insert(strlst.begin(), strlst.end());
+  VERIFY( um.size() == 1 );
+
+  VERIFY( __gnu_test::counter::count() == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+
+  um.insert(strlst.begin(), strlst.end());
+  VERIFY( um.size() == 1 );
+
+  VERIFY( __gnu_test::counter::count() == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+}
+
 int
 main()
 {
@@ -274,5 +296,6 @@ main()
   test21();
   test22();
   test03();
+  test04();
   return 0;
 }


[PATCH] libstdc++: Limit allocations in _Rb_tree 2/2

2023-02-21 Thread François Dumont via Gcc-patches

This one is a refinement for multimap/multiset.

It allows to have share the same key if managed with ref counting like 
the cow string.


    libstdc++: [_Rb_tree] Limit allocations on equal insertions [PR 96088]

    When inserting the same key several times prefer to insert the new 
entry using the
    current stored key_type instance if this copy is noexcept. 
Otherwise create a new

    key instance from input argument.

    libstdc++-v3/ChangeLog:

    PR libstdc++/96088
    * include/bits/cow_string.h 
(basic_string<>::basic_string(const basic_string&)):

    Add noexcept qualification when allocator is always equal.
    * include/bits/stl_tree.h 
(_Rb_tree<>::_M_get_insert_equal_pos_tr): New.

    (_Rb_tree<>::_M_emplace_equal_tr): New, use latter.
    (_Rb_tree<>::_M_emplace_equal_aux): New, use latter.
(_Rb_tree<>::_M_emplace_equal<_Arg>(_Arg&&)): New, use latter.
    * testsuite/23_containers/multimap/96088.cc (test01): Add 
check on redundant

    insertion.
    (test02): Likewise.
    * testsuite/23_containers/multiset/96088.cc (test01, 
test02): Likewise.


François
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index ad9929c4ad3..cdfbe5e190b 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -541,6 +541,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @param  __str  Source string.
*/
   basic_string(const basic_string& __str)
+	_GLIBCXX_NOEXCEPT_IF(_CharT_alloc_traits::_S_always_equal())
   : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
 	__str.get_allocator()),
 		__str.get_allocator())
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 21e9586b0a3..c3a4a97cfcf 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -968,6 +968,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 	pair<_Base_ptr, _Base_ptr>
 	_M_get_insert_unique_pos_tr(const _Kt& __k);
+
+  template
+	pair<_Base_ptr, _Base_ptr>
+	_M_get_insert_equal_pos_tr(const _Kt& __k);
 #endif
 
   pair<_Base_ptr, _Base_ptr>
@@ -1225,6 +1229,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	std::forward<_Arg>(__arg));
 	}
 
+  template
+	iterator
+	_M_emplace_equal_kv(_Kt&&, _Arg&&);
+
+  template
+	iterator
+	_M_emplace_equal_aux(_Arg&& __arg)
+	{
+	  return _M_emplace_equal_kv(
+	_S_forward_key(_KeyOfValue{}(std::forward<_Arg>(__arg))),
+	std::forward<_Arg>(__arg));
+	}
+
   template
 	pair
 	_M_emplace_unique(_Arg&& __arg)
@@ -1237,6 +1254,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	pair
 	_M_emplace_unique(_Args&&... __args);
 
+  template
+	iterator
+	_M_emplace_equal(_Arg&& __arg)
+	{
+	  using __to_value = _ConvertToValueType<_KeyOfValue, value_type>;
+	  return _M_emplace_equal_aux(__to_value{}(std::forward<_Arg>(__arg)));
+	}
+
   template
 	iterator
 	_M_emplace_equal(_Args&&... __args);
@@ -2355,6 +2380,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return _Res(__x, __y);
 	return _Res(__j._M_node, 0);
   }
+
+  template
+template
+  auto
+  _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+  _M_get_insert_equal_pos_tr(const _Kt& __k)
+  -> pair<_Base_ptr, _Base_ptr>
+  {
+	typedef pair<_Base_ptr, _Base_ptr> _Res;
+	_Link_type __x = _M_begin();
+	_Base_ptr __y = _M_end();
+	while (__x != 0)
+	  {
+	__y = __x;
+	__x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
+	  _S_left(__x) : _S_right(__x);
+	  }
+	return _Res(__x, __y);
+  }
 #endif
 
   template
+template
+  auto
+  _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+  _M_emplace_equal_kv(_Kt&& __k, _Arg&& __arg)
+  -> iterator
+  {
+	auto __res = _M_get_insert_equal_pos_tr(__k);
+	_Auto_node __z =
+	  (!is_nothrow_copy_constructible::value
+	   || __res.second == _M_end()
+	   || _M_impl._M_key_compare(__k, _S_key(__res.second)))
+	  ? _S_build_node(*this, std::forward<_Kt>(__k),
+			  std::forward<_Arg>(__arg), _KeyOfValue{})
+	  : _S_build_node(*this, _S_key(__res.second),
+			  std::forward<_Arg>(__arg), _KeyOfValue{});
+	return __z._M_insert(__res);
+  }
+
   template
 template
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/96088.cc b/libstdc++-v3/testsuite/23_containers/multimap/96088.cc
index 919c5e59c71..1a778a0785d 100644
--- a/libstdc++-v3/testsuite/23_containers/multimap/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/multimap/96088.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++17 } }
+// { dg-add-options no_pch }
 // { dg-require-effective-target std_allocator_new }
 
 // Copyright (C) 2023 Free Software Foundation, Inc.
@@ -20,6 +21,9 @@
 
 // libstdc++/96088
 
+#undef _GLIBCXX_USE_CXX11_ABI
+#define _GLIBCXX_USE_CXX11_ABI 0
+
 #include 
 #include 
 #include 
@@ -42,6 +46,15 @@ test01()
 
   VERIFY( __gnu_test::counter::count() 

[PATCH] libstdc++: Limit allocations in _Rb_tree 1/2

2023-02-21 Thread François Dumont via Gcc-patches

Here is eventually a working proposal.

Compared to the unordered container approach we need to find out what 
type is going to be used to call the comparer. Otherwise we might 
reinstantiate a temporary each time we call the comparer. For example in 
case of const char* insertion with a less comparer we would 
create a string_view instance on each comparer call and so each time do 
a strlen.


This code is tricky and do not cover all use cases. For those uncovered 
cases the default behavior is to create a key_type instance which will 
be moved to storage if needed.


Is there any plan to create a builtin function to get help from the 
compiler to find out this type ? Something like std::invoke_result but 
giving also the actual argument types.


    libstdc++: [_Rb_tree] Limit allocations on unique insertions [PR 96088]

    Detect when invoking the comparer requires an allocation using the 
noexcept
    qualification of the functor. In this case guess the type needed to 
invoke
    the comparer and create a temporary instance used for all comparer 
invocations.
    This temporary instance will be eventually moved to storage 
location if it is to
    insert. Avoid to allocate a node and construct the stored value 
otherwise.


    libstdc++-v3/ChangeLog:

    PR libstdc++/96088
    * include/bits/stl_function.h
    (std::less<>::operator()): Add noexcept qualification.
    (std::greater::operator()): Likewise.
(std::_Identity<>::operator<_Tp2>(_Tp2&&)): New perfect forwarding operator.
(std::_Select1st<>::operator<_Pair2>(_Pair2&&)): New move operator.
    * include/bits/stl_tree.h 
(_Rb_tree<>::_ConvertToValueType<>): New helper type.

    (_Rb_tree<>::__has_firstargument): Likewise.
    (_Rb_tree<>::_S_get_key_type_aux): New helper method, use 
latter.

    (_Rb_tree<>::_S_get_key_type): New helper method, use latter.
    (_Rb_tree<>::__key_type_t): New.
    (_Rb_tree<>::__is_comparable_lhs): New.
    (_Rb_tree<>::__is_comparable_rhs): New.
    (_Rb_tree<>::__is_comparable): New, use latters.
    (_Rb_tree<>::__is_nothrow_comparable_lhs): New.
    (_Rb_tree<>::__is_nothrow_comparable_rhs): New.
    (_Rb_tree<>::__is_nothrow_comparable): New, use latters.
    (_Rb_tree<>::_S_forward_key): New.
    (_Rb_tree<>::_M_get_insert_unique_pos_tr): New.
    (_Rb_tree<>::_M_emplace_unique_kv): New.
    (_Rb_tree<>::_M_emplace_unique_aux): New, use latter.
    (_Rb_tree<>::_M_emplace_unique): New, use latter.
    (_Rb_tree<>::_Auto_node::_S_build): New.
    * testsuite/23_containers/map/96088.cc: New test case.
    * testsuite/23_containers/multimap/96088.cc: New test case.
    * testsuite/23_containers/multiset/96088.cc: New test case.
    * testsuite/23_containers/set/96088.cc: New test case.

François
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index fa03f32b1b8..f8817e2f6ae 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -395,6 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX14_CONSTEXPR
   bool
   operator()(const _Tp& __x, const _Tp& __y) const
+	_GLIBCXX_NOEXCEPT_IF( noexcept(__x > __y) )
   { return __x > __y; }
 };
 
@@ -405,6 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX14_CONSTEXPR
   bool
   operator()(const _Tp& __x, const _Tp& __y) const
+	_GLIBCXX_NOEXCEPT_IF( noexcept(__x < __y) )
   { return __x < __y; }
 };
 
@@ -1165,6 +1167,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const _Tp&
   operator()(const _Tp& __x) const
   { return __x; }
+
+#if __cplusplus >= 201103L
+template
+  _Tp2&&
+  operator()(_Tp2&& __x) const noexcept
+  { return std::forward<_Tp2>(__x); }
+#endif
 };
 
   // Partial specialization, avoids confusing errors in e.g. std::set.
@@ -1183,15 +1192,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { return __x.first; }
 
 #if __cplusplus >= 201103L
+private:
   template
-typename _Pair2::first_type&
-operator()(_Pair2& __x) const
-{ return __x.first; }
+	struct __1st_type
+	{ using type = typename _Pair2::first_type; };
+
+  template
+	struct __1st_type>
+	{ using type = _Tp; };
 
+  template
+	struct __1st_type>
+	{ using type = const _Tp; };
+
+  template
+	struct __1st_type<_Pair2&>
+	{ using type = typename __1st_type<_Pair2>::type&; };
+
+public:
   template
-const typename _Pair2::first_type&
-operator()(const _Pair2& __x) const
-{ return __x.first; }
+	typename __1st_type<_Pair2>::type&&
+	operator()(_Pair2&& __x) const noexcept
+	{ return std::forward<_Pair2>(__x).first; }
 #endif
 };
 
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 3c331fbc952..5dae42a504c 100644

Re: [PATCH] [libstdc++] ensure mutex_pool survives _Safe_sequence_base

2023-02-17 Thread François Dumont via Gcc-patches

On 17/02/23 09:01, Alexandre Oliva via Libstdc++ wrote:

On Feb 17, 2023, Alexandre Oliva  wrote:


On vxworks, after destroying the semaphore used to implement a mutex,
__gthread_mutex_lock fails and __gnu_cxx::__mutex::lock calls
__throw_concurrence_lock_error.  Nothing ensures the mutex_pool
mutexes survive init-once objects containing _Safe_sequence_base.  If
such an object completes construction before mutex_pool
initialization, it will be registered for atexit destruction after the
mutex_pool mutexes, so the _M_detach_all() call in the
_Safe_sequence_base dtor will use already-destructed mutexes, and
basic_string/requirements/citerators_cc fails calling terminate.

Here's an alternative approach, with zero runtime overhead.  Negative
overhead, if you count the time it would have taken to destruct the
mutex pool :-) But it fails to destruct them, which is presumably of no
consequence.

[libstdc++] do not destruct mutex_pool mutexes

[Copy of the paragraph quoted above omitted here]

This patch fixes this problem by ensuring the mutex pool mutexes are
constructed on demand, on a statically-allocated buffer, but never
destructed.

Regstrapped on x86_64-linux-gnu.
Tested on arm-vxworks7 (gcc-12) and arm-eabi (trunk).  Ok to install?

for  libstdc++-v3/ChangeLog

* src/c++11/shared_ptr.cc (__gnu_internal::get_mutex):
Avoid destruction of the mutex pool.
---
  libstdc++-v3/src/c++11/shared_ptr.cc |6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++11/shared_ptr.cc 
b/libstdc++-v3/src/c++11/shared_ptr.cc
index bc70134359c87..74e879e582896 100644
--- a/libstdc++-v3/src/c++11/shared_ptr.cc
+++ b/libstdc++-v3/src/c++11/shared_ptr.cc
@@ -36,7 +36,11 @@ namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden)
{
  // increase alignment to put each lock on a separate cache line
  struct alignas(64) M : __gnu_cxx::__mutex { };
-static M m[mask + 1];
+// Use a static buffer, so that the mutexes are not destructed
+// before potential users (or at all)

I guess you meant 'before potential use'

+static __attribute__ ((aligned(__alignof__(M
+  char buffer[(sizeof (M)) * (mask + 1)];
+static M *m = new (buffer) M[mask + 1];
  return m[i];
}
  }





Re: [PATCH] minor optimization bug in basic_string move assignment

2023-02-04 Thread François Dumont via Gcc-patches

On 03/02/23 15:50, Jonathan Wakely wrote:

On Wed, 25 Jan 2023 at 18:38, François Dumont  wrote:

Let's submit a proper patch proposal then.

The occasion for me to ask if there is any reason for cow string not
being C++11 allocator compliant ? Just lack of interest ?

Mostly lack of interest, but also I don't really want to "encourage"
the use of the old string by investing lots of maintenance effort into
it. If you want new features like C++11 Allocators and
resize_and_overwrite etc then you should use the new type.

I don't remember if there were any actual blockers that made it
difficult to support stateful allocators in the COW string. I might
have written something about it in mails to the list when I was adding
the SSO string, but I don't remember now.


Ok, thanks for feedback. I won't bother then.



Anyway, for this patch ...


I wanted to consider it to get rid of the __gnu_debug::_Safe_container
_IsCxx11AllocatorAware template parameter.

  libstdc++: Optimize basic_string move assignment

  Since resolution of Issue 2593 [1] we can consider that equal
allocators
  before the propagate-on-move-assignment operations will still be equal
  afterward.

  So we can extend the optimization of transfering the storage of the
move-to
  instance to the move-from one that is currently limited to always equal
  allocators.

  [1] https://cplusplus.github.io/LWG/issue2593

  libstdc++-v3/ChangeLog:

  * include/bits/basic_string.h (operator=(basic_string&&)):
Transfer move-to
  storage to the move-from instance when allocators are equal.
  *
testsuite/21_strings/basic_string/allocator/char/move_assign.cc (test04):
  New test case.

Tested under linux x86_64, ok to commit ?

OK for trunk, thanks!

+Reviewed-by: Jonathan Wakely 


Should I have added this to the commit ?

If so sorry, I haven't.



[PATCH] libstdc++: Limit allocations in _Rb_tree

2023-02-02 Thread François Dumont via Gcc-patches

This is PR 96088 but this time for _Rb_tree based containers.

I guess it won't go in for the moment but I wanted to submit it already 
because of the changes I had to do in stl_functions.h. It sounds like 
missing parts for C++11 move-semantic. I still need to run all tests to 
see if they can have side effects.


 libstdc++: [_Rb_tree] Limit allocation on iterator insertion [PR 
96088]


    Detect when invoking the comparer require an allocation and in this 
case
    create a temporary instance that will be moved to storage location 
if the

    insertion eventually takes place. Avoid to allocate a node otherwise.

    libstdc++-v3/ChangeLog:

    PR libstdc++/96088
    * include/bits/stl_function.h
    (std::less<>::operator()): Add noexcept qualification.
    (std::greater::operator()): Likewise.
(std::_Identity<>::operator<_Tp2>(_Tp2&&)): New perfect forwarding operator.
(std::_Select1st<>::operator<_Pair2>(_Pair2&&)): New move operator.
    * include/bits/stl_tree.h 
(_Rb_tree<>::_ConvertToValueType<>): New helper type.

    (_Rb_tree<>::_M_get_insert_unique_pos_tr): New.
    (_Rb_tree<>::_S_forward_key): New.
    (_Rb_tree<>::_M_emplace_unique_kv): New.
    (_Rb_tree<>::_M_emplace_unique_aux): New, use latter.
    (_Rb_tree<>::_M_emplace_unique): New, use latter.
    * testsuite/23_containers/map/96088.cc: New test case.
    * testsuite/23_containers/multimap/96088.cc: New test case.
    * testsuite/23_containers/multiset/96088.cc: New test case.
    * testsuite/23_containers/set/96088.cc: New test case.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index fa03f32b1b8..5e04c82629b 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -395,6 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX14_CONSTEXPR
   bool
   operator()(const _Tp& __x, const _Tp& __y) const
+	_GLIBCXX_NOEXCEPT_IF( noexcept(__x > __y) )
   { return __x > __y; }
 };
 
@@ -405,6 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX14_CONSTEXPR
   bool
   operator()(const _Tp& __x, const _Tp& __y) const
+	_GLIBCXX_NOEXCEPT_IF( noexcept(__x < __y) )
   { return __x < __y; }
 };
 
@@ -1165,6 +1167,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const _Tp&
   operator()(const _Tp& __x) const
   { return __x; }
+
+#if __cplusplus >= 201103L
+template
+  _Tp2&&
+  operator()(_Tp2&& __x) const noexcept
+  { return std::forward<_Tp2>(__x); }
+#endif
 };
 
   // Partial specialization, avoids confusing errors in e.g. std::set.
@@ -1192,6 +1201,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	const typename _Pair2::first_type&
 	operator()(const _Pair2& __x) const
 	{ return __x.first; }
+
+  template
+	typename _Pair2::first_type&&
+	operator()(_Pair2&& __x) const
+	{ return std::move(__x.first); }
 #endif
 };
 
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 3c331fbc952..8096ba97f18 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -534,6 +534,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_Rb_tree& _M_t;
   };
 
+#if __cplusplus >= 201103L
+  template
+	struct _ConvertToValueType;
+
+  template
+	struct _ConvertToValueType, _Value>
+	{
+	  template
+	constexpr _Kt&&
+	operator()(_Kt&& __k) const noexcept
+	{ return std::forward<_Kt>(__k); }
+	};
+
+  template
+	struct _ConvertToValueType, _Value>
+	{
+	  constexpr _Value&&
+	  operator()(_Value&& __x) const noexcept
+	  { return std::move(__x); }
+
+	  constexpr const _Value&
+	  operator()(const _Value& __x) const noexcept
+	  { return __x; }
+
+	  template
+	constexpr std::pair<_Kt, _Vt>&&
+	operator()(std::pair<_Kt, _Vt>&& __x) const noexcept
+	{ return std::move(__x); }
+
+	  template
+	constexpr const std::pair<_Kt, _Vt>&
+	operator()(const std::pair<_Kt, _Vt>& __x) const noexcept
+	{ return __x; }
+  };
+#endif // C++11
+
 public:
   typedef _Key key_type;
   typedef _Val value_type;
@@ -830,6 +866,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   pair<_Base_ptr, _Base_ptr>
   _M_get_insert_unique_pos(const key_type& __k);
 
+#if __cplusplus >= 201103L
+  template
+	pair<_Base_ptr, _Base_ptr>
+	_M_get_insert_unique_pos_tr(const _Kt& __k);
+#endif
+
   pair<_Base_ptr, _Base_ptr>
   _M_get_insert_equal_pos(const key_type& __k);
 
@@ -1075,6 +1117,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an);
 	}
 
+  template
+	static __conditional_t<
+	__and_<__is_nothrow_invocable<_Compare&,
+  const key_type&, const key_type&>,
+	   __not_<__is_nothrow_invocable<_Compare&,
+	 _Kt, const key_type&>>>::value,
+	  key_type, _Kt&&>
+	

[PATCH] minor optimization bug in basic_string move assignment

2023-01-25 Thread François Dumont via Gcc-patches

Let's submit a proper patch proposal then.

The occasion for me to ask if there is any reason for cow string not 
being C++11 allocator compliant ? Just lack of interest ?


I wanted to consider it to get rid of the __gnu_debug::_Safe_container 
_IsCxx11AllocatorAware template parameter.


    libstdc++: Optimize basic_string move assignment

    Since resolution of Issue 2593 [1] we can consider that equal 
allocators

    before the propagate-on-move-assignment operations will still be equal
    afterward.

    So we can extend the optimization of transfering the storage of the 
move-to

    instance to the move-from one that is currently limited to always equal
    allocators.

    [1] https://cplusplus.github.io/LWG/issue2593

    libstdc++-v3/ChangeLog:

    * include/bits/basic_string.h (operator=(basic_string&&)): 
Transfer move-to

    storage to the move-from instance when allocators are equal.
    * 
testsuite/21_strings/basic_string/allocator/char/move_assign.cc (test04):

    New test case.

Tested under linux x86_64, ok to commit ?

François


On 17/01/23 20:18, Jonathan Wakely wrote:

On Wed, 4 Jan 2023 at 18:21, François Dumont via Libstdc++
 wrote:

On 04/01/23 00:11, waffl3x via Libstdc++ wrote:

Example: https://godbolt.org/z/sKhGqG1qK
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/bits/basic_string.h;hb=HEAD#l880
When move assigning to a basic_string, the allocated memory of the moved into 
string is stored into the source string instead of deallocating it, a good 
optimization when everything is compatible. However in the case of a stateful 
allocator (is_always_true() evaluating as false) this optimization is never 
taken. Unless there is some reason I can't think of that makes equal stateful 
allocators incompatible here, I believe the if statement on line 880 of 
basic_string.h should also compare the equality of each strings allocator. The 
first condition in the function seems to indicate to me that this scenario was 
being considered and just forgotten about, as the memory doesn't get 
deallocated immediately if the two allocators are equal. I'll note that because 
of how everything is handled, this doesn't result in a leak so this bug is 
still only a minor missed optimization.

mailto:libstd...@gcc.gnu.org

Hmmm, I don't know, at least it is not as simple as you present it.

You cannot add a check on allocator equality as you are proposing
because it is too late. __str allocator might have already been
propagated to *this on the previous call to std::__alloc_on_move. Note
that current check is done only if
!_Alloc_traits::_S_propagate_on_move_assign().

This patch might do the job but I wonder if equal allocators can become
un-equal after the propagate-on-move-assignment ?

Since https://cplusplus.github.io/LWG/issue2593 they can't. But I
think when I wrote that code, they could do, which is probably why the
optimization wasn't done.

diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index aa018262c98..c81dc0d425a 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -844,9 +844,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   operator=(basic_string&& __str)
   noexcept(_Alloc_traits::_S_nothrow_move())
   {
+	const bool __equal_allocs = _Alloc_traits::_S_always_equal()
+	  || _M_get_allocator() == __str._M_get_allocator();
 	if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign()
-	&& !_Alloc_traits::_S_always_equal()
-	&& _M_get_allocator() != __str._M_get_allocator())
+	&& !__equal_allocs)
 	  {
 	// Destroy existing storage before replacing allocator.
 	_M_destroy(_M_allocated_capacity);
@@ -868,16 +869,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 		_M_set_length(__str.size());
 	  }
 	  }
-	else if (_Alloc_traits::_S_propagate_on_move_assign()
-	|| _Alloc_traits::_S_always_equal()
-	|| _M_get_allocator() == __str._M_get_allocator())
+	else if (_Alloc_traits::_S_propagate_on_move_assign() || __equal_allocs)
 	  {
 	// Just move the allocated pointer, our allocator can free it.
 	pointer __data = nullptr;
 	size_type __capacity;
 	if (!_M_is_local())
 	  {
-		if (_Alloc_traits::_S_always_equal())
+		if (__equal_allocs)
 		  {
 		// __str can reuse our existing storage.
 		__data = _M_data();
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
index cc58348e116..21e0b1cb4f4 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/move_assign.cc
@@ -28,6 +28,8 @@ const C c = 'a';
 using traits = std::char_traits;
 
 using __gnu_test::propagating_allocator;
+using __gnu_test::tracker_allocator_counter;
+using __gnu_test::tracker_allocator;
 
 void 

Re: [PATCH][_GLIBCXX_DEBUG] Remove useless checks

2023-01-23 Thread François Dumont via Gcc-patches

On 23/01/23 10:22, Jonathan Wakely wrote:

On Mon, 23 Jan 2023 at 06:02, François Dumont via Libstdc++
 wrote:

  libstdc++: [_GLIBCXX_DEBUG] Remove useless constructor checks

  Creating a safe iterator from a normal iterator is done within the
library where we
  already know that it is done correctly. The rare situation where a
user would use safe
  iterators for his own purpose is non-Standard code so outside
_GLIBCXX_DEBUG scope. For
  those reasons the __msg_init_singular is useless and can be removed.

  Additionally in the copy constructor used for post-increment and
post-decrement operators
  the __msg_init_copy_singular check can also be ommitted because of
the preliminary
  __msg_bad_inc and __msg_bad_dec checks.

  libstdc++-v3/ChangeLog:

  * include/debug/safe_iterator.h
(_Safe_iterator<>::_Unsafe_call): New.

I don't like the name "unsafe call". Why is it unsafe? As you say
above, we don't need to check because we know that it's only called in
a context where it's safe. Can we call it _Unchecked instead of
_Unsafe_call? That seems like a more accurate description of the
behaviour.



  (_Safe_iterator(const _Safe_iterator&, _Unsafe_call): New.
  (_Safe_iterator::operator++(int)): Use latter.
  (_Safe_iterator::operator--(int)): Likewise.
  (_Safe_iterator(_Iterator, const _Safe_sequence_base*)):
Remove !_M_insular()
  check.
  * include/debug/safe_local_iterator.h
(_Safe_local_iterator<>::_Unsafe_call):
  New.
  (_Safe_local_iterator(const _Safe_local_iterator&,
_Unsafe_call): New.
  (_Safe_local_iterator::operator++(int)): Use latter.
  * src/c++11/debug.cc (_S_debug_messages): Add as comment
the _Debug_msg_id
  entry associated to the array entry.

These comments are a great idea, thanks.

If you agree with the _Unchecked name, OK to commit with that change.


It's unsafe because it's unchecked so _Unchecked is fine for me too :-)

Committed with the requested change.

Thanks




[PATCH][_GLIBCXX_DEBUG] Remove useless checks

2023-01-22 Thread François Dumont via Gcc-patches

    libstdc++: [_GLIBCXX_DEBUG] Remove useless constructor checks

    Creating a safe iterator from a normal iterator is done within the 
library where we
    already know that it is done correctly. The rare situation where a 
user would use safe
    iterators for his own purpose is non-Standard code so outside 
_GLIBCXX_DEBUG scope. For

    those reasons the __msg_init_singular is useless and can be removed.

    Additionally in the copy constructor used for post-increment and 
post-decrement operators
    the __msg_init_copy_singular check can also be ommitted because of 
the preliminary

    __msg_bad_inc and __msg_bad_dec checks.

    libstdc++-v3/ChangeLog:

    * include/debug/safe_iterator.h 
(_Safe_iterator<>::_Unsafe_call): New.

    (_Safe_iterator(const _Safe_iterator&, _Unsafe_call): New.
    (_Safe_iterator::operator++(int)): Use latter.
    (_Safe_iterator::operator--(int)): Likewise.
    (_Safe_iterator(_Iterator, const _Safe_sequence_base*)): 
Remove !_M_insular()

    check.
    * include/debug/safe_local_iterator.h 
(_Safe_local_iterator<>::_Unsafe_call):

    New.
    (_Safe_local_iterator(const _Safe_local_iterator&, 
_Unsafe_call): New.

    (_Safe_local_iterator::operator++(int)): Use latter.
    * src/c++11/debug.cc (_S_debug_messages): Add as comment 
the _Debug_msg_id

    entry associated to the array entry.

Tested under Linux x64.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index f364477a00c..570c826649f 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -129,6 +129,12 @@ namespace __gnu_debug
 	typename _Sequence::_Base::iterator,
 	typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
 
+  struct _Unsafe_call { };
+
+  _Safe_iterator(const _Safe_iterator& __x, _Unsafe_call) _GLIBCXX_NOEXCEPT
+  : _Iter_base(__x.base()), _Safe_base()
+  { _M_attach(__x._M_sequence); }
+
 public:
   typedef _Iterator	iterator_type;
   typedef typename _Traits::iterator_category	iterator_category;
@@ -154,11 +160,7 @@ namespace __gnu_debug
   _Safe_iterator(_Iterator __i, const _Safe_sequence_base* __seq)
   _GLIBCXX_NOEXCEPT
   : _Iter_base(__i), _Safe_base(__seq, _S_constant())
-  {
-	_GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
-			  _M_message(__msg_init_singular)
-			  ._M_iterator(*this, "this"));
-  }
+  { }
 
   /**
* @brief Copy construction.
@@ -339,7 +341,7 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	_Safe_iterator __ret = *this;
+	_Safe_iterator __ret(*this, _Unsafe_call());
 	++*this;
 	return __ret;
   }
@@ -514,6 +516,13 @@ namespace __gnu_debug
 protected:
   typedef typename _Safe_base::_OtherIterator _OtherIterator;
 
+  typedef typename _Safe_base::_Unsafe_call _Unsafe_call;
+
+  _Safe_iterator(const _Safe_iterator& __x,
+		 _Unsafe_call __unsafe_call) _GLIBCXX_NOEXCEPT
+	: _Safe_base(__x, __unsafe_call)
+  { }
+
 public:
   /// @post the iterator is singular and unattached
   _Safe_iterator() _GLIBCXX_NOEXCEPT { }
@@ -596,7 +605,7 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	_Safe_iterator __ret = *this;
+	_Safe_iterator __ret(*this, _Unsafe_call());
 	++*this;
 	return __ret;
   }
@@ -627,7 +636,7 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
 			  _M_message(__msg_bad_dec)
 			  ._M_iterator(*this, "this"));
-	_Safe_iterator __ret = *this;
+	_Safe_iterator __ret(*this, _Unsafe_call());
 	--*this;
 	return __ret;
   }
@@ -653,6 +662,12 @@ namespace __gnu_debug
   typedef _Safe_iterator<_OtherIterator, _Sequence,
 			 std::random_access_iterator_tag> _OtherSelf;
 
+  typedef typename _Safe_base::_Unsafe_call _Unsafe_call;
+  _Safe_iterator(const _Safe_iterator& __x,
+		 _Unsafe_call __unsafe_call) _GLIBCXX_NOEXCEPT
+	: _Safe_base(__x, __unsafe_call)
+  { }
+
 public:
   typedef typename _Safe_base::difference_type	difference_type;
   typedef typename _Safe_base::reference		reference;
@@ -744,7 +759,7 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	_Safe_iterator __ret = *this;
+	_Safe_iterator __ret(*this, _Unsafe_call());
 	++*this;
 	return __ret;
   }
@@ -771,7 +786,7 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
 			  _M_message(__msg_bad_dec)
 			  ._M_iterator(*this, "this"));
-	_Safe_iterator __ret = *this;
+	_Safe_iterator __ret(*this, _Unsafe_call());
 	--*this;
 	return 

Re: [PATCH] Use cxx11 abi in versioned namespace

2023-01-16 Thread François Dumont via Gcc-patches

On 13/01/23 18:15, Jonathan Wakely wrote:

@@ -396,7 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Non-inline namespace for components replaced by alternates in active 
mode.
namespace __cxx1998
{
-# if _GLIBCXX_USE_CXX11_ABI
+# if _GLIBCXX_USE_CXX11_ABI && ! _GLIBCXX_VERSION_NAMESPACE

This should be INLINE not VERSION, right?


Indeed, I haven't tested the _GLIBCXX_DEBUG mode.



Re: [PATCH] Use cxx11 abi in versioned namespace

2023-01-16 Thread François Dumont via Gcc-patches

On 13/01/23 18:06, Jonathan Wakely wrote:

On Fri, 13 Jan 2023 at 16:33, Jonathan Wakely  wrote:

On Mon, 5 Dec 2022 at 21:14, François Dumont via Libstdc++
 wrote:

I just rebased this patch.

All good apart from the to_chars/from_chars symbols issue.

François


On 11/10/22 19:28, François Dumont wrote:

Hi

 Now that pretty printer is fixed (once patch validated) I'd like
to propose this patch again.

 Note that I'am adding a check on pretty printer with a std::any on
a std::wstring. I did so because of the FIXME in printers.py which is
dealing with 'std::string' explicitely. Looks like in my case, where
there is no 'std::string' but just a 'std::__8::string' we do not need
the workaround.

 Once again I am attaching also the version namespace bump patch as
I think that adopting the cxx11 abi in this mode is a good enough
reason to bump it. If you agress let me know if I should squash the
commits before pushing.

Yes, I think this change would justify bumping the version.


 libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi

 Use cxx11 abi when activating versioned namespace mode.

 libstdcxx-v3/ChangeLog:

 * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
Default to "new" libstdcxx abi.
 * config/locale/dragonfly/monetary_members.cc
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base
 members.
 * config/locale/generic/monetary_members.cc
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
 * config/locale/gnu/monetary_members.cc
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
 * config/locale/gnu/numeric_members.cc
 [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
 * configure: Regenerate.
 * include/bits/c++config
 [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
_GLIBCXX_BEGIN_NAMESPACE_CXX11): Define
 empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
_GLIBCXX_DEFAULT_ABI_TAG): Likewise.
 * python/libstdcxx/v6/printers.py
 (StdStringPrinter::__init__): Set self.new_string to True
when std::__8::basic_string type is
 found.
 * src/Makefile.am
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
 * src/Makefile.in: Regenerate.
 * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
 (dual_abi_sources): ...this, new. Also move several
sources to...
 (sources): ...this.
 (extra_string_inst_sources): Move several sources to...
 (inst_sources): ...this.

I don't understand this part. Moving those files to sources and
inst_sources will mean they are always compiled, right? But we don't
want them compiled for --disable-libstdcxx-dual-abi

In those files you've changed the #if conditions so they are empty if
the dual ABI is disabled, but why do they need to be compiled at all?
This isn't clear from the patch or the description or the changelog.



 * src/c++11/Makefile.in: Regenerate.
 * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-stdexcept.cc
[_GLIBCXX_USE_CXX11_ABI](error_category::_M_message):
 Skip definition.
 [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
definitions.
 * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-string-io-inst.cc
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-wstring-io-inst.cc
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cxx11-ios_failure.cc
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.

For this file I think your changes make sense, because the definitions
of the gcc4-compatible and cxx11 ABI are different, we're not just
compiling it twice.



 * src/c++11/cxx11-locale-inst.cc: Cleanup, just include
locale-inst.cc.
 * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 [!_GLIBCXX_USE_DUAL_ABI](__cow_string): Remove.
 * src/c++11/cxx11-wlocale-inst.cc
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 * src/c++11/fstream-inst.cc [!_GLIBCXX_USE_CXX11_ABI]:
Skip definitions
 * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet>,
std::use_facet>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet>,
std::has_facet>): Instantiate.
 [!_GLIBCXX_USE_DUAL_ABI](std::num_get>): Instantiate.
 

Re: [PATCH] Use cxx11 abi in versioned namespace

2023-01-16 Thread François Dumont via Gcc-patches

On 13/01/23 17:33, Jonathan Wakely wrote:

On Mon, 5 Dec 2022 at 21:14, François Dumont via Libstdc++
  wrote:

I just rebased this patch.

All good apart from the to_chars/from_chars symbols issue.

François


On 11/10/22 19:28, François Dumont wrote:

Hi

 Now that pretty printer is fixed (once patch validated) I'd like
to propose this patch again.

 Note that I'am adding a check on pretty printer with a std::any on
a std::wstring. I did so because of the FIXME in printers.py which is
dealing with 'std::string' explicitely. Looks like in my case, where
there is no 'std::string' but just a 'std::__8::string' we do not need
the workaround.

 Once again I am attaching also the version namespace bump patch as
I think that adopting the cxx11 abi in this mode is a good enough
reason to bump it. If you agress let me know if I should squash the
commits before pushing.

Yes, I think this change would justify bumping the version.


 libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi

 Use cxx11 abi when activating versioned namespace mode.

 libstdcxx-v3/ChangeLog:

 * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]:
Default to "new" libstdcxx abi.
 * config/locale/dragonfly/monetary_members.cc
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base
 members.
 * config/locale/generic/monetary_members.cc
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
 * config/locale/gnu/monetary_members.cc
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
 * config/locale/gnu/numeric_members.cc
 [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
 * configure: Regenerate.
 * include/bits/c++config
 [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11,
_GLIBCXX_BEGIN_NAMESPACE_CXX11): Define
 empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11,
_GLIBCXX_DEFAULT_ABI_TAG): Likewise.
 * python/libstdcxx/v6/printers.py
 (StdStringPrinter::__init__): Set self.new_string to True
when std::__8::basic_string type is
 found.
 * src/Makefile.am
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.
 * src/Makefile.in: Regenerate.
 * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
 (dual_abi_sources): ...this, new. Also move several
sources to...
 (sources): ...this.
 (extra_string_inst_sources): Move several sources to...
 (inst_sources): ...this.

I don't understand this part. Moving those files to sources and
inst_sources will mean they are always compiled, right? But we don't
want them compiled for --disable-libstdcxx-dual-abi

In those files you've changed the #if conditions so they are empty if
the dual ABI is disabled, but why do they need to be compiled at all?
This isn't clear from the patch or the description or the changelog.


--disable-libstdcxx-dual-abi means use cow string implementation. With 
this patch I am introducing somehow another disable-dual-abi mode but 
this time to use cxx11 string implementation.


At Makefile.am level it was difficult to match both cases so I'm doing 
it at compilation time with most of time the condition:


#if ! _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI

I'll make it clearer at ChangeLog level.


 * src/c++11/Makefile.in: Regenerate.
 * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-stdexcept.cc
[_GLIBCXX_USE_CXX11_ABI](error_category::_M_message):
 Skip definition.
 [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS
definitions.
 * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-string-io-inst.cc
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cow-wstring-io-inst.cc
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 * src/c++11/cxx11-ios_failure.cc
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.

For this file I think your changes make sense, because the definitions
of the gcc4-compatible and cxx11 ABI are different, we're not just
compiling it twice.



 * src/c++11/cxx11-locale-inst.cc: Cleanup, just include
locale-inst.cc.
 * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]:
Skip definitions.
 [!_GLIBCXX_USE_DUAL_ABI](__cow_string): Remove.
 * src/c++11/cxx11-wlocale-inst.cc
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
 * 

Re: libstdc++: Fix deadlock in debug iterator increment [PR108288]

2023-01-15 Thread François Dumont via Gcc-patches

Committed with the idiomatic approach.

I'll work on this additional check later.

On 12/01/23 22:35, Jonathan Wakely wrote:

On Thu, 12 Jan 2023 at 18:25, François Dumont  wrote:

On 12/01/23 13:00, Jonathan Wakely wrote:

On Thu, 12 Jan 2023 at 05:52, François Dumont wrote:

Small update for an obvious compilation issue and to review new test
case that could have lead to an infinite loop if the increment issue was
not detected.

I also forgot to ask if there is more chance for the instantiation to be
elided when it is implemented like in the _Safe_local_iterator:
return { __cur, this->_M_sequence };

No, that doesn't make any difference.


than in the _Safe_iterator:
return _Safe_iterator(__cur, this->_M_sequence);

In the case where the user code do not use it ?

Fully tested now, ok to commit ?

François

On 11/01/23 07:03, François Dumont wrote:

Thanks for fixing this.

Here is the extension of the fix to all post-increment/decrement
operators we have on _GLIBCXX_DEBUG iterator.

Thanks, I completely forgot we have other partial specializations, I
just fixed the one that showed a deadlock in the user's example!


I prefer to restore somehow previous implementation to continue to
have _GLIBCXX_DEBUG post operators implemented in terms of normal post
operators.

Why?

Implementing post-increment as:

  auto tmp = *this;
  ++*this;
  return tmp;

is the idiomatic way to write it, and it works fine in this case. I
don't think it performs any more work than your version, does it?
Why not use the idiomatic form?

Is it just so that post-inc of a debug iterator uses post-inc of the
underlying iterator? Why does that matter?


A little yes, but that's a minor reason that is just making me happy.

Main reason is that this form could produce a __msg_init_copy_singular
before the __msg_bad_inc.

Ah yes, I see. That's a shame. I find the idiomatic form much simpler
to read, and it will generate better code (because it just reuses
existing functions, instead of adding new ones).

We could do this though, right?

 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
   _M_message(__msg_bad_inc)
   ._M_iterator(*this, "this"));
 _Safe_iterator __tmp = *this;
 ++*this;
 return __tmp;

That does the VERIFY check twice though.


And moreover I plan to propose a patch later to skip any check in the
call to _Safe_iterator(__cur, _M_sequence) as we already know that __cur
is ok here like anywhere else in the lib.

There will still be one in the constructor normally elided unless
--no-elide-constructors but there is not much I can do about it.

Don't worry about it. Nobody should ever use -fno-elide-constructors
in any real cases (except maybe debugging some very strange corner
cases, and in that case the extra safe iterator checks are not going
to be their biggest problem).

The patch is OK for trunk then.





Re: libstdc++: Fix deadlock in debug iterator increment [PR108288]

2023-01-12 Thread François Dumont via Gcc-patches

On 12/01/23 13:00, Jonathan Wakely wrote:

On Thu, 12 Jan 2023 at 05:52, François Dumont wrote:

Small update for an obvious compilation issue and to review new test
case that could have lead to an infinite loop if the increment issue was
not detected.

I also forgot to ask if there is more chance for the instantiation to be
elided when it is implemented like in the _Safe_local_iterator:
return { __cur, this->_M_sequence };

No, that doesn't make any difference.


than in the _Safe_iterator:
return _Safe_iterator(__cur, this->_M_sequence);

In the case where the user code do not use it ?

Fully tested now, ok to commit ?

François

On 11/01/23 07:03, François Dumont wrote:

Thanks for fixing this.

Here is the extension of the fix to all post-increment/decrement
operators we have on _GLIBCXX_DEBUG iterator.

Thanks, I completely forgot we have other partial specializations, I
just fixed the one that showed a deadlock in the user's example!


I prefer to restore somehow previous implementation to continue to
have _GLIBCXX_DEBUG post operators implemented in terms of normal post
operators.

Why?

Implementing post-increment as:

 auto tmp = *this;
 ++*this;
 return tmp;

is the idiomatic way to write it, and it works fine in this case. I
don't think it performs any more work than your version, does it?
Why not use the idiomatic form?

Is it just so that post-inc of a debug iterator uses post-inc of the
underlying iterator? Why does that matter?


A little yes, but that's a minor reason that is just making me happy.

Main reason is that this form could produce a __msg_init_copy_singular 
before the __msg_bad_inc.


And moreover I plan to propose a patch later to skip any check in the 
call to _Safe_iterator(__cur, _M_sequence) as we already know that __cur 
is ok here like anywhere else in the lib.


There will still be one in the constructor normally elided unless 
--no-elide-constructors but there is not much I can do about it.





Re: libstdc++: Fix deadlock in debug iterator increment [PR108288]

2023-01-11 Thread François Dumont via Gcc-patches
Small update for an obvious compilation issue and to review new test 
case that could have lead to an infinite loop if the increment issue was 
not detected.


I also forgot to ask if there is more chance for the instantiation to be 
elided when it is implemented like in the _Safe_local_iterator:

return { __cur, this->_M_sequence };

than in the _Safe_iterator:
return _Safe_iterator(__cur, this->_M_sequence);

In the case where the user code do not use it ?

Fully tested now, ok to commit ?

François

On 11/01/23 07:03, François Dumont wrote:

Thanks for fixing this.

Here is the extension of the fix to all post-increment/decrement 
operators we have on _GLIBCXX_DEBUG iterator.


I prefer to restore somehow previous implementation to continue to 
have _GLIBCXX_DEBUG post operators implemented in terms of normal post 
operators.


I also plan to remove the debug check in the _Safe_iterator 
constructor from base iterator to avoid the redundant check we have 
now. But I need to make sure first that we are never calling it with 
an unchecked base iterator. And it might not be the right moment to do 
such a change.


    libstdc++: Fix deadlock in debug local_iterator increment [PR108288]

    Complete fix on all _Safe_iterator post-increment and 
post-decrement implementations

    and on _Safe_local_iterator.

    libstdc++-v3/ChangeLog:

    * include/debug/safe_iterator.h 
(_Safe_iterator<>::operator++(int)): Extend deadlock fix to

    other iterator category.
    (_Safe_iterator<>::operator--(int)): Likewise.
    * include/debug/safe_local_iterator.h 
(_Safe_local_iterator<>::operator++(int)): Fix deadlock.
    * testsuite/util/debug/unordered_checks.h 
(invalid_local_iterator_pre_increment): New.

    (invalid_local_iterator_post_increment): New.
    * 
testsuite/23_containers/unordered_map/debug/invalid_local_iterator_post_increment_neg.cc:

    New test.
    * 
testsuite/23_containers/unordered_map/debug/invalid_local_iterator_pre_increment_neg.cc:

    New test.

Tested under Linux x86_64.

Ok to commit ?

François

On 06/01/23 12:54, Jonathan Wakely via Libstdc++ wrote:

Tested x86_64-linux. Pushed to trunk.

I think we should backport this too, after some soak time on trunk.

-- >8 --

With -fno-elide-constructors the debug iterator post-increment and
post-decrement operators are susceptible to deadlock. They take a mutex
lock and then return a temporary, which also attempts to take a lock to
attach itself to the sequence. If the return value and *this happen to
Note that the chosen mutex depends on the sequence so there is no need 
for conditional sentense here, it will necessarily be the same mutex.

collide and use the same mutex from the pool, then you get a deadlock
trying to lock a mutex that is already held by the current thread.


diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index f9068eaf8d6..f8b46826b7c 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -129,14 +129,6 @@ namespace __gnu_debug
 	typename _Sequence::_Base::iterator,
 	typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
 
-  struct _Attach_single
-  { };
-
-  _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
-  _GLIBCXX_NOEXCEPT
-  : _Iter_base(__i)
-  { _M_attach_single(__seq); }
-
 public:
   typedef _Iterator	iterator_type;
   typedef typename _Traits::iterator_category	iterator_category;
@@ -347,8 +339,13 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
-	return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
+	_Iter_base __cur;
+	{
+	  __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+	  __cur = base()++;
+	}
+
+	return _Safe_iterator(__cur, this->_M_sequence);
   }
 
   // -- Utilities --
@@ -520,12 +517,6 @@ namespace __gnu_debug
 
 protected:
   typedef typename _Safe_base::_OtherIterator _OtherIterator;
-  typedef typename _Safe_base::_Attach_single _Attach_single;
-
-  _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
-  _GLIBCXX_NOEXCEPT
-  : _Safe_base(__i, __seq, _Attach_single())
-  { }
 
 public:
   /// @post the iterator is singular and unattached
@@ -609,9 +600,13 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
-	return _Safe_iterator(this->base()++, this->_M_sequence,
-			  _Attach_single());
+	_Iterator __cur;
+	{
+	  __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+	  __cur = this->base()++;
+	}
+
+	return _Safe_iterator(__cur, 

Re: [committed] libstdc++: Fix deadlock in debug iterator increment [PR108288]

2023-01-10 Thread François Dumont via Gcc-patches

Thanks for fixing this.

Here is the extension of the fix to all post-increment/decrement 
operators we have on _GLIBCXX_DEBUG iterator.


I prefer to restore somehow previous implementation to continue to have 
_GLIBCXX_DEBUG post operators implemented in terms of normal post operators.


I also plan to remove the debug check in the _Safe_iterator constructor 
from base iterator to avoid the redundant check we have now. But I need 
to make sure first that we are never calling it with an unchecked base 
iterator. And it might not be the right moment to do such a change.


    libstdc++: Fix deadlock in debug local_iterator increment [PR108288]

    Complete fix on all _Safe_iterator post-increment and 
post-decrement implementations

    and on _Safe_local_iterator.

    libstdc++-v3/ChangeLog:

    * include/debug/safe_iterator.h 
(_Safe_iterator<>::operator++(int)): Extend deadlock fix to

    other iterator category.
    (_Safe_iterator<>::operator--(int)): Likewise.
    * include/debug/safe_local_iterator.h 
(_Safe_local_iterator<>::operator++(int)): Fix deadlock.
    * testsuite/util/debug/unordered_checks.h 
(invalid_local_iterator_pre_increment): New.

    (invalid_local_iterator_post_increment): New.
    * 
testsuite/23_containers/unordered_map/debug/invalid_local_iterator_post_increment_neg.cc:

    New test.
    * 
testsuite/23_containers/unordered_map/debug/invalid_local_iterator_pre_increment_neg.cc:

    New test.

Tested under Linux x86_64.

Ok to commit ?

François

On 06/01/23 12:54, Jonathan Wakely via Libstdc++ wrote:

Tested x86_64-linux. Pushed to trunk.

I think we should backport this too, after some soak time on trunk.

-- >8 --

With -fno-elide-constructors the debug iterator post-increment and
post-decrement operators are susceptible to deadlock. They take a mutex
lock and then return a temporary, which also attempts to take a lock to
attach itself to the sequence. If the return value and *this happen to
Note that the chosen mutex depends on the sequence so there is no need 
for conditional sentense here, it will necessarily be the same mutex.

collide and use the same mutex from the pool, then you get a deadlock
trying to lock a mutex that is already held by the current thread.
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index f9068eaf8d6..e7c96d1af27 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -129,14 +129,6 @@ namespace __gnu_debug
 	typename _Sequence::_Base::iterator,
 	typename _Sequence::_Base::const_iterator>::__type _OtherIterator;
 
-  struct _Attach_single
-  { };
-
-  _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
-  _GLIBCXX_NOEXCEPT
-  : _Iter_base(__i)
-  { _M_attach_single(__seq); }
-
 public:
   typedef _Iterator	iterator_type;
   typedef typename _Traits::iterator_category	iterator_category;
@@ -347,8 +339,13 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
-	return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
+	_Iter_base __cur;
+	{
+	  __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+	  __cur = base()++;
+	}
+
+	return _Safe_iterator(__cur, this->_M_sequence);
   }
 
   // -- Utilities --
@@ -520,12 +517,6 @@ namespace __gnu_debug
 
 protected:
   typedef typename _Safe_base::_OtherIterator _OtherIterator;
-  typedef typename _Safe_base::_Attach_single _Attach_single;
-
-  _Safe_iterator(_Iterator __i, _Safe_sequence_base* __seq, _Attach_single)
-  _GLIBCXX_NOEXCEPT
-  : _Safe_base(__i, __seq, _Attach_single())
-  { }
 
 public:
   /// @post the iterator is singular and unattached
@@ -609,9 +600,13 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
 			  _M_message(__msg_bad_inc)
 			  ._M_iterator(*this, "this"));
-	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
-	return _Safe_iterator(this->base()++, this->_M_sequence,
-			  _Attach_single());
+	_Iter_base __cur;
+	{
+	  __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+	  __cur = this->base()++;
+	}
+
+	return _Safe_iterator(__cur, this->_M_sequence);
   }
 
   // -- Bidirectional iterator requirements --
@@ -640,9 +635,13 @@ namespace __gnu_debug
 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
 			  _M_message(__msg_bad_dec)
 			  ._M_iterator(*this, "this"));
-	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
-	return _Safe_iterator(this->base()--, this->_M_sequence,
-			  _Attach_single());
+	_Iter_base __cur;
+	{
+	  __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
+	  __cur = this->base()--;
+	}
+
+	return _Safe_iterator(__cur, 

Re: [PATCH] PR 107189 Remove useless _Alloc_node

2023-01-04 Thread François Dumont via Gcc-patches

Still no chance to review ?

On 14/11/22 18:56, François Dumont wrote:

Gentle reminder.

Sorry if I should have committed it as trivial but I cannot do it 
anymore now that I asked :-)



On 12/10/22 22:18, François Dumont wrote:

libstdc++: Remove _Alloc_node instance in _Rb_tree [PR107189]

    libstdc++-v3/ChangeLog:

    PR libstdc++/107189
    * include/bits/stl_tree.h 
(_Rb_tree<>::_M_insert_range_equal): Remove

    unused _Alloc_node instance.

Ok to commit ?

François



diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index a4de6141765..33d25089a1d 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1123,7 +1123,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__enable_if_t::value>
 	_M_insert_range_equal(_InputIterator __first, _InputIterator __last)
 	{
-	  _Alloc_node __an(*this);
 	  for (; __first != __last; ++__first)
 	_M_emplace_equal(*__first);
 	}


Re: [PATCH] libstdc++: Add error handler for

2022-12-07 Thread François Dumont via Gcc-patches

Looks perfect to me, thanks.

On 06/12/22 22:44, Jonathan Wakely wrote:

On Wed, 30 Nov 2022 at 18:00, François Dumont  wrote:

On 30/11/22 14:07, Jonathan Wakely wrote:

On Wed, 30 Nov 2022 at 11:57, Jonathan Wakely  wrote:


On Wed, 30 Nov 2022 at 11:54, Jonathan Wakely  wrote:


On Wed, 30 Nov 2022 at 06:04, François Dumont via Libstdc++ 
 wrote:

Good catch, then we also need this patch.

Is it worth printing an error? If we can't show the backtrace because of an 
error, we can just print nothing there.

No strong opinion on that but if we do not print anything the output
will be:

Backtrace:

Error: ...

I just considered that it did not cost much to report the issue to the
user that defined _GLIBCXX_DEBUG_BACKTRACE and so is expecting a backtrace.

Maybe printing "Backtrace:\n" could be done in the normal callback
leaving the user with the feeling that _GLIBCXX_DEBUG_BACKTRACE does not
work.

OK, how's this?

Tested x86_64-linux.





Re: [PATCH] Use cxx11 abi in versioned namespace

2022-12-05 Thread François Dumont via Gcc-patches

I just rebased this patch.

All good apart from the to_chars/from_chars symbols issue.

François


On 11/10/22 19:28, François Dumont wrote:

Hi

    Now that pretty printer is fixed (once patch validated) I'd like 
to propose this patch again.


    Note that I'am adding a check on pretty printer with a std::any on 
a std::wstring. I did so because of the FIXME in printers.py which is 
dealing with 'std::string' explicitely. Looks like in my case, where 
there is no 'std::string' but just a 'std::__8::string' we do not need 
the workaround.


    Once again I am attaching also the version namespace bump patch as 
I think that adopting the cxx11 abi in this mode is a good enough 
reason to bump it. If you agress let me know if I should squash the 
commits before pushing.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi

    Use cxx11 abi when activating versioned namespace mode.

    libstdcxx-v3/ChangeLog:

    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: 
Default to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11): Define

    empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG): Likewise.

    * python/libstdcxx/v6/printers.py
    (StdStringPrinter::__init__): Set self.new_string to True 
when std::__8::basic_string type is

    found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this, new. Also move several 
sources to...

    (sources): ...this.
    (extra_string_inst_sources): Move several sources to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc 
[_GLIBCXX_USE_CXX11_ABI](error_category::_M_message):

    Skip definition.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-string-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cxx11-ios_failure.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.

    [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
    * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
    * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.

    [!_GLIBCXX_USE_DUAL_ABI](__cow_string): Remove.
    * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/fstream-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions

    * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet>, 
std::use_facet>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet>, 
std::has_facet>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_getistreambuf_iterator>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_putostreambuf_iterator>): Instantiate.
    * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured

    _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.

    [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](time_putostreambuf_iterator>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](time_put_bynameostreambuf_iterator>): Instantiate.

[!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base): 

Re: [PATCH] libstdc++: Add error handler for

2022-11-30 Thread François Dumont via Gcc-patches

On 30/11/22 14:07, Jonathan Wakely wrote:

On Wed, 30 Nov 2022 at 11:57, Jonathan Wakely  wrote:



On Wed, 30 Nov 2022 at 11:54, Jonathan Wakely  wrote:



On Wed, 30 Nov 2022 at 06:04, François Dumont via Libstdc++ 
 wrote:

Good catch, then we also need this patch.


Is it worth printing an error? If we can't show the backtrace because of an 
error, we can just print nothing there.

We also need to pass an error handler to the __glibcxx_backtrace_create_state 
call in formatter.h.

Now that I look at this code again, why do we need the _M_backtrace_full 
member? It's always set to the same thing, why can't we just call that function 
directly?


Oh right, I remember now ... because otherwise the libstdc++.so library needs 
the definition of __glibcxx_backtrace_full.

I'm testing the attached patch.



And I think we should use threaded=1 for the __glibcxx_backtrace_create_state 
call.


You mean that 2 threads could try to assert at the same time.

I don't know what's the rule on the static _Error_formatter instance in 
_S_at. If we have a strong guaranty that only 1 instance will be created 
then I understand why we need threaded=1. Even if in this case the 2 
threads will report the same stacktrace.





Re: [PATCH] libstdc++: Add error handler for

2022-11-30 Thread François Dumont via Gcc-patches

On 30/11/22 14:07, Jonathan Wakely wrote:

On Wed, 30 Nov 2022 at 11:57, Jonathan Wakely  wrote:



On Wed, 30 Nov 2022 at 11:54, Jonathan Wakely  wrote:



On Wed, 30 Nov 2022 at 06:04, François Dumont via Libstdc++ 
 wrote:

Good catch, then we also need this patch.


Is it worth printing an error? If we can't show the backtrace because of an 
error, we can just print nothing there.


No strong opinion on that but if we do not print anything the output 
will be:


Backtrace:

Error: ...

I just considered that it did not cost much to report the issue to the 
user that defined _GLIBCXX_DEBUG_BACKTRACE and so is expecting a backtrace.


Maybe printing "Backtrace:\n" could be done in the normal callback 
leaving the user with the feeling that _GLIBCXX_DEBUG_BACKTRACE does not 
work.




We also need to pass an error handler to the __glibcxx_backtrace_create_state 
call in formatter.h.

Now that I look at this code again, why do we need the _M_backtrace_full 
member? It's always set to the same thing, why can't we just call that function 
directly?


Oh right, I remember now ... because otherwise the libstdc++.so library needs 
the definition of __glibcxx_backtrace_full.

I'm testing the attached patch.



And I think we should use threaded=1 for the __glibcxx_backtrace_create_state 
call.

So like the attached patch.






Re: [PATCH][_GLIBCXX_INLINE_VERSION] Adapt to_chars/from_chars symbols

2022-11-28 Thread François Dumont via Gcc-patches

On 28/11/22 19:35, Jonathan Wakely wrote:



On Mon, 28 Nov 2022 at 06:07, François Dumont via Libstdc++ 
mailto:libstdc%2b...@gcc.gnu.org>> wrote:


This patch is fixing those tests:

20_util/to_chars/float128_c++23.cc
std/format/formatter/requirements.cc
std/format/functions/format.cc
std/format/functions/format_to_n.cc
std/format/functions/size.cc
std/format/functions/vformat_to.cc
std/format/string.cc

Note that symbols used in  for __ibm128 and __iee128 are
untested.


We don't need to do this for those symbols, the ALT128 config is 
incompatible with versioned namespace. If you're using the versioned 
namespace, you don't need backwards compatibility with the old long 
double ABI.





Here is the simplified patch then.

    libstdc++: [_GLIBCXX_INLINE_VERSION] Add to_chars/from_chars 
symbols export


    libstdc++-v3/ChangeLog

    * include/std/format [_GLIBCXX_INLINE_VERSION](to_chars): 
Adapt __asm symbol

    specifications.
    * config/abi/pre/gnu-versioned-namespace.ver: Add 
to_chars/from_chars symbols

    export.

Ok to commit ?

François
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 06ccaa80a58..7fc81514808 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -142,6 +142,12 @@ GLIBCXX_8.0 {
 _ZN14__gnu_parallel9_Settings3getEv;
 _ZN14__gnu_parallel9_Settings3setERS0_;
 
+# to_chars/from_chars _Float128
+_ZNSt3__88to_charsEPcS0_DF128_;
+_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatE;
+_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatEi;
+_ZNSt3__810from_charsEPKcS1_RDF128_NS_12chars_formatE;
+
   local:
 *;
 };
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 23ffbdabed8..fb7a02cec57 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1288,15 +1288,27 @@ namespace __format
   // Make them available as std::__format::to_chars.
   to_chars_result
   to_chars(char*, char*, _Float128) noexcept
+#  if _GLIBCXX_INLINE_VERSION
+__asm("_ZNSt3__88to_charsEPcS0_DF128_");
+#  else
 __asm("_ZSt8to_charsPcS_DF128_");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, _Float128, chars_format) noexcept
+#  if _GLIBCXX_INLINE_VERSION
+__asm("_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatE");
+#  else
 __asm("_ZSt8to_charsPcS_DF128_St12chars_format");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, _Float128, chars_format, int) noexcept
+#  if _GLIBCXX_INLINE_VERSION
+__asm("_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatEi");
+#  else
 __asm("_ZSt8to_charsPcS_DF128_St12chars_formati");
+#  endif
 # endif
 #endif
 


Re: [PATCH][_GLIBCXX_INLINE_VERSION] Adapt to_chars/from_chars symbols

2022-11-28 Thread François Dumont via Gcc-patches
I forgot to add the patch but as you already made another feedback I'll 
clean my patch first.



On 28/11/22 19:43, François Dumont wrote:

On 28/11/22 11:21, Jonathan Wakely wrote:



On Mon, 28 Nov 2022 at 10:10, Jonathan Wakely  wrote:



On Mon, 28 Nov 2022 at 06:07, François Dumont via Libstdc++
mailto:libstdc%2b...@gcc.gnu.org>> wrote:

This patch is fixing those tests:

20_util/to_chars/float128_c++23.cc
std/format/formatter/requirements.cc
std/format/functions/format.cc
std/format/functions/format_to_n.cc
std/format/functions/size.cc
std/format/functions/vformat_to.cc
std/format/string.cc

Note that symbols used in  for __ibm128 and __iee128
are untested.

I even wonder if the normal mode ones are because I cannot
find the
symbols used in gnu.ver.


 libstdc++: [_GLIBCXX_INLINE_VERSION] Add
to_chars/from_chars
symbols export

 libstdc++-v3/ChangeLog

 * include/std/format
[_GLIBCXX_INLINE_VERSION](to_chars):
Adapt __asm symbol
 specifications.
 * config/abi/pre/gnu-versioned-namespace.ver: Add
to_chars/from_chars symbols
 export.

Ok to commit ?



Why are changes needed to the linker script?

Those functions should already match the general wildcard:

    # Names inside the 'extern' block are demangled names.
    extern "C++"
    {
      std::*;
      std::__8::*;
    };



No idear, my guess was that it has something to do with the __asm 
usages in  and with the commnt:


  // These overloads exist in the library, but are not declared for C++20.
  // Make them available as std::__format::to_chars.

Maybe they exist in the library but are unused so not exported unless 
specified in the linker script ?





Instead of nine separate #if blocks, can we just do:

#if _GLIBCXX_INLINE_VERSION
# define _GLIBCXX_ALIAS(S) __asm("_ZNSt3__8" S)
#else
# define _GLIBCXX_ALIAS(S) __asm("_ZNSt" S)
#endif

 And then use:

  _GLIBCXX_ALIAS("8to_charsPcS_eSt12chars_format");

and finally:

#undef _GLIBCXX_ALIAS


I tried and as expected it's not working because the diff in the 
symbol is not limited to the '3__8' pattern. 'chars_format' is also 
defined in versioned namespace which might perhaps explain some 
mangling diff.


Here is an updated patch though, I had forgotten to replace a _DF128 
with a __ieee128 in the untested part of this patch.


If you prefer to take a closer look later I'll just re-submit my patch 
to move versioned namespace mode to cxx11 abi knowing that those tests 
are already FAIL.


François




Re: [PATCH][_GLIBCXX_INLINE_VERSION] Adapt to_chars/from_chars symbols

2022-11-28 Thread François Dumont via Gcc-patches

On 28/11/22 11:21, Jonathan Wakely wrote:



On Mon, 28 Nov 2022 at 10:10, Jonathan Wakely  wrote:



On Mon, 28 Nov 2022 at 06:07, François Dumont via Libstdc++
mailto:libstdc%2b...@gcc.gnu.org>> wrote:

This patch is fixing those tests:

20_util/to_chars/float128_c++23.cc
std/format/formatter/requirements.cc
std/format/functions/format.cc
std/format/functions/format_to_n.cc
std/format/functions/size.cc
std/format/functions/vformat_to.cc
std/format/string.cc

Note that symbols used in  for __ibm128 and __iee128
are untested.

I even wonder if the normal mode ones are because I cannot
find the
symbols used in gnu.ver.


 libstdc++: [_GLIBCXX_INLINE_VERSION] Add to_chars/from_chars
symbols export

 libstdc++-v3/ChangeLog

 * include/std/format
[_GLIBCXX_INLINE_VERSION](to_chars):
Adapt __asm symbol
 specifications.
 * config/abi/pre/gnu-versioned-namespace.ver: Add
to_chars/from_chars symbols
 export.

Ok to commit ?



Why are changes needed to the linker script?

Those functions should already match the general wildcard:

    # Names inside the 'extern' block are demangled names.
    extern "C++"
    {
      std::*;
      std::__8::*;
    };



No idear, my guess was that it has something to do with the __asm usages 
in  and with the commnt:


  // These overloads exist in the library, but are not declared for C++20.
  // Make them available as std::__format::to_chars.

Maybe they exist in the library but are unused so not exported unless 
specified in the linker script ?





Instead of nine separate #if blocks, can we just do:

#if _GLIBCXX_INLINE_VERSION
# define _GLIBCXX_ALIAS(S) __asm("_ZNSt3__8" S)
#else
# define _GLIBCXX_ALIAS(S) __asm("_ZNSt" S)
#endif

 And then use:

  _GLIBCXX_ALIAS("8to_charsPcS_eSt12chars_format");

and finally:

#undef _GLIBCXX_ALIAS


I tried and as expected it's not working because the diff in the symbol 
is not limited to the '3__8' pattern. 'chars_format' is also defined in 
versioned namespace which might perhaps explain some mangling diff.


Here is an updated patch though, I had forgotten to replace a _DF128 
with a __ieee128 in the untested part of this patch.


If you prefer to take a closer look later I'll just re-submit my patch 
to move versioned namespace mode to cxx11 abi knowing that those tests 
are already FAIL.


François



Re: [PATCH][_GLIBCXX_INLINE_VERSION] Adapt dg error messages

2022-11-28 Thread François Dumont via Gcc-patches

On 28/11/22 14:39, Jonathan Wakely wrote:



On Mon, 28 Nov 2022 at 10:08, Jonathan Wakely  wrote:



On Mon, 28 Nov 2022 at 10:06, Jonathan Wakely 
wrote:



On Mon, 28 Nov 2022 at 06:02, François Dumont via Libstdc++
mailto:libstdc%2b...@gcc.gnu.org>> wrote:

libstdc++: [_GLIBCXX_INLINE_VERSION] Adapt dg error messages

libstdc++-v3/ChangeLog

 * testsuite/20_util/bind/ref_neg.cc: Adapt
dg-prune-output message.
 * testsuite/20_util/function/cons/70692.cc: Adapt
dg-error message.

Ok to commit ?


OK, thanks.



Actually wait, can you test this instead?

--- a/libstdc++-v3/testsuite/lib/prune.exp
+++ b/libstdc++-v3/testsuite/lib/prune.exp
@@ -37,6 +37,8 @@ proc libstdc++-dg-prune { system text } {
      return "::unsupported::hosted C++ headers not supported"
    }

+    regsub -all "std::__8::" $text "std::" text
+
    # Ignore caret diagnostics. Unfortunately dejaGNU trims leading
    # spaces, so one cannot rely on them being present.
    regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text

This should mean we can stop needing to make these changes to
every test, and just write the tests naturally.


That only helps for dg-prune-output but we still need to (__8::)? for 
dg-error.


Please push your change to 20_util/function/cons/70692.cc but not the 
change to 20_util/bind/ref_neg.cc (the latter will get fixed after I 
pushed the prune.expo change).



Done as requested and I confirm that prune.exp enhancement fixed 
20_util/bind/ref_neg.cc.


Thanks


[PATCH][_GLIBCXX_INLINE_VERSION] Adapt to_chars/from_chars symbols

2022-11-27 Thread François Dumont via Gcc-patches

This patch is fixing those tests:

20_util/to_chars/float128_c++23.cc
std/format/formatter/requirements.cc
std/format/functions/format.cc
std/format/functions/format_to_n.cc
std/format/functions/size.cc
std/format/functions/vformat_to.cc
std/format/string.cc

Note that symbols used in  for __ibm128 and __iee128 are untested.

I even wonder if the normal mode ones are because I cannot find the 
symbols used in gnu.ver.



    libstdc++: [_GLIBCXX_INLINE_VERSION] Add to_chars/from_chars 
symbols export


    libstdc++-v3/ChangeLog

    * include/std/format [_GLIBCXX_INLINE_VERSION](to_chars): 
Adapt __asm symbol

    specifications.
    * config/abi/pre/gnu-versioned-namespace.ver: Add 
to_chars/from_chars symbols

    export.

Ok to commit ?

François
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 06ccaa80a58..7fc81514808 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -142,6 +142,12 @@ GLIBCXX_8.0 {
 _ZN14__gnu_parallel9_Settings3getEv;
 _ZN14__gnu_parallel9_Settings3setERS0_;
 
+# to_chars/from_chars _Float128
+_ZNSt3__88to_charsEPcS0_DF128_;
+_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatE;
+_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatEi;
+_ZNSt3__810from_charsEPKcS1_RDF128_NS_12chars_formatE;
+
   local:
 *;
 };
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 23ffbdabed8..a05f3981622 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1248,27 +1248,51 @@ namespace __format
   // Make them available as std::__format::to_chars.
   to_chars_result
   to_chars(char*, char*, __ibm128) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_e");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_e");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, __ibm128, chars_format) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_eSt12chars_format");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_eNS_12chars_formatE");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, __ibm128, chars_format, int) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_eSt12chars_formati");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_eNS_12chars_formatEi");
+#  endif
 #elif __cplusplus == 202002L
   to_chars_result
   to_chars(char*, char*, __ieee128) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_u9__ieee128");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_DF128_");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, __ieee128, chars_format) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_u9__ieee128St12chars_format");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_u9__ieee128NS_12chars_formatE");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, __ieee128, chars_format, int) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_u9__ieee128St12chars_formati");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_u9__ieee128NS_12chars_formatEi");
+#  endif
 #endif
 
 #elif defined _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128
@@ -1288,15 +1312,27 @@ namespace __format
   // Make them available as std::__format::to_chars.
   to_chars_result
   to_chars(char*, char*, _Float128) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_DF128_");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_DF128_");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, _Float128, chars_format) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_DF128_St12chars_format");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatE");
+#  endif
 
   to_chars_result
   to_chars(char*, char*, _Float128, chars_format, int) noexcept
+#  if !_GLIBCXX_INLINE_VERSION
 __asm("_ZSt8to_charsPcS_DF128_St12chars_formati");
+#  else
+__asm("_ZNSt3__88to_charsEPcS0_DF128_NS_12chars_formatEi");
+#  endif
 # endif
 #endif
 


[PATCH][_GLIBCXX_INLINE_VERSION] Adapt dg error messages

2022-11-27 Thread François Dumont via Gcc-patches

libstdc++: [_GLIBCXX_INLINE_VERSION] Adapt dg error messages

libstdc++-v3/ChangeLog

    * testsuite/20_util/bind/ref_neg.cc: Adapt dg-prune-output message.
    * testsuite/20_util/function/cons/70692.cc: Adapt dg-error message.

Ok to commit ?

François
diff --git a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
index a78935775c2..830b30eae6c 100644
--- a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
@@ -50,7 +50,7 @@ void test02()
 
 // Ignore the reasons for deduction/substitution failure in the headers.
 // Arrange for the match to work on installed trees as well as build trees.
-// { dg-prune-output "no type named 'type' in 'struct std::result_of" }
+// { dg-prune-output "no type named 'type' in 'struct std::(__8::)?result_of" }
 
 int main()
 {
diff --git a/libstdc++-v3/testsuite/20_util/function/cons/70692.cc b/libstdc++-v3/testsuite/20_util/function/cons/70692.cc
index f9e8fe31570..b15208a2531 100644
--- a/libstdc++-v3/testsuite/20_util/function/cons/70692.cc
+++ b/libstdc++-v3/testsuite/20_util/function/cons/70692.cc
@@ -11,4 +11,4 @@ int main()
   std::function ff(f);  // { dg-error "no matching function" }
   std::function f2(f);  // { dg-error "no matching function" }
 }
-// { dg-error "std::enable_if" "" { target *-*-* } 0 }
+// { dg-error "std::(__8::)?enable_if" "" { target *-*-* } 0 }


Re: [PATCH] Fix in _GLIBCXX_INLINE_VERSION mode

2022-11-20 Thread François Dumont via Gcc-patches

On 19/11/22 14:11, Jonathan Wakely wrote:

On Sat, 19 Nov 2022 at 13:03, François Dumont via Libstdc++
 wrote:

Without this qualification I have this in _GLIBCXX_INLINE_VERSION mode:

/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649:
note: candidate: 'template bool std::__9::isxdigit(_CharT,
const locale&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649:
note:   template argument deduction/substitution failed:
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1540:
note:   candidate expects 2 arguments, 1 provided
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1630:
error: no matching function for call to 'isxdigit(const
std::__9::basic_string_view::value_type&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649:
note: candidate: 'template bool std::__9::isxdigit(_CharT,
const locale&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649:
note:   template argument deduction/substitution failed:
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1630:
note:   candidate expects 2 arguments, 1 provided
compiler exited with status 1
FAIL: 17_intro/headers/c++2020/all_attributes.cc (test for excess errors)
Excess errors:
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1540:
error: no matching function for call to 'isxdigit(const
std::__9::basic_string_view::value_type&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1630:
error: no matching function for call to 'isxdigit(const
std::__9::basic_string_view::value_type&)'

It sounds like the most reasonable fix as this is how toupper is being
called.

I think the real problem is that include/c_global/cctype is missing
the NAMESPACE_VERSION macros.

All declarations of std::isxdigit etc should be in the same namespace,
precisely so we don't need to do this.


Didn't you want to fix it this way then ?

To be honest I was a little bit lost by this code:

#if !__has_builtin(__builtin_toupper)
# include 
#endif

Looks like cctype is included only for toupper, why not for isxdigit ?




  libstdc++: Add missing std qualification on isxdigit calls

  libstdc++-v3/ChangeLog

  * include/std/format: Add std qualification on isxdigit calls.

Ok to commit ?

Yes, OK.


Committed.



[PATCH] Fix in _GLIBCXX_INLINE_VERSION mode

2022-11-19 Thread François Dumont via Gcc-patches

Without this qualification I have this in _GLIBCXX_INLINE_VERSION mode:

/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649: 
note: candidate: 'template bool std::__9::isxdigit(_CharT, 
const locale&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649: 
note:   template argument deduction/substitution failed:
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1540: 
note:   candidate expects 2 arguments, 1 provided
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1630: 
error: no matching function for call to 'isxdigit(const 
std::__9::basic_string_view::value_type&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649: 
note: candidate: 'template bool std::__9::isxdigit(_CharT, 
const locale&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/locale_facets.h:2649: 
note:   template argument deduction/substitution failed:
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1630: 
note:   candidate expects 2 arguments, 1 provided

compiler exited with status 1
FAIL: 17_intro/headers/c++2020/all_attributes.cc (test for excess errors)
Excess errors:
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1540: 
error: no matching function for call to 'isxdigit(const 
std::__9::basic_string_view::value_type&)'
/home/fdt/dev/gcc/build_versioned_ns/x86_64-pc-linux-gnu/libstdc++-v3/include/format:1630: 
error: no matching function for call to 'isxdigit(const 
std::__9::basic_string_view::value_type&)'


It sounds like the most reasonable fix as this is how toupper is being 
called.


    libstdc++: Add missing std qualification on isxdigit calls

    libstdc++-v3/ChangeLog

    * include/std/format: Add std qualification on isxdigit calls.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index f4fc85a16d2..9f5b7bee2be 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1537,7 +1537,7 @@ namespace __format
 
 	  if (__trailing_zeros)
 		{
-		  if (!isxdigit(__s[0]))
+		  if (!std::isxdigit(__s[0]))
 		--__sigfigs;
 		  __z = __prec - __sigfigs;
 		}
@@ -1627,7 +1627,7 @@ namespace __format
 		{
 		  __fill_char = _CharT('0');
 		  // Write sign before zero filling.
-		  if (!isxdigit(__narrow_str[0]))
+		  if (!std::isxdigit(__narrow_str[0]))
 		{
 		  *__out++ = __str[0];
 		  __str.remove_prefix(1);


Re: [PATCH] Fix gdb FilteringTypePrinter (again)

2022-11-16 Thread François Dumont via Gcc-patches

On 16/11/22 12:54, Jonathan Wakely wrote:

On Wed, 16 Nov 2022 at 11:35, Jonathan Wakely  wrote:

On Wed, 16 Nov 2022 at 06:04, François Dumont  wrote:

On 15/11/22 17:17, Jonathan Wakely wrote:

On 06/10/22 19:38 +0200, François Dumont wrote:

Hi

Looks like the previous patch was not enough. When using it in the
context of a build without dual abi and versioned namespace I started
having failures again. I guess I hadn't rebuild everything properly.

This time I think the problem was in those lines:

 if self.type_obj == type_obj:
 return strip_inline_namespaces(self.name)

I've added a call to gdb.types.get_basic_type so that we do not compare
a type with its typedef.

Thanks for the pointer to the doc !

Doing so I eventually use your code Jonathan to make FilteringTypeFilter
more specific to a given instantiation.

 libstdc++: Fix gdb FilteringTypePrinter

 Once we found a matching FilteringTypePrinter instance we look for
the associated
 typedef and check that the returned Python Type is equal to the
Type to recognize.
 But gdb Python Type includes properties to distinguish a typedef
from the actual
 type. So use gdb.types.get_basic_type to check if we are indeed on
the same type.

 Additionnaly enhance FilteringTypePrinter matching mecanism by
introducing targ1 that,
 if not None, will be used as the 1st template parameter.

 libstdc++-v3/ChangeLog:

 * python/libstdcxx/v6/printers.py (FilteringTypePrinter):
Rename 'match' field
 'template'. Add self.targ1 to specify the first template
parameter of the instantiation
 to match.
 (add_one_type_printer): Add targ1 optional parameter,
default to None.
 Use gdb.types.get_basic_type to compare the type to
recognize and the type
 returned from the typedef lookup.
 (register_type_printers): Adapt calls to
add_one_type_printers.

Tested under Linux x86_64 normal, version namespace with or without dual
abi.

François

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0fa7805183e..52339b247d8 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2040,62 +2040,72 @@ def add_one_template_type_printer(obj, name,
defargs):

class FilteringTypePrinter(object):
 r"""
-A type printer that uses typedef names for common template
specializations.
+A type printer that uses typedef names for common template
instantiations.

 Args:
-match (str): The class template to recognize.
+template (str): The class template to recognize.
 name (str): The typedef-name that will be used instead.
+targ1 (str): The first template argument.
+If arg1 is provided (not None), only template
instantiations with this type
+as the first template argument, e.g. if
template='basic_string is the same
type as
+e.g. for template='basic_istream', name='istream', if any
instantiation of
+std::basic_istream is the same type as std::istream then
print it as
+std::istream.
+
+e.g. for template='basic_istream', name='istream', targ1='char',
if any
+instantiation of std::basic_istream is the same type as
 std::istream then print it as std::istream.
 """

These are template specializations, not instantiations. Please undo
the changes to the comments, because the comments are 100% correct
now, and would become wrong with this patch.

template struct foo { };
using F = foo; // #1
template struct foo { }; // #2
template<> struct foo { }; // #3

#1 is a *specialization* of the class template foo. It is
*instantiated* when you construct one or depend on its size, or its
members.
#2 is a *partial specialization* and #3 is an explicit specialization.
But #1 is a speclialization, not an instantiation.

Instantiation is a process that happens during compilation. A
specialization is a type (or function, or variable) generated from a
template by substituting arguments for the template parameters. The
python type printer matches specializations.

Lesson learned, thanks.

Maybe comment on line 169 is wrong then. I think there is a clue in the
function name 'is_specialization_of' :-)

Good point! Thanks, I'll fix it.


-def __init__(self, match, name):
-self.match = match
+def __init__(self, template, name, targ1):

Is there a reason to require targ1 here, instead of making it
optional, by using =None as the default?

In your original, and I know untested, proposal it was not working.

The function add_one_type_printer was missing to pass its targ1
parameter to the FilteringTypePrinter ctor but thanks to the default
value it was un-noticed by the interpreter.

My untested patch had this, which adds it, doesn't it?

-def add_one_type_printer(obj, match, name):
-printer = FilteringTypePrinter('std::' + match, 'std::' + name)
+def 

Re: [PATCH] Fix gdb FilteringTypePrinter (again)

2022-11-15 Thread François Dumont via Gcc-patches

On 15/11/22 17:17, Jonathan Wakely wrote:

On 06/10/22 19:38 +0200, François Dumont wrote:

Hi

Looks like the previous patch was not enough. When using it in the
context of a build without dual abi and versioned namespace I started
having failures again. I guess I hadn't rebuild everything properly.

This time I think the problem was in those lines:

    if self.type_obj == type_obj:
    return strip_inline_namespaces(self.name)

I've added a call to gdb.types.get_basic_type so that we do not compare
a type with its typedef.

Thanks for the pointer to the doc !

Doing so I eventually use your code Jonathan to make FilteringTypeFilter
more specific to a given instantiation.

    libstdc++: Fix gdb FilteringTypePrinter

    Once we found a matching FilteringTypePrinter instance we look for
the associated
    typedef and check that the returned Python Type is equal to the
Type to recognize.
    But gdb Python Type includes properties to distinguish a typedef
from the actual
    type. So use gdb.types.get_basic_type to check if we are indeed on
the same type.

    Additionnaly enhance FilteringTypePrinter matching mecanism by
introducing targ1 that,
    if not None, will be used as the 1st template parameter.

    libstdc++-v3/ChangeLog:

    * python/libstdcxx/v6/printers.py (FilteringTypePrinter):
Rename 'match' field
    'template'. Add self.targ1 to specify the first template
parameter of the instantiation
    to match.
    (add_one_type_printer): Add targ1 optional parameter,
default to None.
    Use gdb.types.get_basic_type to compare the type to
recognize and the type
    returned from the typedef lookup.
    (register_type_printers): Adapt calls to 
add_one_type_printers.


Tested under Linux x86_64 normal, version namespace with or without dual
abi.

François

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py

index 0fa7805183e..52339b247d8 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2040,62 +2040,72 @@ def add_one_template_type_printer(obj, name, 
defargs):


class FilteringTypePrinter(object):
    r"""
-    A type printer that uses typedef names for common template 
specializations.
+    A type printer that uses typedef names for common template 
instantiations.


    Args:
-    match (str): The class template to recognize.
+    template (str): The class template to recognize.
    name (str): The typedef-name that will be used instead.
+    targ1 (str): The first template argument.
+    If arg1 is provided (not None), only template 
instantiations with this type
+    as the first template argument, e.g. if 
template='basic_string

-    Checks if a specialization of the class template 'match' is the 
same type
+    Checks if an instantiation of the class template 'template' is 
the same type

    as the typedef 'name', and prints it as 'name' instead.

-    e.g. if an instantiation of std::basic_istream is the same 
type as
+    e.g. for template='basic_istream', name='istream', if any 
instantiation of
+    std::basic_istream is the same type as std::istream then 
print it as

+    std::istream.
+
+    e.g. for template='basic_istream', name='istream', targ1='char', 
if any

+    instantiation of std::basic_istream is the same type as
    std::istream then print it as std::istream.
    """


These are template specializations, not instantiations. Please undo
the changes to the comments, because the comments are 100% correct
now, and would become wrong with this patch.

template struct foo { };
using F = foo; // #1
template struct foo { }; // #2
template<> struct foo { }; // #3

#1 is a *specialization* of the class template foo. It is
*instantiated* when you construct one or depend on its size, or its
members.
#2 is a *partial specialization* and #3 is an explicit specialization.
But #1 is a speclialization, not an instantiation.

Instantiation is a process that happens during compilation. A
specialization is a type (or function, or variable) generated from a
template by substituting arguments for the template parameters. The
python type printer matches specializations.


Lesson learned, thanks.

Maybe comment on line 169 is wrong then. I think there is a clue in the 
function name 'is_specialization_of' :-)






-    def __init__(self, match, name):
-    self.match = match
+    def __init__(self, template, name, targ1):


Is there a reason to require targ1 here, instead of making it
optional, by using =None as the default?


In your original, and I know untested, proposal it was not working.

The function add_one_type_printer was missing to pass its targ1 
parameter to the FilteringTypePrinter ctor but thanks to the default 
value it was un-noticed by the interpreter. So I removed it as useless 
and redundant with this function default value.







+    

Re: [PATCH] Fix gdb FilteringTypePrinter (again)

2022-11-14 Thread François Dumont via Gcc-patches

Any chance to review this one ?

On 06/10/22 19:38, François Dumont wrote:

Hi

Looks like the previous patch was not enough. When using it in the 
context of a build without dual abi and versioned namespace I started 
having failures again. I guess I hadn't rebuild everything properly.


This time I think the problem was in those lines:

    if self.type_obj == type_obj:
    return strip_inline_namespaces(self.name)

I've added a call to gdb.types.get_basic_type so that we do not 
compare a type with its typedef.


Thanks for the pointer to the doc !

Doing so I eventually use your code Jonathan to make 
FilteringTypeFilter more specific to a given instantiation.


    libstdc++: Fix gdb FilteringTypePrinter

    Once we found a matching FilteringTypePrinter instance we look for 
the associated
    typedef and check that the returned Python Type is equal to the 
Type to recognize.
    But gdb Python Type includes properties to distinguish a typedef 
from the actual
    type. So use gdb.types.get_basic_type to check if we are indeed on 
the same type.


    Additionnaly enhance FilteringTypePrinter matching mecanism by 
introducing targ1 that,

    if not None, will be used as the 1st template parameter.

    libstdc++-v3/ChangeLog:

    * python/libstdcxx/v6/printers.py (FilteringTypePrinter): 
Rename 'match' field
    'template'. Add self.targ1 to specify the first template 
parameter of the instantiation

    to match.
    (add_one_type_printer): Add targ1 optional parameter, 
default to None.
    Use gdb.types.get_basic_type to compare the type to 
recognize and the type

    returned from the typedef lookup.
    (register_type_printers): Adapt calls to 
add_one_type_printers.


Tested under Linux x86_64 normal, version namespace with or without 
dual abi.


François





Re: [PATCH] PR 107189 Remove useless _Alloc_node

2022-11-14 Thread François Dumont via Gcc-patches

Gentle reminder.

Sorry if I should have committed it as trivial but I cannot do it 
anymore now that I asked :-)



On 12/10/22 22:18, François Dumont wrote:

libstdc++: Remove _Alloc_node instance in _Rb_tree [PR107189]

    libstdc++-v3/ChangeLog:

    PR libstdc++/107189
    * include/bits/stl_tree.h 
(_Rb_tree<>::_M_insert_range_equal): Remove

    unused _Alloc_node instance.

Ok to commit ?

François





[PATCH] PR 107189 Remove useless _Alloc_node

2022-10-12 Thread François Dumont via Gcc-patches

    libstdc++: Remove _Alloc_node instance in _Rb_tree [PR107189]

    libstdc++-v3/ChangeLog:

    PR libstdc++/107189
    * include/bits/stl_tree.h 
(_Rb_tree<>::_M_insert_range_equal): Remove

    unused _Alloc_node instance.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index a4de6141765..33d25089a1d 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -1123,7 +1123,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__enable_if_t::value>
 	_M_insert_range_equal(_InputIterator __first, _InputIterator __last)
 	{
-	  _Alloc_node __an(*this);
 	  for (; __first != __last; ++__first)
 	_M_emplace_equal(*__first);
 	}


Re: [PATCH] Use cxx11 abi in versioned namespace

2022-10-11 Thread François Dumont via Gcc-patches

Hi

    Now that pretty printer is fixed (once patch validated) I'd like to 
propose this patch again.


    Note that I'am adding a check on pretty printer with a std::any on 
a std::wstring. I did so because of the FIXME in printers.py which is 
dealing with 'std::string' explicitely. Looks like in my case, where 
there is no 'std::string' but just a 'std::__8::string' we do not need 
the workaround.


    Once again I am attaching also the version namespace bump patch as 
I think that adopting the cxx11 abi in this mode is a good enough reason 
to bump it. If you agress let me know if I should squash the commits 
before pushing.


    libstdc++: [_GLIBCXX_INLINE_VERSION] Use cxx11 abi

    Use cxx11 abi when activating versioned namespace mode.

    libstdcxx-v3/ChangeLog:

    * acinclude.m4 [GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI]: Default 
to "new" libstdcxx abi.
    * config/locale/dragonfly/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Define money_base

    members.
    * config/locale/generic/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.
    * config/locale/gnu/monetary_members.cc 
[!_GLIBCXX_USE_DUAL_ABI]: Likewise.

    * config/locale/gnu/numeric_members.cc
    [!_GLIBCXX_USE_DUAL_ABI](__narrow_multibyte_chars): Define.
    * configure: Regenerate.
    * include/bits/c++config
    [_GLIBCXX_INLINE_VERSION](_GLIBCXX_NAMESPACE_CXX11, 
_GLIBCXX_BEGIN_NAMESPACE_CXX11): Define

    empty.
[_GLIBCXX_INLINE_VERSION](_GLIBCXX_END_NAMESPACE_CXX11, 
_GLIBCXX_DEFAULT_ABI_TAG): Likewise.

    * python/libstdcxx/v6/printers.py
    (StdStringPrinter::__init__): Set self.new_string to True 
when std::__8::basic_string type is

    found.
    * src/Makefile.am 
[ENABLE_SYMVERS_GNU_NAMESPACE](ldbl_alt128_compat_sources): Define empty.

    * src/Makefile.in: Regenerate.
    * src/c++11/Makefile.am (cxx11_abi_sources): Rename into...
    (dual_abi_sources): ...this, new. Also move several sources 
to...

    (sources): ...this.
    (extra_string_inst_sources): Move several sources to...
    (inst_sources): ...this.
    * src/c++11/Makefile.in: Regenerate.
    * src/c++11/cow-fstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-locale_init.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-sstream-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-stdexcept.cc 
[_GLIBCXX_USE_CXX11_ABI](error_category::_M_message):

    Skip definition.
    [_GLIBCXX_USE_CXX11_ABI]: Skip Transaction Memory TS 
definitions.
    * src/c++11/cow-string-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-string-io-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-inst.cc [_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cow-wstring-io-inst.cc 
[_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/cxx11-hash_tr1.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.
    * src/c++11/cxx11-ios_failure.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.

    [!_GLIBCXX_USE_DUAL_ABI] (__ios_failure): Remove.
    * src/c++11/cxx11-locale-inst.cc: Cleanup, just include 
locale-inst.cc.
    * src/c++11/cxx11-stdexcept.cc [!_GLIBCXX_USE_CXX11_ABI]: 
Skip definitions.

    [!_GLIBCXX_USE_DUAL_ABI](__cow_string): Remove.
    * src/c++11/cxx11-wlocale-inst.cc 
[!_GLIBCXX_USE_CXX11_ABI]: Skip definitions.
    * src/c++11/fstream-inst.cc [!_GLIBCXX_USE_CXX11_ABI]: Skip 
definitions

    * src/c++11/locale-inst-numeric.h
[!_GLIBCXX_USE_DUAL_ABI](std::use_facet>, 
std::use_facet>): Instantiate.
[!_GLIBCXX_USE_DUAL_ABI](std::has_facet>, 
std::has_facet>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_getistreambuf_iterator>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](std::num_putostreambuf_iterator>): Instantiate.
    * src/c++11/locale-inst.cc [!_GLIBCXX_USE_DUAL_ABI]: Build 
only when configured

    _GLIBCXX_USE_CXX11_ABI is equal to currently built abi.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__moneypunct_cache): 
Instantiate.

    [!_GLIBCXX_USE_DUAL_ABI](__numpunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](__timepunct_cache): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](time_putostreambuf_iterator>): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](time_put_bynameostreambuf_iterator>): Instantiate.

[!_GLIBCXX_USE_DUAL_ABI](__ctype_abstract_base): Instantiate.
    [!_GLIBCXX_USE_DUAL_ABI](ctype_byname): Instantiate.
    

[PATCH] Fix gdb FilteringTypePrinter (again)

2022-10-06 Thread François Dumont via Gcc-patches

Hi

Looks like the previous patch was not enough. When using it in the 
context of a build without dual abi and versioned namespace I started 
having failures again. I guess I hadn't rebuild everything properly.


This time I think the problem was in those lines:

    if self.type_obj == type_obj:
    return strip_inline_namespaces(self.name)

I've added a call to gdb.types.get_basic_type so that we do not compare 
a type with its typedef.


Thanks for the pointer to the doc !

Doing so I eventually use your code Jonathan to make FilteringTypeFilter 
more specific to a given instantiation.


    libstdc++: Fix gdb FilteringTypePrinter

    Once we found a matching FilteringTypePrinter instance we look for 
the associated
    typedef and check that the returned Python Type is equal to the 
Type to recognize.
    But gdb Python Type includes properties to distinguish a typedef 
from the actual
    type. So use gdb.types.get_basic_type to check if we are indeed on 
the same type.


    Additionnaly enhance FilteringTypePrinter matching mecanism by 
introducing targ1 that,

    if not None, will be used as the 1st template parameter.

    libstdc++-v3/ChangeLog:

    * python/libstdcxx/v6/printers.py (FilteringTypePrinter): 
Rename 'match' field
    'template'. Add self.targ1 to specify the first template 
parameter of the instantiation

    to match.
    (add_one_type_printer): Add targ1 optional parameter, 
default to None.
    Use gdb.types.get_basic_type to compare the type to 
recognize and the type

    returned from the typedef lookup.
    (register_type_printers): Adapt calls to add_one_type_printers.

Tested under Linux x86_64 normal, version namespace with or without dual 
abi.


François

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0fa7805183e..52339b247d8 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2040,62 +2040,72 @@ def add_one_template_type_printer(obj, name, defargs):
 
 class FilteringTypePrinter(object):
 r"""
-A type printer that uses typedef names for common template specializations.
+A type printer that uses typedef names for common template instantiations.
 
 Args:
-match (str): The class template to recognize.
+template (str): The class template to recognize.
 name (str): The typedef-name that will be used instead.
+targ1 (str): The first template argument.
+If arg1 is provided (not None), only template instantiations with this type
+as the first template argument, e.g. if template='basic_string is the same type as
+e.g. for template='basic_istream', name='istream', if any instantiation of
+std::basic_istream is the same type as std::istream then print it as
+std::istream.
+
+e.g. for template='basic_istream', name='istream', targ1='char', if any
+instantiation of std::basic_istream is the same type as
 std::istream then print it as std::istream.
 """
 
-def __init__(self, match, name):
-self.match = match
+def __init__(self, template, name, targ1):
+self.template = template
 self.name = name
+self.targ1 = targ1
 self.enabled = True
 
 class _recognizer(object):
 "The recognizer class for FilteringTypePrinter."
 
-def __init__(self, match, name):
-self.match = match
+def __init__(self, template, name, targ1):
+self.template = template
 self.name = name
+self.targ1 = targ1
 self.type_obj = None
 
 def recognize(self, type_obj):
 """
-If type_obj starts with self.match and is the same type as
+If type_obj starts with self.template and is the same type as
 self.name then return self.name, otherwise None.
 """
 if type_obj.tag is None:
 return None
 
 if self.type_obj is None:
-if not type_obj.tag.startswith(self.match):
+if self.targ1 is not None:
+if not type_obj.tag.startswith('{}<{}'.format(self.template, self.targ1)):
+# Filter didn't match.
+return None
+elif not type_obj.tag.startswith(self.template):
 # Filter didn't match.
 return None
+
 try:
 self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
 except:
 pass
-if self.type_obj == type_obj:
-return strip_inline_namespaces(self.name)
 
 if self.type_obj is None:
 return None
 
-# Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols.
-ambiguous = False
- 

Re: [PATCH] Fix gdb printers for std::string

2022-10-03 Thread François Dumont via Gcc-patches

On 01/10/22 17:30, Jonathan Wakely wrote:

On Sat, 1 Oct 2022 at 11:43, François Dumont  wrote:

On 01/10/22 12:06, Jonathan Wakely wrote:

On Sat, 1 Oct 2022 at 08:20, François Dumont via Libstdc++
 wrote:

I had forgotten to re-run tests after I removed the #define
_GLIBCXX_USE_CXX11_ABI 0.

The comment was misleading, it could also impact output of std::list.

I am also restoring the correct std::string alias for
std::__cxx11::basic_string, even if with my workaround it doesn't really
matter as the one for std::basic_string will be used.

I also restored the printer for std::__cxx11::string typedef. Is it
intentional to keep this ?

Yes, I kept that intentionally. There can be programs where some
objects still use that typedef, if those objects were compiled with
GCC 8.x or older.


   libstdc++: Fix gdb pretty printers when dealing with std::string

   Since revision 33b43b0d8cd2de722d177ef823930500948a7487 std::string
and other
   similar typedef are ambiguous from a gdb point of view because it
matches both
   std::basic_string and std::__cxx11::basic_string
symbols. For those
   typedef add a workaround to accept the substitution as long as the
same regardless
   of __cxx11 namespace.

Thanks for figuring out what was going wrong here, and how to fix it.



   Also avoid to register printers for types in std::__cxx11::__8::
namespace, there is
   no such symbols.

   libstdc++-v3/ChangeLog:

   * libstdc++-v3/python/libstdcxx/v6/printers.py
(Printer.add_version): Do not add
   version namespace for __cxx11 symbols.
   (add_one_template_type_printer): Likewise.
   (add_one_type_printer): Likewise.
   (FilteringTypePrinter._recognizer.recognize): Add a
workaround for std::string & al
   ambiguous typedef matching both std:: and std::__cxx11::
symbols.
   (register_type_printers): Refine type registration to limit
false positive in
   FilteringTypePrinter._recognize.recognize requiring to look
for the type in gdb.

I don't really like this part of the change though:

I'll check what you are proposing but I don't think it is necessary to
fix the problem.

Most of my patch is an alternative way to make the filter match on
"basic_string
I did this on my path to find out what was going wrong. Once I
understood it I consider that it was just a good change to keep. If you
think otherwise I can revert this part.

Yeah it looks like it's just an optimization to fail faster without
having to do gdb.lookup_type.

Please revert the changes to register_type_printers then, and we can
consider that part later if we want to revisit it. I'm not opposed to
making that fail-fast optimization, as long as we keep the property
that FilteringTypePrinter.match is the class template name. Maybe it
should be renamed to something other than "match" to make that clear.


Or change the doc ? For my info, why is it so important to comply to the 
current doc ? Is it extracted from some gdb doc ?


Now that the problem is fixed it is less important but I never managed 
to find any doc about this gdb feature that we are relying on.





The rest of the patch is OK for trunk, thanks.


I also noted that gdb consider the filters as a filo list, not fifo. And
I think that the 1st filters registered are the most extensively used. I
can propose to invert all the registration if you think it worth it.

I've not noticed any performance problems with the printers, but I
have wondered how many printers is too many. That's an interesting
observation about the order they're checked. I'll talk to some of the
GDB devs to find out if they think it's something we should worry
about. Let's not try make premature optimizations until we know if it
matters.


Yes, but with the 1st registration and so the last evaluation being 
'std::string' it sounds more like a premature lowering ;-)





Re: [PATCH] Fix gdb printers for std::string

2022-10-01 Thread François Dumont via Gcc-patches

On 01/10/22 12:06, Jonathan Wakely wrote:

On Sat, 1 Oct 2022 at 08:20, François Dumont via Libstdc++
 wrote:

I had forgotten to re-run tests after I removed the #define
_GLIBCXX_USE_CXX11_ABI 0.

The comment was misleading, it could also impact output of std::list.

I am also restoring the correct std::string alias for
std::__cxx11::basic_string, even if with my workaround it doesn't really
matter as the one for std::basic_string will be used.

I also restored the printer for std::__cxx11::string typedef. Is it
intentional to keep this ?

Yes, I kept that intentionally. There can be programs where some
objects still use that typedef, if those objects were compiled with
GCC 8.x or older.


  libstdc++: Fix gdb pretty printers when dealing with std::string

  Since revision 33b43b0d8cd2de722d177ef823930500948a7487 std::string
and other
  similar typedef are ambiguous from a gdb point of view because it
matches both
  std::basic_string and std::__cxx11::basic_string
symbols. For those
  typedef add a workaround to accept the substitution as long as the
same regardless
  of __cxx11 namespace.

Thanks for figuring out what was going wrong here, and how to fix it.



  Also avoid to register printers for types in std::__cxx11::__8::
namespace, there is
  no such symbols.

  libstdc++-v3/ChangeLog:

  * libstdc++-v3/python/libstdcxx/v6/printers.py
(Printer.add_version): Do not add
  version namespace for __cxx11 symbols.
  (add_one_template_type_printer): Likewise.
  (add_one_type_printer): Likewise.
  (FilteringTypePrinter._recognizer.recognize): Add a
workaround for std::string & al
  ambiguous typedef matching both std:: and std::__cxx11::
symbols.
  (register_type_printers): Refine type registration to limit
false positive in
  FilteringTypePrinter._recognize.recognize requiring to look
for the type in gdb.

I don't really like this part of the change though:


I'll check what you are proposing but I don't think it is necessary to 
fix the problem.


I did this on my path to find out what was going wrong. Once I 
understood it I consider that it was just a good change to keep. If you 
think otherwise I can revert this part.


I also noted that gdb consider the filters as a filo list, not fifo. And 
I think that the 1st filters registered are the most extensively used. I 
can propose to invert all the registration if you think it worth it.





@@ -2105,29 +2120,29 @@ def register_type_printers(obj):
  return

  # Add type printers for typedefs std::string, std::wstring etc.
-for ch in ('', 'w', 'u8', 'u16', 'u32'):
-add_one_type_printer(obj, 'basic_string', ch + 'string')
-add_one_type_printer(obj, '__cxx11::basic_string', ch + 'string')
+for ch in (('char', ''), ('wchar_t', 'w'), ('char8_t', 'u8'),
('char16_t', 'u16'), ('char32_t', 'u32')):
+add_one_type_printer(obj, 'basic_string<' + ch[0], ch[1] + 'string')
+add_one_type_printer(obj, '__cxx11::basic_string<' + ch[0],
ch[1] + 'string')


As the docs for FilteringTypePrinter says, the first argument is
supposed to be the class template name:

class FilteringTypePrinter(object):
 r"""
 A type printer that uses typedef names for common template specializations.

 Args:
 match (str): The class template to recognize.
 name (str): The typedef-name that will be used instead.

 Checks if a specialization of the class template 'match' is the same type
 as the typedef 'name', and prints it as 'name' instead.

 e.g. if an instantiation of std::basic_istream is the same type as
 std::istream then print it as std::istream.
 """

With this change, the "class template" is sometimes just a string
prefix of a particular specialization, e.g. "basic_string




Re: [PATCH] Fix gdb printers for std::string

2022-10-01 Thread François Dumont via Gcc-patches
I had forgotten to re-run tests after I removed the #define 
_GLIBCXX_USE_CXX11_ABI 0.


The comment was misleading, it could also impact output of std::list.

I am also restoring the correct std::string alias for 
std::__cxx11::basic_string, even if with my workaround it doesn't really 
matter as the one for std::basic_string will be used.


I also restored the printer for std::__cxx11::string typedef. Is it 
intentional to keep this ?


    libstdc++: Fix gdb pretty printers when dealing with std::string

    Since revision 33b43b0d8cd2de722d177ef823930500948a7487 std::string 
and other
    similar typedef are ambiguous from a gdb point of view because it 
matches both
    std::basic_string and std::__cxx11::basic_string 
symbols. For those
    typedef add a workaround to accept the substitution as long as the 
same regardless

    of __cxx11 namespace.

    Also avoid to register printers for types in std::__cxx11::__8:: 
namespace, there is

    no such symbols.

    libstdc++-v3/ChangeLog:

    * libstdc++-v3/python/libstdcxx/v6/printers.py 
(Printer.add_version): Do not add

    version namespace for __cxx11 symbols.
    (add_one_template_type_printer): Likewise.
    (add_one_type_printer): Likewise.
    (FilteringTypePrinter._recognizer.recognize): Add a 
workaround for std::string & al
    ambiguous typedef matching both std:: and std::__cxx11:: 
symbols.
    (register_type_printers): Refine type registration to limit 
false positive in
    FilteringTypePrinter._recognize.recognize requiring to look 
for the type in gdb.
    * libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc: 
Remove obsolete

    \#define _GLIBCXX_USE_CXX11_ABI 0.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc: Likewise. 
Adapt test

    to accept std::__cxx11::list.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.
    * libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc: 
Likewise and remove

    xfail for c++20 and debug mode.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc: Likewise.


Ok to commit ?

François

On 28/09/22 22:42, François Dumont wrote:
Sometimes substitution of basic_string by one of the std::string 
typeedef fails. Here is the fix.


    libstdc++: Fix gdb pretty printers when dealing with std::string

    Since revision 33b43b0d8cd2de722d177ef823930500948a7487 
std::string and other
    similar typedef are ambiguous from a gdb point of view because it 
matches both
    std::basic_string and std::__cxx11::basic_string 
symbols. For those
    typedef add a workaround to accept the substitution as long as the 
same regardless

    of __cxx11 namespace.

    Also avoid to register printers for types in std::__cxx11::__8:: 
namespace, there is

    no such symbols.

    libstdc++-v3/ChangeLog:

    * libstdc++-v3/python/libstdcxx/v6/printers.py 
(Printer.add_version): Do not add

    version namespace for __cxx11 symbols.
    (add_one_template_type_printer): Likewise.
    (add_one_type_printer): Likewise.
    (FilteringTypePrinter._recognizer.recognize): Add a 
workaround for std::string & al
    ambiguous typedef matching both std:: and std::__cxx11:: 
symbols.
    (register_type_printers): Refine type registration to 
limit false positive in
    FilteringTypePrinter._recognize.recognize requiring to 
look for the type in gdb.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc: Remove obsolete

    \#define _GLIBCXX_USE_CXX11_ABI 0.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc: Likewise.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc: Likewise and 
remove

    xfail for c++20 and debug mode.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc: Likewise.


Tested under x86_64 linux w/o _GLIBCXX_INLINE_VERSION and w/o 
_GLIBCXX_DEBUG.


I also tested it with my patch to use cxx11 abi in 
_GLIBCXX_INLINE_VERSION mode.


Ok to commit ?

François


diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 245b6e3dbcd..0f966fc79a7 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1857,7 +1857,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:
+if _versioned_namespace and not '__cxx11' in base:
 

[PATCH] Fix gdb printers for std::string

2022-09-28 Thread François Dumont via Gcc-patches
Sometimes substitution of basic_string by one of the std::string 
typeedef fails. Here is the fix.


    libstdc++: Fix gdb pretty printers when dealing with std::string

    Since revision 33b43b0d8cd2de722d177ef823930500948a7487 std::string 
and other
    similar typedef are ambiguous from a gdb point of view because it 
matches both
    std::basic_string and std::__cxx11::basic_string 
symbols. For those
    typedef add a workaround to accept the substitution as long as the 
same regardless

    of __cxx11 namespace.

    Also avoid to register printers for types in std::__cxx11::__8:: 
namespace, there is

    no such symbols.

    libstdc++-v3/ChangeLog:

    * libstdc++-v3/python/libstdcxx/v6/printers.py 
(Printer.add_version): Do not add

    version namespace for __cxx11 symbols.
    (add_one_template_type_printer): Likewise.
    (add_one_type_printer): Likewise.
    (FilteringTypePrinter._recognizer.recognize): Add a 
workaround for std::string & al
    ambiguous typedef matching both std:: and std::__cxx11:: 
symbols.
    (register_type_printers): Refine type registration to limit 
false positive in
    FilteringTypePrinter._recognize.recognize requiring to look 
for the type in gdb.
    * libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc: 
Remove obsolete

    \#define _GLIBCXX_USE_CXX11_ABI 0.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc: Likewise.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc: Likewise.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.
    * libstdc++-v3/testsuite/libstdc++-prettyprinters/80276.cc: 
Likewise and remove

    xfail for c++20 and debug mode.
    * 
libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc: Likewise.


Tested under x86_64 linux w/o _GLIBCXX_INLINE_VERSION and w/o 
_GLIBCXX_DEBUG.


I also tested it with my patch to use cxx11 abi in 
_GLIBCXX_INLINE_VERSION mode.


Ok to commit ?

François
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 245b6e3dbcd..b4878b93bb2 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1857,7 +1857,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:
+if _versioned_namespace and not '__cxx11' in base:
 vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' % _versioned_namespace, base)
 self.add(vbase + name, function)
 
@@ -2026,7 +2026,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:
+if _versioned_namespace and not '__cxx11' in name:
 # Add second type printer for same type in versioned namespace:
 ns = 'std::' + _versioned_namespace
 # PR 86112 Cannot use dict comprehension here:
@@ -2084,6 +2084,21 @@ class FilteringTypePrinter(object):
 pass
 if self.type_obj == type_obj:
 return strip_inline_namespaces(self.name)
+
+if self.type_obj is None:
+return None
+
+# Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols.
+ambiguous = False
+for ch in ('', 'w', 'u8', 'u16', 'u32'):
+if self.name == 'std::' + ch + 'string':
+ambiguous = True
+break
+
+if ambiguous:
+if self.type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''):
+return strip_inline_namespaces(self.name)
+
 return None
 
 def instantiate(self):
@@ -2093,7 +2108,7 @@ class FilteringTypePrinter(object):
 def add_one_type_printer(obj, match, name):
 printer = FilteringTypePrinter('std::' + match, 'std::' + name)
 gdb.types.register_type_printer(obj, printer)
-if _versioned_namespace:
+if _versioned_namespace and not '__cxx11' in match:
 ns = 'std::' + _versioned_namespace
 printer = FilteringTypePrinter(ns + match, ns + name)
 gdb.types.register_type_printer(obj, printer)
@@ -2105,29 +2120,26 @@ def register_type_printers(obj):
 return
 
 # Add type printers for typedefs std::string, std::wstring etc.
-for ch in ('', 'w', 'u8', 'u16', 'u32'):
-add_one_type_printer(obj, 'basic_string', ch + 'string')
-add_one_type_printer(obj, '__cxx11::basic_string', ch + 'string')
-# Typedefs for __cxx11::basic_string used to be in namespace __cxx11:
-add_one_type_printer(obj, '__cxx11::basic_string',
-   

[PATCH][_GLIBCXX_DEBUG][_GLIBCXX_INLINE_VERSION] Add missing printers

2022-09-22 Thread François Dumont via Gcc-patches

Hi

    This patch fix failures when _GLIBCXX_INLINE_VERSION mode and running:

make check-debug RUNTESTFLAGS=prettyprinters.exp

    libstdc++: [_GLIBCXX_INLINE_VERSION] Add gdb pretty print for 
_GLIBCXX_DEBUG


    In _GLIBCXX_DEBUG mode containers are in std::__debug namespace but 
not template
    parameters. In _GLIBCXX_INLINE_VERSION mode most types are in 
std::__8 namespace but
    not std::__debug containers. We need to register specific type 
printers for this

    combination.

    libstdc++-v3/ChangeLog:

    * python/libstdcxx/v6/printers.py 
(add_one_template_type_printer): Register
    printer for types in std::__debug namespace with template 
parameters in std::__8

    namespace.

Ok to commit ?

François
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 24a6462e496..1e9d0627e9f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2036,6 +2036,10 @@ def add_one_template_type_printer(obj, name, defargs):
 printer = TemplateTypePrinter(ns+name, defargs)
 gdb.types.register_type_printer(obj, printer)
 
+# Add type printer for same type in debug namespace:
+printer = TemplateTypePrinter('std::__debug::'+name, defargs)
+gdb.types.register_type_printer(obj, printer)
+
 class FilteringTypePrinter(object):
 r"""
 A type printer that uses typedef names for common template specializations.


[PATCH] Cleanup gdb printers.py

2022-09-21 Thread François Dumont via Gcc-patches
I stopped my research to find out if those types ever existed in 2001. 
Clearly they do not exist now.


    libstdc++: Remove useless gdb printer registrations.

    libstdc++-v3/ChangeLog:

    * python/libstdcxx/v6/printers.py: Remove printer 
registration for non-existing
    types std::__debug::unique_ptr, std::__debug::stack, 
std::__debug::queue,

    std::__debug::priority_queue.

Ok to commit ?

François
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index bd4289c1c62..5a3dcbd13f9 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2246,12 +2246,7 @@ def build_libstdcxx_dictionary ():
 libstdcxx_printer.add('std::__debug::map', StdMapPrinter)
 libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter)
 libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter)
-libstdcxx_printer.add('std::__debug::priority_queue',
-  StdStackOrQueuePrinter)
-libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter)
 libstdcxx_printer.add('std::__debug::set', StdSetPrinter)
-libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter)
-libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter)
 libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
 
 # These are the TR1 and C++11 printers.


[PATCH][_GLIBCXX_INLINE_VERSION] Fix test dg-prune-output

2022-09-14 Thread François Dumont via Gcc-patches

    libstdc++: [_GLIBCXX_INLINE_VERSION] Fix test dg-prune-output

    libstdc++-v3/ChangeLog:

    * 
testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: Adapt 
dg-prune-output to

    _GLIBCXX_INLINE_VERSION mode.


With this patch all tests are Ok in _GLIBCXX_INLINE_VERSION mode (at the 
time I'm writing this).


Ok to commit ?

François
diff --git a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc
index fc0b70b319c..bc66c13feee 100644
--- a/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc
@@ -1,6 +1,6 @@
 // { dg-do compile { target c++11 } }
 // { dg-prune-output "must be a complete" }
-// { dg-prune-output "'value' is not a member of 'std::is_move_cons" }
+// { dg-prune-output "'value' is not a member of 'std::(__8::)?is_move_cons" }
 // { dg-prune-output "invalid use of incomplete type" }
 
 // Copyright (C) 2019-2022 Free Software Foundation, Inc.


[PATCH][_GLIBCXX_INLINE_VERSION] Cleanup gnu-versioned-namespace.ver

2022-09-14 Thread François Dumont via Gcc-patches
    libstdc++: [_GLIBCXX_INLINE_VERSION] Cleanup 
gnu-versioned-namespace.ver


    Remove expressions for symbols in std::__detail::__8 namespace, 
they are obsolete since

    version namespace applies only at std:: level, not at sub-levels.

    libstdc++-v3/ChangeLog:

    * config/abi/pre/gnu-versioned-namespace.ver: Remove 
obsolete std::__detail::__8

    symbols.

Tested under Linux x86_64.

Ok to commit ?

François
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index b37199ece72..06ccaa80a58 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -76,20 +76,9 @@ GLIBCXX_8.0 {
 # locale
 _ZNSt3__89has_facetINS_*;
 
-# hash
-_ZNSt8__detail3__812__prime_listE;
-_ZNSt3tr18__detail3__812__prime_listE;
-
 # thread/mutex/condition_variable/future
 __once_proxy;
 
-# std::__detail::_List_node_base
-_ZNSt8__detail3__815_List_node_base7_M_hook*;
-_ZNSt8__detail3__815_List_node_base9_M_unhookEv;
-_ZNSt8__detail3__815_List_node_base10_M_reverseEv;
-_ZNSt8__detail3__815_List_node_base11_M_transfer*;
-_ZNSt8__detail3__815_List_node_base4swapER*;
-
 # std::__convert_to_v
 _ZNSt3__814__convert_to_v*;
 


Re: [PATCH] libstdc++: Refactor implementation of operator+ for std::string

2022-09-08 Thread François Dumont via Gcc-patches

On 05/09/22 20:30, Will Hawkins wrote:

Based on Jonathan's work, here is a patch for the implementation of operator+
on std::string that makes sure we always use the best allocation strategy.

I have attempted to learn from all the feedback that I got on a previous
submission -- I hope I did the right thing.

Passes abi and conformance testing on x86-64 trunk.

Sincerely,
Will

-- >8 --

Create a single function that performs one-allocation string concatenation
that can be used by various different version of operator+.

libstdc++-v3/ChangeLog:

* include/bits/basic_string.h:
Add common function that performs single-allocation string
concatenation. (__str_cat)
Use __str_cat to perform optimized operator+, where relevant.
* include/bits/basic_string.tcc::
Remove single-allocation implementation of operator+.

Signed-off-by: Will Hawkins 
---
  libstdc++-v3/include/bits/basic_string.h   | 66 --
  libstdc++-v3/include/bits/basic_string.tcc | 41 --
  2 files changed, 49 insertions(+), 58 deletions(-)

diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index 0df64ea98ca..4078651fadb 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3481,6 +3481,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
  _GLIBCXX_END_NAMESPACE_CXX11
  #endif
  
+  template

+_GLIBCXX20_CONSTEXPR
+inline _Str
+__str_concat(typename _Str::value_type const* __lhs,
+typename _Str::size_type __lhs_len,
+typename _Str::value_type const* __rhs,
+typename _Str::size_type __rhs_len,
+typename _Str::allocator_type const& __a)
+{
+  typedef typename _Str::allocator_type allocator_type;
+  typedef __gnu_cxx::__alloc_traits _Alloc_traits;
+  _Str __str(_Alloc_traits::_S_select_on_copy(__a));
+  __str.reserve(__lhs_len + __rhs_len);
+  __str.append(__lhs, __lhs_len);
+  __str.append(__rhs, __rhs_len);
+  return __str;
+}
+
// operator+
/**
 *  @brief  Concatenate two strings.
@@ -3490,13 +3508,14 @@ _GLIBCXX_END_NAMESPACE_CXX11
 */
template
  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
-basic_string<_CharT, _Traits, _Alloc>
+inline basic_string<_CharT, _Traits, _Alloc>
  operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  const basic_string<_CharT, _Traits, _Alloc>& __rhs)
  {
-  basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
-  __str.append(__rhs);
-  return __str;
+  typedef basic_string<_CharT, _Traits, _Alloc> _Str;
+  return std::__str_concat<_Str>(__lhs.c_str(), __lhs.size(),
+__rhs.c_str(), __rhs.size(),


You should use data() rather than c_str() here and all other operators.

It is currently the same but is more accurate in your context. Maybe one 
day it will make a difference.



+__lhs.get_allocator());
  }
  
/**

@@ -3507,9 +3526,16 @@ _GLIBCXX_END_NAMESPACE_CXX11
 */
template
  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
-basic_string<_CharT,_Traits,_Alloc>
+inline basic_string<_CharT,_Traits,_Alloc>


Why inlining ?

I guess it is done this way to limit code bloat.


  operator+(const _CharT* __lhs,
- const basic_string<_CharT,_Traits,_Alloc>& __rhs);
+ const basic_string<_CharT,_Traits,_Alloc>& __rhs)
+{
+  __glibcxx_requires_string(__lhs);
+  typedef basic_string<_CharT, _Traits, _Alloc> _Str;
+  return std::__str_concat<_Str>(__lhs, _Traits::length(__lhs),
+__rhs.c_str(), __rhs.size(),
+__rhs.get_allocator());
+}
  
/**

 *  @brief  Concatenate character and string.
@@ -3519,8 +3545,14 @@ _GLIBCXX_END_NAMESPACE_CXX11
 */
template
  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
-basic_string<_CharT,_Traits,_Alloc>
-operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
+inline basic_string<_CharT,_Traits,_Alloc>
+operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
+{
+  typedef basic_string<_CharT, _Traits, _Alloc> _Str;
+  return std::__str_concat<_Str>(__builtin_addressof(__lhs), 1,
+__rhs.c_str(), __rhs.size(),
+__rhs.get_allocator());
+}
  
/**

 *  @brief  Concatenate string and C string.
@@ -3534,11 +3566,12 @@ _GLIBCXX_END_NAMESPACE_CXX11
  operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
  const _CharT* __rhs)
  {
-  basic_string<_CharT, _Traits, _Alloc> __str(__lhs);
-  __str.append(__rhs);
-  return __str;
+  __glibcxx_requires_string(__rhs);
+  typedef basic_string<_CharT, _Traits, _Alloc> _Str;
+  return 

Re: [PATCH] Use mallinfo2 with glibc >= 2.33

2022-09-07 Thread François Dumont via Gcc-patches
    libstdc++: glibc mallinfo deprecated, use mallinfo2 when version => 
2.33


    glibc mallinfo is now deprecated resulting in make check-performance
    failure. When glibc => 2.33 prefer mallinfo2.

    libstdcxx-v3/ChangeLog:

    * testsuite/util/testsuite_performance.h 
(__gnu_test::MallocInfo): New.
    (__gnu_test::malloc_info): New, replace mallinfo on current 
platform

    supporting it and use mallinfo2 when glibc >= 2.33.

Tested under Linux x86_64.

Ok to commit ?

François

On 07/09/22 19:10, Jonathan Wakely wrote:

On Wed, 7 Sept 2022 at 18:03, François Dumont via Libstdc++
 wrote:

libstdc++: Use glibc >= 2.33 mallinfo2 function

mallinfo started to be deprecated which makes performance tests failed
to build, just
adopt mallinfo2.

libstdcxx-v3/ChangeLog:

  * testsuite/util/testsuite_performance.h (__mallinfo): New, our
own mallinfo

There's no reason to use a reserved name here, this isn't a header
that users include.

I would call the struct MallocInfo and the function malloc_info().
Even better, put them both in namespace __gnu_test, as
__gnu_test::MallocInfo and __gnu_test::malloc_info (without the extern
"C" language linkage). If we're not calling the glibc function
directly, but via our own wrapper, then there's no reason it has to
use the name "mallinfo", no reason it has to be in the global
namespace, and no reason it has to be extern "C" (in fact, I don't
think there was ever a reason for it to be extern "C").




  struct with just what we need. When using glibc >= 2.33 use
mallinfo2 to
  populate it.

Tested under Linux x86_64,

Ok to commit ?

François


diff --git a/libstdc++-v3/testsuite/util/testsuite_performance.h b/libstdc++-v3/testsuite/util/testsuite_performance.h
index 2e05bef8460..4f8b1eab8b9 100644
--- a/libstdc++-v3/testsuite/util/testsuite_performance.h
+++ b/libstdc++-v3/testsuite/util/testsuite_performance.h
@@ -36,42 +36,39 @@
 #include 
 
 #if defined (__linux__) || defined (__GLIBC__)
-#include 
-#elif defined (__FreeBSD__)
-extern "C"
-{
-  struct mallinfo
-  {
-int uordblks;
-int hblkhd;
-  };
+#include  // For mallinfo.
+#endif
 
-  struct mallinfo
-  mallinfo(void)
-  {
-struct mallinfo m = { (((std::size_t) sbrk (0) + 1023) / 1024), 0 };
-return m;
-  }
-}
-#elif !defined (__hpux__)
-extern "C"
+namespace __gnu_test
 {
-  struct mallinfo
+  struct MallocInfo
   {
-int uordblks;
-int hblkhd;
-  };
+MallocInfo() : uordblks(0), hblkhd(0) { }
+MallocInfo(std::size_t uordblocks, std::size_t hblockhd)
+  : uordblks(uordblocks), hblkhd(hblockhd)
+{ }
 
-  struct mallinfo empty = { 0, 0 };
+std::size_t uordblks;
+std::size_t hblkhd;
+  };
 
-  struct mallinfo
-  mallinfo(void)
-  { return empty; }
-}
+  MallocInfo
+  malloc_info()
+  {
+#if defined (__linux__) || defined (__hpux__) || defined (__GLIBC__)
+#if __GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 33
+struct mallinfo2 mi = mallinfo2();
+#else
+struct mallinfo mi = mallinfo();
+#endif
+return MallocInfo(mi.uordblks, mi.hblkhd);
+#elif defined (__FreeBSD__)
+return MallocInfostd::size_t) sbrk (0) + 1023) / 1024), 0);
+#else
+return MallocInfo();
 #endif
+  }
 
-namespace __gnu_test
-{
   class time_counter
   {
   private:
@@ -146,8 +143,8 @@ namespace __gnu_test
 int who;
 rusage	rusage_begin;
 rusage	rusage_end;
-struct mallinfo  	allocation_begin;
-struct mallinfo  	allocation_end;
+MallocInfo  	allocation_begin;
+MallocInfo  	allocation_end;
 
   public:
 resource_counter(int i = RUSAGE_SELF) : who(i)
@@ -168,7 +165,7 @@ namespace __gnu_test
   if (getrusage(who, _begin) != 0 )
 	memset(_begin, 0, sizeof(rusage_begin));
   void* p __attribute__((unused)) = malloc(0); // Needed for some implementations.
-  allocation_begin = mallinfo();
+  allocation_begin = malloc_info();
 }
 
 void
@@ -176,7 +173,7 @@ namespace __gnu_test
 {
   if (getrusage(who, _end) != 0 )
 	memset(_end, 0, sizeof(rusage_end));
-  allocation_end = mallinfo();
+  allocation_end = malloc_info();
 }
 
 int


[PATCH] Use mallinfo2 with glibc >= 2.33

2022-09-07 Thread François Dumont via Gcc-patches

libstdc++: Use glibc >= 2.33 mallinfo2 function

mallinfo started to be deprecated which makes performance tests failed 
to build, just

adopt mallinfo2.

libstdcxx-v3/ChangeLog:

    * testsuite/util/testsuite_performance.h (__mallinfo): New, our 
own mallinfo
    struct with just what we need. When using glibc >= 2.33 use 
mallinfo2 to

    populate it.

Tested under Linux x86_64,

Ok to commit ?

François
diff --git a/libstdc++-v3/testsuite/util/testsuite_performance.h b/libstdc++-v3/testsuite/util/testsuite_performance.h
index 2e05bef8460..dc002b8c390 100644
--- a/libstdc++-v3/testsuite/util/testsuite_performance.h
+++ b/libstdc++-v3/testsuite/util/testsuite_performance.h
@@ -35,37 +35,49 @@
 #include 
 #include 
 
-#if defined (__linux__) || defined (__GLIBC__)
-#include 
-#elif defined (__FreeBSD__)
 extern "C"
 {
-  struct mallinfo
+  struct __mallinfo
   {
-int uordblks;
-int hblkhd;
+size_t uordblks;
+size_t hblkhd;
   };
+}
 
-  struct mallinfo
-  mallinfo(void)
+#if defined (__linux__) || defined (__GLIBC__)
+#include 
+extern "C"
+{
+  struct __mallinfo
+  __mallinfo(void)
+  {
+#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 33
+struct mallinfo2 mi = mallinfo2();
+struct __mallinfo m = { mi.uordblks, mi.hblkhd };
+#else
+struct mallinfo mi = mallinfo();
+struct __mallinfo m = { mi.uordblks, mi.hblkhd };
+#endif
+return m;
+  }
+}
+#elif defined (__FreeBSD__)
+extern "C"
+{
+  struct __mallinfo
+  __mallinfo(void)
   {
-struct mallinfo m = { (((std::size_t) sbrk (0) + 1023) / 1024), 0 };
+struct __mallinfo m = { (((std::size_t) sbrk (0) + 1023) / 1024), 0 };
 return m;
   }
 }
 #elif !defined (__hpux__)
 extern "C"
 {
-  struct mallinfo
-  {
-int uordblks;
-int hblkhd;
-  };
-
-  struct mallinfo empty = { 0, 0 };
+  struct __mallinfo empty = { 0, 0 };
 
-  struct mallinfo
-  mallinfo(void)
+  struct __mallinfo
+  __mallinfo(void)
   { return empty; }
 }
 #endif
@@ -146,8 +158,8 @@ namespace __gnu_test
 int who;
 rusage	rusage_begin;
 rusage	rusage_end;
-struct mallinfo  	allocation_begin;
-struct mallinfo  	allocation_end;
+struct __mallinfo  	allocation_begin;
+struct __mallinfo  	allocation_end;
 
   public:
 resource_counter(int i = RUSAGE_SELF) : who(i)
@@ -168,7 +180,7 @@ namespace __gnu_test
   if (getrusage(who, _begin) != 0 )
 	memset(_begin, 0, sizeof(rusage_begin));
   void* p __attribute__((unused)) = malloc(0); // Needed for some implementations.
-  allocation_begin = mallinfo();
+  allocation_begin = __mallinfo();
 }
 
 void
@@ -176,7 +188,7 @@ namespace __gnu_test
 {
   if (getrusage(who, _end) != 0 )
 	memset(_end, 0, sizeof(rusage_end));
-  allocation_end = mallinfo();
+  allocation_end = __mallinfo();
 }
 
 int


Re: Add three way lower_bound

2022-08-31 Thread François Dumont via Gcc-patches

Any feedback regarding this proposal:
https://gcc.gnu.org/pipermail/libstdc++/2021-June/052821.html


On 23/06/21 22:34, François Dumont wrote:

Hi

Following the message to propose an alternative lower_bound and the 
reply to use three way comparison I try to implement this.


Before going further I wonder if this is something possible ?

The purpose of the:

if constexpr (three_way_comparable<>)

is to make sure that we use it only if there is a proper <=> operator 
defined. Afai understood what is in  we can have the 
__synth3way for any type as long as < exist. But I think that if <=> 
is implemented in terms of < then it might be too expensive, the 
actual lower_bound might already be implemented this way.


My main concerns is of course Standard conformity, could it be ok ?

François

diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 84a1f9e98f6..7a0c42a4909 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1472,6 +1472,48 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   return __first;
 }
 
+#if __cpp_lib_three_way_comparison
+  template
+_GLIBCXX20_CONSTEXPR
+_ForwardIterator
+__lower_bound_three_way(_ForwardIterator __first, _ForwardIterator __last,
+			const _Tp& __val, _Compare __comp)
+{
+  auto __len = std::distance(__first, __last);
+
+  while (__len > 0)
+	{
+	  auto __half = __len >> 1;
+	  if (__half == 0)
+	{
+	  if (auto __c = __comp(*__first, __val); __c < 0)
+		return std::next(__first);
+	  return __first;
+	}
+
+	  _ForwardIterator __prev_mid = __first;
+	  std::advance(__prev_mid, __half - 1);
+	  _ForwardIterator __middle = std::next(__prev_mid);
+	  if (auto __c = __comp(*__middle, __val); __c != 0)
+	{
+	  if (__c < 0)
+		{
+		  __first = __middle;
+		  ++__first;
+		  __len = __len - __half - 1;
+		}
+	  else
+		__len = __half;
+	}
+	  else if (__c = __comp(*__prev_mid, __val); __c != 0)
+	return __middle;
+	  else // __c == 0.
+	__len = __half - 1;
+	}
+  return __first;
+}
+#endif
+
   /**
*  @brief Finds the first position in which @a val could be inserted
* without changing the ordering.
@@ -1495,6 +1537,13 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
 	typename iterator_traits<_ForwardIterator>::value_type, _Tp>)
   __glibcxx_requires_partitioned_lower(__first, __last, __val);
 
+#if __cpp_lib_three_way_comparison
+  if constexpr (three_way_comparable_with<
+		typename iterator_traits<_ForwardIterator>::reference,
+		const _Tp&>)
+	return std::__lower_bound_three_way(__first, __last, __val,
+	compare_three_way{});
+#endif
   return std::__lower_bound(__first, __last, __val,
 __gnu_cxx::__ops::__iter_less_val());
 }


Re: [PATCH] Add _GLIBCXX_DEBUG backtrace generation

2022-08-31 Thread François Dumont via Gcc-patches

On 31/08/22 12:11, Jonathan Wakely wrote:

On Wed, 31 Aug 2022 at 06:05, François Dumont  wrote:

After a second thought here is an even cleaner version. No more function
rename, current pretty_print is fine.

  libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand

Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace
generation on
  _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the
lib with:

  --enable-libstdcxx-backtrace=yes

  libstdc++-v3/ChangeLog:

  * include/debug/formatter.h
  [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define.
  [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare.
[_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New.
[_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New.
  * src/c++11/debug.cc
[_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New.
  (_Error_formatter::_M_error()): Adapt.
  * src/libbacktrace/Makefile.am: Add backtrace.c.
  * src/libbacktrace/Makefile.in: Regenerate.
  * src/libbacktrace/backtrace-rename.h (backtrace_full): New.
  *
testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test.
  * doc/xml/manual/debug_mode.xml: Document
_GLIBCXX_DEBUG_BACKTRACE.
  * doc/xml/manual/using.xml: Likewise.
Ok to commit ?

OK for trunk, thanks.

The small change to print_raw in this patch makes me wonder whether
that function is actually useful.

It supports two modes, print with max precision, and print without.
The only time we use it to print with max precision we pass a string
of exactly the right length, so the precision is not needed (but the
caller has to get the string length correct: if we increase _S_indent
and do not increase the "" literal passed to print_raw, the
effects would be wrong).

Wouldn't it be better to just use fprintf directly when we want to
print without precision, and use a minimum field width instead of
precision for indenting? i.e. ...

--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -608,15 +608,6 @@ namespace
 print_literal(PrintContext& ctx, const char()[Length])
 { print_word(ctx, word, Length - 1); }

-  void
-  print_raw(PrintContext& ctx, const char* str, ptrdiff_t nbc = -1)
-  {
-if (nbc >= 0)
-  ctx._M_column += fprintf(stderr, "%.*s", (int)nbc, str);
-else
-  ctx._M_column += fprintf(stderr, "%s", str);
-  }
-
   void
   print_word(PrintContext& ctx, const char* word, ptrdiff_t nbc = -1)
   {
@@ -643,12 +634,9 @@ namespace
|| (ctx._M_column + visual_length < ctx._M_max_length)
|| (visual_length >= ctx._M_max_length && ctx._M_column == 1))
   {
-   // If this isn't the first line, indent
+   // If this isn't the first line, indent.
if (ctx._M_column == 1 && !ctx._M_first_line)
- {
-   const char spacing[PrintContext::_S_indent + 1] = "";
-   print_raw(ctx, spacing, PrintContext::_S_indent);
- }
+ ctx._M_column += fprintf(stderr, "%*c", PrintContext::_S_indent, ' ');

I did not know this syntax, it looks definitely better.


int written = fprintf(stderr, "%.*s", (int)length, word);

@@ -1112,7 +1100,7 @@ namespace __gnu_debug
 PrintContext ctx;
 if (_M_file)
   {
-   print_raw(ctx, _M_file);
+   ctx._M_column += fprintf(stderr, "%s", _M_file);
print_literal(ctx, ":");
go_to_next_line = true;
   }


Do you take care or you prefer I do ?




Re: [PATCH] Add _GLIBCXX_DEBUG backtrace generation

2022-08-30 Thread François Dumont via Gcc-patches
After a second thought here is an even cleaner version. No more function 
rename, current pretty_print is fine.


    libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand

  Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace 
generation on
    _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the 
lib with:


    --enable-libstdcxx-backtrace=yes

    libstdc++-v3/ChangeLog:

    * include/debug/formatter.h
    [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define.
    [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare.
[_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New.
[_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New.
    * src/c++11/debug.cc 
[_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New.

    (_Error_formatter::_M_error()): Adapt.
    * src/libbacktrace/Makefile.am: Add backtrace.c.
    * src/libbacktrace/Makefile.in: Regenerate.
    * src/libbacktrace/backtrace-rename.h (backtrace_full): New.
    * 
testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test.
    * doc/xml/manual/debug_mode.xml: Document 
_GLIBCXX_DEBUG_BACKTRACE.

    * doc/xml/manual/using.xml: Likewise.
Ok to commit ?

François

On 09/08/22 10:07, François Dumont wrote:

On 08/08/22 15:29, Jonathan Wakely wrote:

On Wed, 13 Jul 2022 at 18:28, François Dumont via Libstdc++
 wrote:

libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand

    Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace generation
on _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the lib
with:

    --enable-libstdcxx-backtrace=yes

    libstdc++-v3/ChangeLog:

    * include/debug/formatter.h
    [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define.
[_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define.
    [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define.
    [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare.
[_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New.
[_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New.
    * src/c++11/debug.cc (pretty_print): Rename into...
    (print_function): ...that.

This does more than just rename it, what are the other changes for?


Nothing, I'm starting to remember what you did on this, reverted.






[_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New.
    (_Error_formatter::_M_error()): Adapt.
    * src/libbacktrace/Makefile.am: Add backtrace.c.
    * src/libbacktrace/Makefile.in: Regenerate.
    * src/libbacktrace/backtrace-rename.h (backtrace_full): New.
    * testsuite/23_containers/vector/debug/assign4_neg.cc: Add 
backtrace

  generation.
    * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE.
    * doc/xml/manual/using.xml: Likewise.

Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes.

Ok to commit ?



--- a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc
@@ -16,6 +16,7 @@
// .
//
// { dg-do run { xfail *-*-* } }
+// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" }

#include 
#include 

This will fail to link if the static lib isn't available.

Good point ! So I am introducing a new test case with the necessary dg 
directive.


It is a 'run' test case even if what is really tested is only the 
compilation/link part. For the run part someone has to look at the log 
file.


François


diff --git a/libstdc++-v3/doc/xml/manual/debug_mode.xml b/libstdc++-v3/doc/xml/manual/debug_mode.xml
index 988c4a93601..dadc0cd1bb4 100644
--- a/libstdc++-v3/doc/xml/manual/debug_mode.xml
+++ b/libstdc++-v3/doc/xml/manual/debug_mode.xml
@@ -161,6 +161,12 @@ which always works correctly.
   GLIBCXX_DEBUG_MESSAGE_LENGTH can be used to request a
   different length.
 
+Note that libstdc++ is able to produce backtraces on error.
+  It requires that you configure libstdc++ build with
+  --enable-libstdcxx-backtrace=yes.
+  Use -D_GLIBCXX_DEBUG_BACKTRACE to activate it.
+  You'll then have to link with libstdc++_libbacktrace static library
+  (-lstdc++_libbacktrace) to build your application.
 
 
 Using a Specific Debug Container
diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml
index 0b9a0c98518..0acdba6b3bd 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1144,6 +1144,15 @@ 

Re: [PATCH][_GLIBCXX_DEBUG] Review null string assertions (was: Add basic_string::starts_with/ends_with checks)

2022-08-30 Thread François Dumont via Gcc-patches
If I got your point correctly here is this patch again with just the 
change on '0' becoming 'nullptr' in assertions.


    libstdc++: [_GLIBCXX_DEBUG] Review nullptr assertion diagnostics

    Review null string checks to show:
    _String != nullptr

    rather than:
    _String != 0

    libstdc++-v3/ChangeLog:

    * include/debug/debug.h: Use nullptr rather than '0' in 
checks in post-C++11.

    * include/debug/string: Likewise.
    * 
testsuite/21_strings/basic_string/operations/ends_with/char.cc: Use 
__gnu_test::string.
    * 
testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc: Likewise.
    * 
testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc: Likewise.
    * 
testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc: 
Likewise.
    * 
testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc: 
Likewise.
    * 
testsuite/21_strings/basic_string/operations/starts_with/char.cc: Likewise..


Ok to commit ?

François

On 26/08/22 11:31, Jonathan Wakely wrote:

On Sun, 14 Aug 2022 at 16:34, François Dumont via Libstdc++
 wrote:

I think we can add those checks.

Note that I wonder if it was needed as in basic_string_view I see usages
of __attribute__((__nonnull__)). But running the test I saw no impact
even after I try to apply this attribute to the starts_with/ends_with
methods themselves.

That should cause warnings, and does when I try it.

As you say, the relevant string_view constructor already has that anyway:

   __attribute__((__nonnull__)) constexpr
   basic_string_view(const _CharT* __str) noexcept

And so does string_view::find. The problem is that those only help if
the compiler inlines the calls to those functions and so can propagate
the null value all the way down to a function with the attribute.
Adding the attribute to the relevant starts_with, ends_with and
contains functions makes the diagnostics more likely to be emitted
without optimization.


Also note that several checks like the ones I am adding here are XFAILS
when using 'make check' because of the segfault rather than on a proper
debug checks. Would you prefer to add dg-require-debug-mode to those ?

  libstdc++: [_GLIBCXX_DEBUG] Add basic_string::starts_with/ends_with
checks

  Add simple checks on C string parameters which should not be null.

  Review null string checks to show:
  _String != nullptr

  rather than:
  _String != 0

I don't really like the extra complexity in the macros, but this does
seem like a nice improvement for what users see.

We could use __null for C++98, which is a compiler keyword that
expands to a null pointer constant, but I'm not sure if that would be
clear to all users or not. Maybe 0 is better.

.


diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
index 28e250f0c50..f4233760426 100644
--- a/libstdc++-v3/include/debug/debug.h
+++ b/libstdc++-v3/include/debug/debug.h
@@ -118,10 +118,17 @@ namespace __gnu_debug
   __glibcxx_check_heap(_First,_Last)
 # define __glibcxx_requires_heap_pred(_First,_Last,_Pred)	\
   __glibcxx_check_heap_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_string(_String)	\
+# if __cplusplus < 201103L
+#  define __glibcxx_requires_string(_String)	\
   _GLIBCXX_DEBUG_PEDASSERT(_String != 0)
-# define __glibcxx_requires_string_len(_String,_Len)	\
+#  define __glibcxx_requires_string_len(_String,_Len)	\
   _GLIBCXX_DEBUG_PEDASSERT(_String != 0 || _Len == 0)
+# else
+#  define __glibcxx_requires_string(_String)	\
+  _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr)
+#  define __glibcxx_requires_string_len(_String,_Len)	\
+  _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr || _Len == 0)
+# endif
 # define __glibcxx_requires_irreflexive(_First,_Last)	\
   __glibcxx_check_irreflexive(_First,_Last)
 # define __glibcxx_requires_irreflexive2(_First,_Last)	\
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index c32eb41eacd..574a78e3dac 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -50,14 +50,25 @@
 #endif
 
 #ifdef _GLIBCXX_DEBUG_PEDANTIC
-# define __glibcxx_check_string(_String)\
+# if __cplusplus < 201103L
+#  define __glibcxx_check_string(_String)			\
   _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0,		\
 __FILE__, __LINE__,		\
 __PRETTY_FUNCTION__);
-# define __glibcxx_check_string_len(_String,_Len)		\
+#  define __glibcxx_check_string_len(_String,_Len)		\
   _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0 || _Len == 0,	\
 __FILE__, __LINE__,		\
 __PRETTY_FUNCTION__);
+# else
+#  define __glibcxx_check_string(_String)			\
+  _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr,		\
+__FILE__, __LINE__,		\
+__PRETTY_FUNCTION__);
+#  define __glibcxx_check_string_len(_String,_Len)		\
+  _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr || _Len == 0,	\
+__FILE__, 

[PATCH][_GLIBCXX_ASSERTIONS] Activate __glibcxx_requires_string/__glibcxx_requires_string_len

2022-08-16 Thread François Dumont via Gcc-patches
Following my remark about tests XFAIL-ing when running 'make check' I'd 
like to propose this to avoid this situation.


    libstdc++: [_GLIBCXX_ASSERTIONS] Activate basic 
_GLIBCXX_DEBUB_PEDANTIC checks


    Activate __glibcxx_requires_string/__glibcxx_requires_string_len in 
basic _GLIBCXX_ASSERTIONS
    mode which is then considering _GLIBCXX_DEBUG_PEDANTIC for this 
purpose.


    Thanks to this change add _GLIBCXX_ASSERTIONS to some tests that 
are otherwise XFAIL-ing on

    segmentation fault rather than on a proper __glibcxx_assert call.

    libstdc++-v3/ChangeLog:

    * include/debug/debug.h (__glibcxx_requires_string, 
__glibcxx_requires_string_len): Move

    definitions...
    * include/debug/assertions.h: ... here. Definition now 
depends on _GLIBCXX_ASSERTIONS rather

    than _GLIBCXX_DEBUG.
    * 
testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc: Add 
_GLIBCXX_ASSERTIONS

    define.
    * 
testsuite/21_strings/basic_string/operations/ends_with/wchar_t_neg.cc: 
Likewise.
    * 
testsuite/21_strings/basic_string/operations/starts_with/char_neg.cc: 
Likewise.
    * 
testsuite/21_strings/basic_string/operations/starts_with/wchar_t_neg.cc: 
Likewise.


Tested under Linux x86_64.

Ok to commit ?

François
diff --git a/libstdc++-v3/include/debug/assertions.h b/libstdc++-v3/include/debug/assertions.h
index 57c0ab2c3cf..fcc910c7396 100644
--- a/libstdc++-v3/include/debug/assertions.h
+++ b/libstdc++-v3/include/debug/assertions.h
@@ -43,6 +43,8 @@
 # define __glibcxx_requires_non_empty_range(_First,_Last)
 # define __glibcxx_requires_nonempty()
 # define __glibcxx_requires_subscript(_N)
+# define __glibcxx_requires_string(_String)
+# define __glibcxx_requires_string_len(_String,_Len)
 #else
 
 // Verify that [_First, _Last) forms a non-empty iterator range.
@@ -53,6 +55,22 @@
 // Verify that the container is nonempty
 # define __glibcxx_requires_nonempty()		\
   __glibcxx_assert(!this->empty())
+# ifdef _GLIBCXX_DEBUG_PEDANTIC
+#  if __cplusplus < 201103L
+#   define __glibcxx_requires_string(_String)	\
+  __glibcxx_assert(_String != 0)
+#   define __glibcxx_requires_string_len(_String,_Len)	\
+  __glibcxx_assert(_String != 0 || _Len == 0)
+#  else
+#   define __glibcxx_requires_string(_String)	\
+  __glibcxx_assert(_String != nullptr)
+#   define __glibcxx_requires_string_len(_String,_Len)	\
+  __glibcxx_assert(_String != nullptr || _Len == 0)
+#  endif // C++11
+# else
+#  define __glibcxx_requires_string(_String)
+#  define __glibcxx_requires_string_len(_String,_Len)
+# endif // _GLIBCXX_DEBUG_PEDANTIC
 #endif
 
 #ifdef _GLIBCXX_DEBUG
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
index f4233760426..5593b4fe92c 100644
--- a/libstdc++-v3/include/debug/debug.h
+++ b/libstdc++-v3/include/debug/debug.h
@@ -78,8 +78,6 @@ namespace __gnu_debug
 # define __glibcxx_requires_partitioned_upper_pred(_First,_Last,_Value,_Pred)
 # define __glibcxx_requires_heap(_First,_Last)
 # define __glibcxx_requires_heap_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_string(_String)
-# define __glibcxx_requires_string_len(_String,_Len)
 # define __glibcxx_requires_irreflexive(_First,_Last)
 # define __glibcxx_requires_irreflexive2(_First,_Last)
 # define __glibcxx_requires_irreflexive_pred(_First,_Last,_Pred)
@@ -118,17 +116,6 @@ namespace __gnu_debug
   __glibcxx_check_heap(_First,_Last)
 # define __glibcxx_requires_heap_pred(_First,_Last,_Pred)	\
   __glibcxx_check_heap_pred(_First,_Last,_Pred)
-# if __cplusplus < 201103L
-#  define __glibcxx_requires_string(_String)	\
-  _GLIBCXX_DEBUG_PEDASSERT(_String != 0)
-#  define __glibcxx_requires_string_len(_String,_Len)	\
-  _GLIBCXX_DEBUG_PEDASSERT(_String != 0 || _Len == 0)
-# else
-#  define __glibcxx_requires_string(_String)	\
-  _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr)
-#  define __glibcxx_requires_string_len(_String,_Len)	\
-  _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr || _Len == 0)
-# endif
 # define __glibcxx_requires_irreflexive(_First,_Last)	\
   __glibcxx_check_irreflexive(_First,_Last)
 # define __glibcxx_requires_irreflexive2(_First,_Last)	\
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc
index 7a7b8dd077d..6080ddc0555 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc
@@ -15,7 +15,7 @@
 // with this library; see the file COPYING3.  If not see
 // .
 //
-// { dg-options "-std=gnu++2a -O0" }
+// { dg-options "-std=gnu++2a -D_GLIBCXX_ASSERTIONS" }
 // { dg-do run { target c++2a xfail *-*-* } }
 
 #define _GLIBCXX_DEBUG_PEDANTIC
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/wchar_t_neg.cc 

Re: [PATCH][_GLIBCXX_DEBUG] Add basic_string::starts_with/ends_with checks

2022-08-15 Thread François Dumont via Gcc-patches

With the patch !

On 14/08/22 17:32, François Dumont wrote:

I think we can add those checks.

Note that I wonder if it was needed as in basic_string_view I see 
usages of __attribute__((__nonnull__)). But running the test I saw no 
impact even after I try to apply this attribute to the 
starts_with/ends_with methods themselves.


Also note that several checks like the ones I am adding here are 
XFAILS when using 'make check' because of the segfault rather than on 
a proper debug checks. Would you prefer to add dg-require-debug-mode 
to those ?


    libstdc++: [_GLIBCXX_DEBUG] Add 
basic_string::starts_with/ends_with checks


    Add simple checks on C string parameters which should not be null.

    Review null string checks to show:
    _String != nullptr

    rather than:
    _String != 0

    libstdc++-v3/ChangeLog:

    * include/bits/basic_string.h (starts_with, ends_with): 
Add __glibcxx_check_string.
    * include/bits/cow_string.h (starts_with, ends_with): 
Likewise.
    * include/debug/debug.h: Use nullptr rather than '0' in 
checks in C++11.

    * include/debug/string: Likewise.
    * 
testsuite/21_strings/basic_string/operations/ends_with/char.cc: Use 
__gnu_test::string.
    * 
testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc: Use 
__gnu_test::wstring.
    * 
testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc: 
Use __gnu_test::wstring.
    * 
testsuite/21_strings/basic_string/operations/starts_with/char.cc: Use 
__gnu_test::string.
    * 
testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc: 
New test.
    * 
testsuite/21_strings/basic_string/operations/ends_with/wchar_t_neg.cc: 
New test.
    * 
testsuite/21_strings/basic_string/operations/starts_with/char_neg.cc: 
New test.
    * 
testsuite/21_strings/basic_string/operations/starts_with/wchar_t_neg.cc: 
New test.


Tested under linux normal and debug modes.

François


diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index b04fba95678..d06330e6c48 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3402,7 +3402,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
   constexpr bool
   starts_with(const _CharT* __x) const noexcept
-  { return __sv_type(this->data(), this->size()).starts_with(__x); }
+  {
+	__glibcxx_requires_string(__x);
+	return __sv_type(this->data(), this->size()).starts_with(__x);
+  }
 
   constexpr bool
   ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
@@ -3414,7 +3417,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
   constexpr bool
   ends_with(const _CharT* __x) const noexcept
-  { return __sv_type(this->data(), this->size()).ends_with(__x); }
+  {
+	__glibcxx_requires_string(__x);
+	return __sv_type(this->data(), this->size()).ends_with(__x);
+  }
 #endif // C++20
 
 #if __cplusplus > 202002L
diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h
index f16e33ac1ef..59b36a1006a 100644
--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -3014,7 +3014,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   bool
   starts_with(const _CharT* __x) const noexcept
-  { return __sv_type(this->data(), this->size()).starts_with(__x); }
+  {
+	__glibcxx_requires_string(__x);
+	return __sv_type(this->data(), this->size()).starts_with(__x);
+  }
 
   bool
   ends_with(basic_string_view<_CharT, _Traits> __x) const noexcept
@@ -3026,7 +3029,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   bool
   ends_with(const _CharT* __x) const noexcept
-  { return __sv_type(this->data(), this->size()).ends_with(__x); }
+  {
+	__glibcxx_requires_string(__x);
+	return __sv_type(this->data(), this->size()).ends_with(__x);
+  }
 #endif // C++20
 
 #if __cplusplus > 202011L
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
index 28e250f0c50..f4233760426 100644
--- a/libstdc++-v3/include/debug/debug.h
+++ b/libstdc++-v3/include/debug/debug.h
@@ -118,10 +118,17 @@ namespace __gnu_debug
   __glibcxx_check_heap(_First,_Last)
 # define __glibcxx_requires_heap_pred(_First,_Last,_Pred)	\
   __glibcxx_check_heap_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_string(_String)	\
+# if __cplusplus < 201103L
+#  define __glibcxx_requires_string(_String)	\
   _GLIBCXX_DEBUG_PEDASSERT(_String != 0)
-# define __glibcxx_requires_string_len(_String,_Len)	\
+#  define __glibcxx_requires_string_len(_String,_Len)	\
   _GLIBCXX_DEBUG_PEDASSERT(_String != 0 || _Len == 0)
+# else
+#  define __glibcxx_requires_string(_String)	\
+  _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr)
+#  define __glibcxx_requires_string_len(_String,_Len)	\
+  _GLIBCXX_DEBUG_PEDASSERT(_String != nullptr || _Len == 0)
+# endif
 # define 

[PATCH][_GLIBCXX_DEBUG] Add basic_string::starts_with/ends_with checks

2022-08-14 Thread François Dumont via Gcc-patches

I think we can add those checks.

Note that I wonder if it was needed as in basic_string_view I see usages 
of __attribute__((__nonnull__)). But running the test I saw no impact 
even after I try to apply this attribute to the starts_with/ends_with 
methods themselves.


Also note that several checks like the ones I am adding here are XFAILS 
when using 'make check' because of the segfault rather than on a proper 
debug checks. Would you prefer to add dg-require-debug-mode to those ?


    libstdc++: [_GLIBCXX_DEBUG] Add basic_string::starts_with/ends_with 
checks


    Add simple checks on C string parameters which should not be null.

    Review null string checks to show:
    _String != nullptr

    rather than:
    _String != 0

    libstdc++-v3/ChangeLog:

    * include/bits/basic_string.h (starts_with, ends_with): Add 
__glibcxx_check_string.

    * include/bits/cow_string.h (starts_with, ends_with): Likewise.
    * include/debug/debug.h: Use nullptr rather than '0' in 
checks in C++11.

    * include/debug/string: Likewise.
    * 
testsuite/21_strings/basic_string/operations/ends_with/char.cc: Use 
__gnu_test::string.
    * 
testsuite/21_strings/basic_string/operations/ends_with/wchar_t.cc: Use 
__gnu_test::wstring.
    * 
testsuite/21_strings/basic_string/operations/starts_with/wchar_t.cc: Use 
__gnu_test::wstring.
    * 
testsuite/21_strings/basic_string/operations/starts_with/char.cc: Use 
__gnu_test::string.
    * 
testsuite/21_strings/basic_string/operations/ends_with/char_neg.cc: New 
test.
    * 
testsuite/21_strings/basic_string/operations/ends_with/wchar_t_neg.cc: 
New test.
    * 
testsuite/21_strings/basic_string/operations/starts_with/char_neg.cc: 
New test.
    * 
testsuite/21_strings/basic_string/operations/starts_with/wchar_t_neg.cc: 
New test.


Tested under linux normal and debug modes.

François




  1   2   3   >