]> gcc.gnu.org Git - gcc.git/commit
c++: wrong std::is_convertible with cv-qual fn [PR109680]
authorMarek Polacek <polacek@redhat.com>
Tue, 2 May 2023 21:36:00 +0000 (17:36 -0400)
committerMarek Polacek <polacek@redhat.com>
Wed, 10 May 2023 22:24:38 +0000 (18:24 -0400)
commit4c2ffb02fd4104d77c5d907662f04434dc4c3fe8
tree8e0fdae498929f0b836a2ba5e80fbf2b60ccb78e
parent475904f710ccb99653d1f5c1cf426eaa3aa1626c
c++: wrong std::is_convertible with cv-qual fn [PR109680]

This PR points out that std::is_convertible has given the wrong answer
in

  static_assert (!std::is_convertible_v <int () const, int (*) ()>, "");

since r13-2822 implemented __is_{,nothrow_}convertible.

std::is_convertible uses the imaginary

  To test() { return std::declval<From>(); }

to do its job.  Here, From is 'int () const'.  std::declval is defined as:

  template<class T>
  typename std::add_rvalue_reference<T>::type declval() noexcept;

std::add_rvalue_reference is defined as "If T is a function type that
has no cv- or ref- qualifier or an object type, provides a member typedef
type which is T&&, otherwise type is T."

In our case, T is cv-qualified, so the result is T, so we end up with

  int () const declval() noexcept;

which is invalid.  In other words, this is pretty much like:

  using T = int () const;
  T fn1(); // bad, fn returning a fn
  T& fn2(); // bad, cannot declare reference to qualified function type
  T* fn3(); // bad, cannot declare pointer to qualified function type

  using U = int ();
  U fn4(); // bad, fn returning a fn
  U& fn5(); // OK
  U* fn6(); // OK

I think is_convertible_helper needs to simulate std::declval better.
To that end, I'm introducing build_trait_object, to be used where
a declval is needed.

PR c++/109680

gcc/cp/ChangeLog:

* method.cc (build_trait_object): New.
(assignable_expr): Use it.
(ref_xes_from_temporary): Likewise.
(is_convertible_helper): Likewise.  Check FUNC_OR_METHOD_TYPE_P.

gcc/testsuite/ChangeLog:

* g++.dg/ext/is_convertible6.C: New test.
gcc/cp/method.cc
gcc/testsuite/g++.dg/ext/is_convertible6.C [new file with mode: 0644]
This page took 0.066137 seconds and 6 git commands to generate.