[Bug libstdc++/95606] [10/11 regression] conflicts with std::is_constructible

2020-06-10 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95606

--- Comment #3 from Jonathan Wakely  ---
And probably one or both of the basic_json and json_ref constructors should be
explicit, so that you can't implicitly convert them both to each other.

[Bug libstdc++/95606] [10/11 regression] conflicts with std::is_constructible

2020-06-10 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95606

Jonathan Wakely  changed:

   What|Removed |Added

 Resolution|--- |INVALID
 Status|UNCONFIRMED |RESOLVED

--- Comment #2 from Jonathan Wakely  ---
I think this is not a bug in GCC. A specialization of std::swap still depends
on the signature of the primary template, and that primary template requires
the argument types to be swappable. The is_swappable trait requires
move_constructible, and that requires complete types. Checking
is_move_constructible will perform overload resolution which considers
the basic_json(json_ref) constructor, which tries to see if json_ref can be
constructed from a basic_json rvalue, which checks the constraint on the
json_ref constructor, which depends on basic_json, which is incomplete at this
point.

The json code is incorrect and should be fixed.

The std::swap specialization is wrong and should be replaced by a normal
(non-template) overload in the same namespace as the json type:

void swap(json&, json&) noexcept;

The json_ref constructor should be constrained to avoid recursive
instantiations with incomplete types, e.g.

template
  using is_not = std::is_same>, U>;

class json_ref
{
  public:
template ::value>,
  typename = std::enable_if_t::value>,
  bool = std::is_constructible::value>
json_ref(T &&){}
};

[Bug libstdc++/95606] [10/11 regression] conflicts with std::is_constructible

2020-06-10 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95606

--- Comment #1 from Jonathan Wakely  ---
The testcase is:

#include 
#include 

template
class basic_json;

using json = basic_json;

class json_ref
{
  public:
template ::value>
json_ref(T &&){}
};

template
class basic_json
{
  public:
basic_json(json_ref) {}
};

namespace std {

template<>
void swap(json&, json&) noexcept {}

}

int main() {}


This fails when compiled with -std=gnu++17 or later.

Specializing std::swap like this is wrong (and in C++20 explicitly results in
undefined behaviour). Replacing it with a normal overload in the same namespace
as the type avoids the error.

Do you have an example that doesn't involve a bogus specialization in namespace
std?

[Bug libstdc++/95606] [10/11 regression] conflicts with std::is_constructible

2020-06-10 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95606

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|--- |10.2
   Keywords||rejects-valid