This patch implements built-in trait for std::decay. gcc/cp/ChangeLog:
* cp-trait.def: Define __decay. * semantics.cc (finish_trait_type): Handle CPTK_DECAY. gcc/testsuite/ChangeLog: * g++.dg/ext/has-builtin-1.C: Test existence of __decay. * g++.dg/ext/decay.C: New test. Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org> --- gcc/cp/cp-trait.def | 1 + gcc/cp/semantics.cc | 12 ++++++++ gcc/testsuite/g++.dg/ext/decay.C | 39 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 ++ 4 files changed, 55 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/decay.C diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 9e8f9eb38b8..11270f3ae6b 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -51,6 +51,7 @@ DEFTRAIT_TYPE (ADD_LVALUE_REFERENCE, "__add_lvalue_reference", 1) DEFTRAIT_TYPE (ADD_POINTER, "__add_pointer", 1) DEFTRAIT_TYPE (ADD_RVALUE_REFERENCE, "__add_rvalue_reference", 1) +DEFTRAIT_TYPE (DECAY, "__decay", 1) DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1) DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1) DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index f437e272ea6..256e7ef8166 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -12785,6 +12785,18 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2, return type1; return cp_build_reference_type (type1, /*rval=*/true); + case CPTK_DECAY: + if (TYPE_REF_P (type1)) + type1 = TREE_TYPE (type1); + + if (TREE_CODE (type1) == ARRAY_TYPE) + return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2, + complain); + else if (TREE_CODE (type1) == FUNCTION_TYPE) + return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain); + else + return cv_unqualified (type1); + case CPTK_REMOVE_ALL_EXTENTS: return strip_array_types (type1); diff --git a/gcc/testsuite/g++.dg/ext/decay.C b/gcc/testsuite/g++.dg/ext/decay.C new file mode 100644 index 00000000000..cf224b7452c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/decay.C @@ -0,0 +1,39 @@ +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +// class ClassType { }; + +// Positive tests. +using test1_type = __decay(bool); +SA(__is_same(test1_type, bool)); + +// NB: DR 705. +using test2_type = __decay(const int); +SA(__is_same(test2_type, int)); + +using test3_type = __decay(int[4]); +SA(__is_same(test3_type, __remove_extent(int[4])*)); + +using fn_type = void (); +using test4_type = __decay(fn_type); +SA(__is_same(test4_type, __add_pointer(fn_type))); + +using cfn_type = void () const; +using test5_type = __decay(cfn_type); +SA(__is_same(test5_type, cfn_type)); + +// SA(__is_same(__add_rvalue_reference(int), int&&)); +// SA(__is_same(__add_rvalue_reference(int&&), int&&)); +// SA(__is_same(__add_rvalue_reference(int&), int&)); +// SA(__is_same(__add_rvalue_reference(const int), const int&&)); +// SA(__is_same(__add_rvalue_reference(int*), int*&&)); +// SA(__is_same(__add_rvalue_reference(ClassType&&), ClassType&&)); +// SA(__is_same(__add_rvalue_reference(ClassType), ClassType&&)); +// SA(__is_same(__add_rvalue_reference(int(int)), int(&&)(int))); +// SA(__is_same(__add_rvalue_reference(void), void)); +// SA(__is_same(__add_rvalue_reference(const void), const void)); +// SA(__is_same(__add_rvalue_reference(bool(int) const), bool(int) const)); +// SA(__is_same(__add_rvalue_reference(bool(int) &), bool(int) &)); +// SA(__is_same(__add_rvalue_reference(bool(int) const &&), bool(int) const &&)); +// SA(__is_same(__add_rvalue_reference(bool(int)), bool(&&)(int))); diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C index 9d7e59b47fb..5b590db1cf6 100644 --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C @@ -11,6 +11,9 @@ #if !__has_builtin (__add_rvalue_reference) # error "__has_builtin (__add_rvalue_reference) failed" #endif +#if !__has_builtin (__decay) +# error "__has_builtin (__decay) failed" +#endif #if !__has_builtin (__builtin_addressof) # error "__has_builtin (__builtin_addressof) failed" #endif -- 2.43.0