libstdc++: Allow for function parameters in annotations_of[_with_type] [P3795R2]
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
This patch adds function parameters as an allowed reflection info that can
be passed to eval_annotations_of, and therefore the annotations_of and
annotations_of_with_type metafunctions, following the update from P3795R2.
The error message when an invalid reflection info has been passed in has
also been updated to reflect this change.
Tested and bootstrapped on x86_64-pc-linux-gnu.
gcc/
* cp/reflect.cc (eval_annotations_of): Allow function parameters and update
error message
accordingly
gcc/testsuite/
* g++.dg/reflect/annotations18.C: New test
* g++.dg/reflect/annotations19.C: Likewise
* g++.dg/reflect/annotations20.C: Likewise
Comments
On 4/4/26 5:38 PM, Septicake wrote:
> This patch adds function parameters as an allowed reflection info that
> can be passed to eval_annotations_of, and therefore the annotations_of
> and annotations_of_with_type metafunctions, following the update from
> P3795R2. The error message when an invalid reflection info has been
> passed in has also been updated to reflect this change.
Thanks for the contribution!
There's already a patch in review for this, that should be committed soon:
https://inbox.sourceware.org/gcc-patches/acUfPDbhcQHP9ywS@tucnak/
Jason
> There's already a patch in review for this, that should be committed soon:
>
> https://inbox.sourceware.org/gcc-patches/acUfPDbhcQHP9ywS@tucnak/
Ah, fair enough, it seems to handle it better anyway. Thanks for
pointing it out to me!
From 8894d4bbca547afe170a3faba03fbfdb2da23bed Mon Sep 17 00:00:00 2001
From: Septicake <septicake056@gmail.com>
Date: Sat, 4 Apr 2026 15:46:40 -0400
Subject: [PATCH] libstdc++: Allow for function parameters in
annotations_of[_with_type] [P3795R2]
Signed-off-by: Septicake <septicake056@gmail.com>
---
gcc/cp/reflect.cc | 8 +++++---
gcc/testsuite/g++.dg/reflect/annotations18.C | 14 ++++++++++++++
gcc/testsuite/g++.dg/reflect/annotations19.C | 20 ++++++++++++++++++++
gcc/testsuite/g++.dg/reflect/annotations20.C | 19 +++++++++++++++++++
4 files changed, 58 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/reflect/annotations18.C
create mode 100644 gcc/testsuite/g++.dg/reflect/annotations19.C
create mode 100644 gcc/testsuite/g++.dg/reflect/annotations20.C
@@ -3818,15 +3818,17 @@ eval_annotations_of (location_t loc, const constexpr_ctx *ctx, tree r,
|| eval_is_type_alias (r) == boolean_true_node
|| eval_is_variable (r, kind) == boolean_true_node
|| eval_is_function (r) == boolean_true_node
+ || eval_is_function_parameter (r, kind) == boolean_true_node
|| eval_is_namespace (r) == boolean_true_node
|| eval_is_enumerator (r) == boolean_true_node
|| eval_is_base (r, kind) == boolean_true_node
|| eval_is_nonstatic_data_member (r) == boolean_true_node))
return throw_exception (loc, ctx,
"reflection does not represent a type,"
- " type alias, variable, function, namespace,"
- " enumerator, direct base class relationship,"
- " or non-static data member",
+ " type alias, variable, function, function"
+ " parameter, namespace, enumerator, direct"
+ " base class relationship, or non-static"
+ " data member.",
fun, non_constant_p, jump_target);
if (type)
new file mode 100644
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+// Test annotations_of on function parameter reflections
+
+#include <meta>
+
+using namespace std::meta;
+
+void foo([[=2]] int);
+
+void foo([[=1]] int) {}
+
+static_assert (define_static_array(annotations_of(parameters_of(^^foo)[0])).size() == 2);
+static_assert ([: constant_of(annotations_of(parameters_of(^^foo)[0])[0]) :] == 2);
new file mode 100644
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+// Test annotations_of_with_type works as expected
+
+#include <meta>
+#include <ranges>
+#include <vector>
+
+using namespace std::meta;
+
+void foo([[=1, =2.0f, =2.3f]] int) {
+ constexpr auto a_p = define_static_array(annotations_of_with_type(parameters_of(^^foo)[0], ^^float));
+
+ static_assert(a_p.size() == 2);
+ static_assert((annotations_of_with_type(parameters_of(^^foo)[0], ^^float)
+ | std::views::transform(constant_of)
+ | std::ranges::to<std::vector>())
+ == std::vector { reflect_constant(2.0f),
+ reflect_constant(2.3f) });
+}
new file mode 100644
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+// Test that annotations match between
+// variable and parameter reflections
+
+#include <meta>
+
+using namespace std::meta;
+
+void foo([[=2]] int);
+
+void foo([[=1]] int i) {
+ constexpr info p_r = parameters_of(^^foo)[0];
+ constexpr info i_r = ^^i;
+
+ static_assert(define_static_array(annotations_of(p_r)).size() == 2);
+ static_assert(define_static_array(annotations_of(i_r)).size() == 2);
+ static_assert(annotations_of(p_r) == annotations_of(i_r));
+}
--
2.43.0