]> gcc.gnu.org Git - gcc.git/commit
c++: Implement __is_{nothrow_,}convertible [PR106784]
authorMarek Polacek <polacek@redhat.com>
Tue, 20 Sep 2022 19:48:52 +0000 (15:48 -0400)
committerMarek Polacek <polacek@redhat.com>
Fri, 23 Sep 2022 16:12:41 +0000 (12:12 -0400)
commit8a7bcf95a82c3dd68bd4bcfbd8432eb970575bc2
tree391e7f2aef62a839154be40fd95c7a3ccf3f3c10
parent7d4df630c6cfb1909288a2796ec2f8b9ec4e8486
c++: Implement __is_{nothrow_,}convertible [PR106784]

To improve compile times, the C++ library could use compiler built-ins
rather than implementing std::is_convertible (and _nothrow) as class
templates.  This patch adds the built-ins.  We already have
__is_constructible and __is_assignable, and the nothrow forms of those.

Microsoft (and clang, for compatibility) also provide an alias called
__is_convertible_to.  I did not add it, but it would be trivial to do
so.

I noticed that our __is_assignable doesn't implement the "Access checks
are performed as if from a context unrelated to either type" requirement,
therefore std::is_assignable / __is_assignable give two different results
here:

  class S {
    operator int();
    friend void g(); // #1
  };

  void
  g ()
  {
    // #1 doesn't matter
    static_assert(std::is_assignable<int&, S>::value, "");
    static_assert(__is_assignable(int&, S), "");
  }

This is not a problem if __is_assignable is not meant to be used by
the users.

This patch doesn't make libstdc++ use the new built-ins, but I had to
rename a class otherwise its name would clash with the new built-in.

PR c++/106784

gcc/c-family/ChangeLog:

* c-common.cc (c_common_reswords): Add __is_convertible and
__is_nothrow_convertible.
* c-common.h (enum rid): Add RID_IS_CONVERTIBLE and
RID_IS_NOTHROW_CONVERTIBLE.

gcc/cp/ChangeLog:

* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONVERTIBLE
and CPTK_IS_NOTHROW_CONVERTIBLE.
* cp-objcp-common.cc (names_builtin_p): Handle RID_IS_CONVERTIBLE
RID_IS_NOTHROW_CONVERTIBLE.
* cp-tree.h (enum cp_trait_kind): Add CPTK_IS_CONVERTIBLE and
CPTK_IS_NOTHROW_CONVERTIBLE.
(is_convertible): Declare.
(is_nothrow_convertible): Likewise.
* cxx-pretty-print.cc (pp_cxx_trait_expression): Handle
CPTK_IS_CONVERTIBLE and CPTK_IS_NOTHROW_CONVERTIBLE.
* method.cc (is_convertible): New.
(is_nothrow_convertible): Likewise.
* parser.cc (cp_parser_primary_expression): Handle RID_IS_CONVERTIBLE
and RID_IS_NOTHROW_CONVERTIBLE.
(cp_parser_trait_expr): Likewise.
* semantics.cc (trait_expr_value): Handle CPTK_IS_CONVERTIBLE and
CPTK_IS_NOTHROW_CONVERTIBLE.
(finish_trait_expr): Likewise.

libstdc++-v3/ChangeLog:

* include/std/type_traits: Rename __is_nothrow_convertible to
__is_nothrow_convertible_lib.
* testsuite/20_util/is_nothrow_convertible/value_ext.cc: Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/ext/has-builtin-1.C: Enhance to test __is_convertible and
__is_nothrow_convertible.
* g++.dg/ext/is_convertible1.C: New test.
* g++.dg/ext/is_convertible2.C: New test.
* g++.dg/ext/is_nothrow_convertible1.C: New test.
* g++.dg/ext/is_nothrow_convertible2.C: New test.
16 files changed:
gcc/c-family/c-common.cc
gcc/c-family/c-common.h
gcc/cp/constraint.cc
gcc/cp/cp-objcp-common.cc
gcc/cp/cp-tree.h
gcc/cp/cxx-pretty-print.cc
gcc/cp/method.cc
gcc/cp/parser.cc
gcc/cp/semantics.cc
gcc/testsuite/g++.dg/ext/has-builtin-1.C
gcc/testsuite/g++.dg/ext/is_convertible1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/is_convertible2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/is_nothrow_convertible1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/is_nothrow_convertible2.C [new file with mode: 0644]
libstdc++-v3/include/std/type_traits
libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value_ext.cc
This page took 0.065664 seconds and 5 git commands to generate.