[v13,01/26] c++: Implement __is_const built-in trait
Commit Message
This patch implements built-in trait for std::is_const.
gcc/cp/ChangeLog:
* cp-trait.def: Define __is_const.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONST.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/ext/has-builtin-1.C: Test existence of __is_const.
* g++.dg/ext/is_const.C: New test.
Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
---
gcc/cp/constraint.cc | 3 +++
gcc/cp/cp-trait.def | 1 +
gcc/cp/semantics.cc | 4 ++++
gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 +++
gcc/testsuite/g++.dg/ext/is_const.C | 20 ++++++++++++++++++++
5 files changed, 31 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C
Comments
On Wed, Feb 28, 2024 at 11:32 AM Ken Matsui <kmatsui@gcc.gnu.org> wrote:
>
> Hi,
>
> This patch series implements __is_const, __is_volatile, __is_pointer,
> and __is_unbounded_array built-in traits, which were isolated from my
> previous patch series "Optimize type traits compilation performance"
> because they contained performance regression. I confirmed that this
> patch series does not cause any performance regression. The main reason
> of the performance regression were the exhaustiveness of the benchmarks
> and the instability of the benchmark results. Also, this patch series
> includes built-ins for add_pointer, remove_extent, remove_all_extents,
> add_lvalue_reference, add_rvalue_reference, decay, rank, is_invocable,
> and is_nothrow_invocable. Here are the benchmark results:
Ping. Ok for trunk or maybe for 15?
>
> is_const: https://github.com/ken-matsui/gcc-bench/blob/main/is_const.md#sat-dec-23-090605-am-pst-2023
> time: -4.36603%, peak memory: -0.300891%, total memory: -0.247934%
>
> is_const_v: https://github.com/ken-matsui/gcc-bench/blob/main/is_const_v.md#sat-jun-24-044815-am-pdt-2023
> time: -2.86467%, peak memory: -1.0654%, total memory: -1.62369%
>
> is_volatile: https://github.com/ken-matsui/gcc-bench/blob/main/is_volatile.md#sun-oct-22-091644-pm-pdt-2023
> time: -5.25164%, peak memory: -0.337971%, total memory: -0.247934%
>
> is_volatile_v: https://github.com/ken-matsui/gcc-bench/blob/main/is_volatile_v.md#sat-dec-23-091518-am-pst-2023
> time: -4.06816%, peak memory: -0.609298%, total memory: -0.659134%
>
> is_pointer: https://github.com/ken-matsui/gcc-bench/blob/main/is_pointer.md#sat-dec-23-124903-pm-pst-2023
> time: -2.47124%, peak memory: -2.98207%, total memory: -4.0811%
>
> is_pointer_v: https://github.com/ken-matsui/gcc-bench/blob/main/is_pointer_v.md#sun-oct-22-122257-am-pdt-2023
> time: -4.71336%, peak memory: -2.25026%, total memory: -3.125%
>
> is_unbounded_array: https://github.com/ken-matsui/gcc-bench/blob/main/is_unbounded_array.md#sun-oct-22-091644-pm-pdt-2023
> time: -6.33287%, peak memory: -0.602494%, total memory: -1.56035%
>
> is_unbounded_array_v: https://github.com/ken-matsui/gcc-bench/blob/main/is_unbounded_array_v.md#sat-dec-23-010046-pm-pst-2023
> time: -1.50025%, peak memory: -1.07386%, total memory: -2.32394%
>
> add_pointer_t: https://github.com/ken-matsui/gcc-bench/blob/main/add_pointer_t.md#wed-feb-28-060044-am-pst-2024
> time: -21.6673%, peak memory: -14.6666%, total memory: -17.4716%
>
> remove_extent_t: https://github.com/ken-matsui/gcc-bench/blob/main/remove_extent_t.md#wed-feb-28-063021-am-pst-2024
> time: -14.4089%, peak memory: -2.71836%, total memory: -9.87013%
>
> remove_all_extents_t: https://github.com/ken-matsui/gcc-bench/blob/main/remove_all_extents_t.md#wed-feb-28-064716-am-pst-2024
> time: -28.8941%, peak memory: -16.6981%, total memory: -23.6088%
>
> add_lvalue_reference_t: https://github.com/ken-matsui/gcc-bench/blob/main/add_lvalue_reference_t.md#wed-feb-28-070023-am-pst-2024
> time: -33.8827%, peak memory: -24.9292%, total memory: -25.3043%
>
> add_rvalue_reference_t: https://github.com/ken-matsui/gcc-bench/blob/main/add_rvalue_reference_t.md#wed-feb-28-070701-am-pst-2024
> time: -23.9186%, peak memory: -17.1311%, total memory: -19.5891%
>
> decay_t: https://github.com/ken-matsui/gcc-bench/blob/main/decay_t.md#wed-feb-28-072330-am-pst-2024
> time: -42.4076%, peak memory: -29.2077%, total memory: -33.0914%
>
> rank: https://github.com/ken-matsui/gcc-bench/blob/main/rank.md#wed-feb-28-074917-am-pst-2024
> time: -33.7312%, peak memory: -27.5885%, total memory: -34.5736%
>
> rank_v: https://github.com/ken-matsui/gcc-bench/blob/main/rank_v.md#wed-feb-28-073632-am-pst-2024
> time: -40.7174%, peak memory: -16.4653%, total memory: -23.0131%
>
> is_invocable_v: https://github.com/ken-matsui/gcc-bench/blob/main/is_invocable.md#wed-feb-28-111001-am-pst-2024
> time: -58.8307%, peak memory: -59.4966%, total memory: -59.8871%
> (This benchmark is not exhaustive as my laptop crashed with larger benchmarks)
>
> is_nothrow_invocable_v: https://github.com/ken-matsui/gcc-bench/blob/main/is_nothrow_invocable.md#wed-feb-28-112414-am-pst-2024
> time: -70.4102%, peak memory: -62.5516%, total memory: -65.5853%
> (This benchmark is not exhaustive as my laptop crashed with larger benchmarks)
>
> Sincerely,
> Ken Matsui
>
> Ken Matsui (26):
> c++: Implement __is_const built-in trait
> libstdc++: Optimize std::is_const compilation performance
> c++: Implement __is_volatile built-in trait
> libstdc++: Optimize std::is_volatile compilation performance
> c++: Implement __is_pointer built-in trait
> libstdc++: Optimize std::is_pointer compilation performance
> c++: Implement __is_unbounded_array built-in trait
> libstdc++: Optimize std::is_unbounded_array compilation performance
> c++: Implement __add_pointer built-in trait
> libstdc++: Optimize std::add_pointer compilation performance
> c++: Implement __remove_extent built-in trait
> libstdc++: Optimize std::remove_extent compilation performance
> c++: Implement __remove_all_extents built-in trait
> libstdc++: Optimize std::remove_all_extents compilation performance
> c++: Implement __add_lvalue_reference built-in trait
> libstdc++: Optimize std::add_lvalue_reference compilation performance
> c++: Implement __add_rvalue_reference built-in trait
> libstdc++: Optimize std::add_rvalue_reference compilation performance
> c++: Implement __decay built-in trait
> libstdc++: Optimize std::decay compilation performance
> c++: Implement __rank built-in trait
> libstdc++: Optimize std::rank compilation performance
> c++: Implement __is_invocable built-in trait
> libstdc++: Optimize std::is_invocable compilation performance
> c++: Implement __is_nothrow_invocable built-in trait
> libstdc++: Optimize std::is_nothrow_invocable compilation performance
>
> gcc/cp/constraint.cc | 27 ++
> gcc/cp/cp-trait.def | 13 +
> gcc/cp/cp-tree.h | 2 +
> gcc/cp/method.cc | 132 +++++++
> gcc/cp/semantics.cc | 92 ++++-
> .../g++.dg/ext/add_lvalue_reference.C | 21 ++
> gcc/testsuite/g++.dg/ext/add_pointer.C | 39 ++
> .../g++.dg/ext/add_rvalue_reference.C | 20 +
> gcc/testsuite/g++.dg/ext/decay.C | 22 ++
> gcc/testsuite/g++.dg/ext/has-builtin-1.C | 39 ++
> gcc/testsuite/g++.dg/ext/is_const.C | 20 +
> gcc/testsuite/g++.dg/ext/is_invocable1.C | 349 ++++++++++++++++++
> gcc/testsuite/g++.dg/ext/is_invocable2.C | 139 +++++++
> gcc/testsuite/g++.dg/ext/is_invocable3.C | 51 +++
> gcc/testsuite/g++.dg/ext/is_invocable4.C | 33 ++
> .../g++.dg/ext/is_nothrow_invocable.C | 62 ++++
> gcc/testsuite/g++.dg/ext/is_pointer.C | 51 +++
> gcc/testsuite/g++.dg/ext/is_unbounded_array.C | 37 ++
> gcc/testsuite/g++.dg/ext/is_volatile.C | 20 +
> gcc/testsuite/g++.dg/ext/rank.C | 24 ++
> gcc/testsuite/g++.dg/ext/remove_all_extents.C | 16 +
> gcc/testsuite/g++.dg/ext/remove_extent.C | 16 +
> libstdc++-v3/include/bits/cpp_type_traits.h | 31 +-
> libstdc++-v3/include/std/type_traits | 142 ++++++-
> .../is_invocable/incomplete_args_neg.cc | 1 +
> .../20_util/is_invocable/incomplete_neg.cc | 1 +
> .../incomplete_args_neg.cc | 1 +
> .../is_nothrow_invocable/incomplete_neg.cc | 1 +
> 28 files changed, 1389 insertions(+), 13 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/ext/add_lvalue_reference.C
> create mode 100644 gcc/testsuite/g++.dg/ext/add_pointer.C
> create mode 100644 gcc/testsuite/g++.dg/ext/add_rvalue_reference.C
> create mode 100644 gcc/testsuite/g++.dg/ext/decay.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_const.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable1.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable2.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable3.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable4.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_nothrow_invocable.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_pointer.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_unbounded_array.C
> create mode 100644 gcc/testsuite/g++.dg/ext/is_volatile.C
> create mode 100644 gcc/testsuite/g++.dg/ext/rank.C
> create mode 100644 gcc/testsuite/g++.dg/ext/remove_all_extents.C
> create mode 100644 gcc/testsuite/g++.dg/ext/remove_extent.C
>
> --
> 2.44.0
>
@@ -3767,6 +3767,9 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_IS_CLASS:
inform (loc, " %qT is not a class", t1);
break;
+ case CPTK_IS_CONST:
+ inform (loc, " %qT is not a const type", t1);
+ break;
case CPTK_IS_CONSTRUCTIBLE:
if (!t2)
inform (loc, " %qT is not default constructible", t1);
@@ -64,6 +64,7 @@ DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
+DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1)
@@ -12446,6 +12446,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_CLASS:
return NON_UNION_CLASS_TYPE_P (type1);
+ case CPTK_IS_CONST:
+ return CP_TYPE_CONST_P (type1);
+
case CPTK_IS_CONSTRUCTIBLE:
return is_xible (INIT_EXPR, type1, type2);
@@ -12688,6 +12691,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_ARRAY:
case CPTK_IS_BOUNDED_ARRAY:
case CPTK_IS_CLASS:
+ case CPTK_IS_CONST:
case CPTK_IS_ENUM:
case CPTK_IS_FUNCTION:
case CPTK_IS_MEMBER_FUNCTION_POINTER:
@@ -71,6 +71,9 @@
#if !__has_builtin (__is_class)
# error "__has_builtin (__is_class) failed"
#endif
+#if !__has_builtin (__is_const)
+# error "__has_builtin (__is_const) failed"
+#endif
#if !__has_builtin (__is_constructible)
# error "__has_builtin (__is_constructible) failed"
#endif
new file mode 100644
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+class ClassType { };
+using cClassType = const ClassType;
+using vClassType = volatile ClassType;
+using cvClassType = const volatile ClassType;
+
+// Positive tests.
+SA(__is_const(const int));
+SA(__is_const(const volatile int));
+SA(__is_const(cClassType));
+SA(__is_const(cvClassType));
+
+// Negative tests.
+SA(!__is_const(int));
+SA(!__is_const(volatile int));
+SA(!__is_const(ClassType));
+SA(!__is_const(vClassType));