Bug 85965 - [8/9/10 Regression] G++ gives cryptic error instead of incomplete type
Summary: [8/9/10 Regression] G++ gives cryptic error instead of incomplete type
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 8.1.0
: P3 normal
Target Milestone: 8.4
Assignee: Jonathan Wakely
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2018-05-29 05:26 UTC by Paul Smith
Modified: 2019-08-30 14:19 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 7.3.0
Known to fail: 8.3.0, 9.0
Last reconfirmed: 2019-03-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Smith 2018-05-29 05:26:44 UTC
Compiling code with GCC 8.1 / binutils 2.30 (built locally on GNU/Linux amd64) which previously compiled and worked OK with GCC 6.2 and 7.3.

I received a very cryptic error that had me running around reworking class implementations for quite a while before I realized the problem: I had an incomplete type.  I don't know if there's anything G++ could do better here, but FYI I had this code:

class Bar
{
public:
    struct Less
    {
        bool operator()(const Bar& lhs, const Bar& rhs) const;
        bool operator()(const Bar* lhs, const Bar* rhs) const;
    };
};

class Biz;

#include <set>

class Foo
{
    std::set<const Biz*, Bar::Less> _map;
};

It's not immediately clear that the incomplete Biz class is a problem, especially in my code which is significantly more complex and crosses multiple header files, and G++ doesn't give a very helpful (to me) error:

$ g++ -o set.o -c set.cpp
In file included from x86_64-generic-linux-gnu/include/c++/8.1.0/set:60,
                 from set.cpp:13:
x86_64-generic-linux-gnu/include/c++/8.1.0/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<const Biz*, const Biz*, std::_Identity<const Biz*>, Bar::Less, std::allocator<const Biz*> >':
x86_64-generic-linux-gnu/include/c++/8.1.0/bits/stl_set.h:133:17:   required from 'class std::set<const Biz*, Bar::Less>'
set.cpp:17:37:   required from here
x86_64-generic-linux-gnu/include/c++/8.1.0/bits/stl_tree.h:452:21: error: static assertion failed: comparison object must be invocable with two arguments of key type
       static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If I had included the complete type for class Biz, the compiler would have seen that Biz is a subclass of Bar and it would have been fine; adding in the header file fixed my problem:

class Bar
{
public:
    struct Less
    {
        bool operator()(const Bar& lhs, const Bar& rhs) const;
        bool operator()(const Bar* lhs, const Bar* rhs) const;
    };
};

class Biz : public Bar
{}

#include <set>

class Foo
{
    std::set<const Biz*, Bar::Less> _map;
};
Comment 1 Jonathan Wakely 2018-05-29 11:51:14 UTC
There's nothing that can be done here. The error comes from the library (not the compiler) and there's no way the compiler can possibly say "the static assertion would have passed if the __is_invocable trait had been true, which might have happened if the type was complete so that a conversion sequence from const Biz* to const Bar* might be possible".

The is_invocable trait asks if that function object can be called with those arguments, and when Biz is incomplete the answer is no.

I think sadly I have to remove that static_assertion, or just make it happen later when the comparison function is used (by which point either the call works, or you get an error anyway and the static assertion doesn't add any value).
Comment 2 Hedayat Vatankhah 2019-03-19 15:17:26 UTC
IMHO, it is very unfortunate that we need to provide the full definition for this to work. It has forced me to include a header file just for this error to go away, which is not desirable. I guess it doesn't compile a completely valid C++ code (at least, I've not found that this is a std::set requirement). 

Probably, __is_invocable<> should not signal an error if it finds an incomplete type, or it should be replaced with a construct that doesn't.

So, if the code using an incomplete type pointer for std::set is a valid C++ code, this is a sever (non-standard conforming) bug in library.
Comment 3 Jonathan Wakely 2019-03-19 16:13:36 UTC
(In reply to Hedayat Vatankhah from comment #2)
> Probably, __is_invocable<> should not signal an error if it finds an
> incomplete type, or it should be replaced with a construct that doesn't.

It's not possible for a type trait to give a different answer depending whether a type is complete or not. That would violate the One-Definition Rule.

I'd forgotten about this issue because the component wasn't libstdc++. I will remove the is_invocable checks.
Comment 4 Paul Smith 2019-03-19 16:55:34 UTC
Oops sorry: I guess I'm not familiar enough with the vagaries of the bug trackers :).  Thanks Jonathan!
Comment 5 Jonathan Wakely 2019-03-19 17:01:26 UTC
No problem, it's not the reporter's responsibility to categorise it correctly.
Comment 6 Jonathan Wakely 2019-03-26 15:29:20 UTC
Author: redi
Date: Tue Mar 26 15:28:48 2019
New Revision: 269949

URL: https://gcc.gnu.org/viewcvs?rev=269949&root=gcc&view=rev
Log:
PR libstdc++/85965 delay static assertions until types are complete

The static assertions added for PR libstdc++/48101 were at class scope
and so were evaluated too eagerly, when it might not be possible to
determine whether the function objects are invocable with the key types.
The problematic cases are where the key type is not known to be
convertible to the argument type(s) of the function object until later,
after a type has been completed. Specifically, if the key type is a
pointer to a derived class and the function object's argument type is a
pointer to a base class, then the derived-to-base conversion is only
valid once the derived type is complete.

By moving the static assertions to the destructor they will only be
evaluated when the destructor is instantiated, at which point whether
the key type can be passed to the function object should be knowable.
The ideal place to do the checks would be only when the function objects
are actually invoked, but that would mean adding the checks in numerous
places, so the destructor is used instead.

The tests need to be adjusted because the "required from here" line is
now the location of the destructor, not the point of instantiation in
the test file. For the map and multimap tests which check two
specializations, the dg-error matching the assertion text matches both
cases. Also check the diagnostic output for the template arguments, to
ensure both specializations trigger the assertion.

	PR libstdc++/85965
	* include/bits/hashtable.h (_Hashtable): Move static assertions to
	destructor so they are not evaluated until the _Key type is complete.
	* include/bits/stl_tree.h (_Rb_tree): Likewise.
	* testsuite/23_containers/set/85965.cc: New test.
	* testsuite/23_containers/unordered_set/85965.cc: New test.
	* testsuite/23_containers/map/48101_neg.cc: Replace "here" errors
	with regexp matching the corresponding _Rb_tree specialization.
	* testsuite/23_containers/multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/multiset/48101_neg.cc: Remove "here" error.
	* testsuite/23_containers/set/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.

Added:
    trunk/libstdc++-v3/testsuite/23_containers/set/85965.cc
      - copied, changed from r269947, trunk/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc
      - copied, changed from r269947, trunk/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/hashtable.h
    trunk/libstdc++-v3/include/bits/stl_tree.h
    trunk/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
Comment 7 Jonathan Wakely 2019-04-02 12:24:28 UTC
This is fixed on trunk now, but still needs to be backported to gcc-8-branch.
Comment 8 Jonathan Wakely 2019-05-07 15:46:36 UTC
Author: redi
Date: Tue May  7 15:46:05 2019
New Revision: 270960

URL: https://gcc.gnu.org/viewcvs?rev=270960&root=gcc&view=rev
Log:
PR libstdc++/85965 delay static assertions until types are complete

The static assertions added for PR libstdc++/48101 were at class scope
and so were evaluated too eagerly, when it might not be possible to
determine whether the function objects are invocable with the key types.
The problematic cases are where the key type is not known to be
convertible to the argument type(s) of the function object until later,
after a type has been completed. Specifically, if the key type is a
pointer to a derived class and the function object's argument type is a
pointer to a base class, then the derived-to-base conversion is only
valid once the derived type is complete.

By moving the static assertions to the destructor they will only be
evaluated when the destructor is instantiated, at which point whether
the key type can be passed to the function object should be knowable.
The ideal place to do the checks would be only when the function objects
are actually invoked, but that would mean adding the checks in numerous
places, so the destructor is used instead.

The tests need to be adjusted because the "required from here" line is
now the location of the destructor, not the point of instantiation in
the test file. For the map and multimap tests which check two
specializations, the dg-error matching the assertion text matches both
cases. Also check the diagnostic output for the template arguments, to
ensure both specializations trigger the assertion.

Backport from mainline
2019-03-26  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/85965
	* include/bits/hashtable.h (_Hashtable): Move static assertions to
	destructor so they are not evaluated until the _Key type is complete.
	* include/bits/stl_tree.h (_Rb_tree): Likewise.
	* testsuite/23_containers/set/85965.cc: New test.
	* testsuite/23_containers/unordered_set/85965.cc: New test.
	* testsuite/23_containers/map/48101_neg.cc: Replace "here" errors
	with regexp matching the corresponding _Rb_tree specialization.
	* testsuite/23_containers/multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/multiset/48101_neg.cc: Remove "here" error.
	* testsuite/23_containers/set/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.

Added:
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/set/85965.cc
      - copied, changed from r270959, branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc
      - copied, changed from r270959, branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
Modified:
    branches/gcc-8-branch/libstdc++-v3/ChangeLog
    branches/gcc-8-branch/libstdc++-v3/include/bits/hashtable.h
    branches/gcc-8-branch/libstdc++-v3/include/bits/stl_tree.h
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
Comment 9 Jonathan Wakely 2019-05-07 15:51:10 UTC
Fixed for 8.4 too.
Comment 10 Hedayat Vatankhah 2019-05-14 15:02:57 UTC
Isn't it expected to be fixed in Gcc 9.1.1? It seems to still affect GCC 9.1.1 (Fedora 30)
Comment 11 Jonathan Wakely 2019-05-14 15:17:25 UTC
The example reported here is fixed in 9.1.0, if you have a different example maybe there's a different problem.
Comment 12 Hedayat Vatankhah 2019-05-15 10:35:16 UTC
OK, I found the problem. Yes, the fix is included in 9.1.1. 
However, the fix assumes that the type must be complete when desctructor is called, but unfortunately, this is a wrong assumption. AFAIK, this is a completely valid C++ code, but cannot be compiled successfully:

foo.h:
-------------------------------
class Bar
{
public:
    struct Less
    {
        bool operator()(const Bar& lhs, const Bar& rhs) const;
        bool operator()(const Bar* lhs, const Bar* rhs) const;
    };
};

class Biz;

#include <set>

class Foo
{
public:
    void do_something();
    std::set<const Biz*, Bar::Less> _map;
};
-------------------------------
test.cpp:
-------------------------------
void tt()
{
        Foo f;
        f.do_something();
}

-------------------------------
foo.cpp:
-------------------------------

#include "foo.h"
#include "biz.h"

Foo::do_something()
{
    // do an insert...
}
Comment 13 Jonathan Wakely 2019-05-15 11:57:06 UTC
(In reply to Hedayat Vatankhah from comment #12)
> AFAIK, this is a completely valid C++ code,

I don't think that's actually clear.

The standard doesn't specify when the comparison object must be invocable, so I think it's conforming (but not very user friendly) to reject that code, and the original example in this bug report.
Comment 14 Jonathan Wakely 2019-05-15 16:00:23 UTC
A new patch to fix this was posted to:
https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00863.html
Comment 15 Hedayat Vatankhah 2019-05-15 20:59:21 UTC
Thanks!

Yep, I'm certainly not a C++ standard expert.
Comment 16 Jonathan Wakely 2019-05-17 14:14:03 UTC
Author: redi
Date: Fri May 17 14:13:32 2019
New Revision: 271323

URL: https://gcc.gnu.org/viewcvs?rev=271323&root=gcc&view=rev
Log:
PR libstdc++/85965 move is_invocable assertions again

This is another attempt to reduce how often the assertions are
evaluated, so that code which doesn't try to use the function objects
doesn't need them to be invocable.

For _Rb_tree we access the _M_key_compare object directly, so can't put
the assertions in an accessor function for it. However, every invocation
of _M_key_compare is accompanied by a use of _S_key, so the assertions
can be put in there.  For _Hashtable there are member functions that are
consistently used to obtain a hash code or test for equality, so the
assertions can go in those members.

	PR libstdc++/85965
	* include/bits/hashtable.h (_Hashtable::~_Hashtable()): Remove static
	assertions from the destructor.
	* include/bits/hashtable_policy.h (_Hash_code_base::_M_hash_code):
	Move static_assert for hash function to here.
	(_Hash_table_base::_M_equals): Move static_assert for equality
	predicate to here.
	* include/bits/stl_tree.h (_Rb_tree::_S_value(_Const_Link_type)):
	Remove.
	(_Rb_tree::_S_key(_Const_Link_type)): Move assertions here. Access
	the value directly instead of calling _S_value.
	(_Rb_tree::_S_value(_Const_Base_ptr)): Remove.
	(_Rb_tree::_S_key(_Const_Base_ptr)): Do downcast and forward to
	_S_key(_Const_Link_type).
	* testsuite/23_containers/set/85965.cc: Check construction,
	destruction, assignment and size() do not trigger the assertions.
	* testsuite/23_containers/unordered_set/85965.cc: Likewise.
	* testsuite/23_containers/map/48101_neg.cc: Call find and adjust
	expected errors.
	* testsuite/23_containers/multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/set/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/hashtable.h
    trunk/libstdc++-v3/include/bits/hashtable_policy.h
    trunk/libstdc++-v3/include/bits/stl_tree.h
    trunk/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/set/85965.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc
Comment 17 Jonathan Wakely 2019-05-24 16:09:59 UTC
Author: redi
Date: Fri May 24 16:09:28 2019
New Revision: 271607

URL: https://gcc.gnu.org/viewcvs?rev=271607&root=gcc&view=rev
Log:
PR libstdc++/85965 move is_invocable assertions again

This is another attempt to reduce how often the assertions are
evaluated, so that code which doesn't try to use the function objects
doesn't need them to be invocable.

For _Rb_tree we access the _M_key_compare object directly, so can't put
the assertions in an accessor function for it. However, every invocation
of _M_key_compare is accompanied by a use of _S_key, so the assertions
can be put in there.  For _Hashtable there are member functions that are
consistently used to obtain a hash code or test for equality, so the
assertions can go in those members.

Backport from mainline
2019-05-17  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/85965
	* include/bits/hashtable.h (_Hashtable::~_Hashtable()): Remove static
	assertions from the destructor.
	* include/bits/hashtable_policy.h (_Hash_code_base::_M_hash_code):
	Move static_assert for hash function to here.
	(_Hash_table_base::_M_equals): Move static_assert for equality
	predicate to here.
	* include/bits/stl_tree.h (_Rb_tree::_S_key(_Const_Link_type)): Move
	assertions here. Access the value directly instead of calling _S_value.
	(_Rb_tree::_S_key(_Const_Base_ptr)): Do downcast and forward to
	_S_key(_Const_Link_type).
	* testsuite/23_containers/set/85965.cc: Check construction,
	destruction, assignment and size() do not trigger the assertions.
	* testsuite/23_containers/unordered_set/85965.cc: Likewise.
	* testsuite/23_containers/map/48101_neg.cc: Call find and adjust
	expected errors.
	* testsuite/23_containers/multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/set/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.

Modified:
    branches/gcc-9-branch/libstdc++-v3/ChangeLog
    branches/gcc-9-branch/libstdc++-v3/include/bits/hashtable.h
    branches/gcc-9-branch/libstdc++-v3/include/bits/hashtable_policy.h
    branches/gcc-9-branch/libstdc++-v3/include/bits/stl_tree.h
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/set/85965.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
    branches/gcc-9-branch/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc
Comment 18 Jonathan Wakely 2019-08-30 13:10:13 UTC
Author: redi
Date: Fri Aug 30 13:09:42 2019
New Revision: 275166

URL: https://gcc.gnu.org/viewcvs?rev=275166&root=gcc&view=rev
Log:
PR libstdc++/85965 move is_invocable assertions again

This is another attempt to reduce how often the assertions are
evaluated, so that code which doesn't try to use the function objects
doesn't need them to be invocable.

For _Rb_tree we access the _M_key_compare object directly, so can't put
the assertions in an accessor function for it. However, every invocation
of _M_key_compare is accompanied by a use of _S_key, so the assertions
can be put in there.  For _Hashtable there are member functions that are
consistently used to obtain a hash code or test for equality, so the
assertions can go in those members.

Backport from mainline
2019-05-17  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/85965
	* include/bits/hashtable.h (_Hashtable::~_Hashtable()): Remove static
	assertions from the destructor.
	* include/bits/hashtable_policy.h (_Hash_code_base::_M_hash_code):
	Move static_assert for hash function to here.
	(_Hash_table_base::_M_equals): Move static_assert for equality
	predicate to here.
	* include/bits/stl_tree.h (_Rb_tree::_S_key(_Const_Link_type)): Move
	assertions here. Access the value directly instead of calling _S_value.
	(_Rb_tree::_S_key(_Const_Base_ptr)): Do downcast and forward to
	_S_key(_Const_Link_type).
	* testsuite/23_containers/set/85965.cc: Check construction,
	destruction, assignment and size() do not trigger the assertions.
	* testsuite/23_containers/unordered_set/85965.cc: Likewise.
	* testsuite/23_containers/map/48101_neg.cc: Call find and adjust
	expected errors.
	* testsuite/23_containers/multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/set/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
	* testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.

Modified:
    branches/gcc-8-branch/libstdc++-v3/ChangeLog
    branches/gcc-8-branch/libstdc++-v3/include/bits/hashtable.h
    branches/gcc-8-branch/libstdc++-v3/include/bits/hashtable_policy.h
    branches/gcc-8-branch/libstdc++-v3/include/bits/stl_tree.h
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/set/85965.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
    branches/gcc-8-branch/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc
Comment 19 Jonathan Wakely 2019-08-30 14:19:05 UTC
Fixed for 8.4