Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16?
-- >8 --
Here we ICE because S::S(int) lost its DECL_ARGUMENTS, and so the
skip_artificial_parms_for in FUNCTION_FIRST_USER_PARM in write_reflection
crashes on a null tree. We've thrown away the body of S::S(int) in
cgraph_node::release_body along with its DECL_ARGUMENTS:
if (!keep_arguments)
DECL_ARGUMENTS (decl) = NULL;
This happens in finalize_compilation_unit -> analyze_functions because
there are no cgraph_node::callers (so referred_to_p() is false I think),
and .force_output is false.
We then call mangle_decl from finalize_compilation_unit ->
dwarf2out_early_finish.
Instead of FUNCTION_FIRST_USER_PARM we can use DECL_PARM_INDEX, thus
avoiding the need to either keep the body around or at least set
keep_arguments.
PR c++/125498
gcc/cp/ChangeLog:
* mangle.cc (write_reflection): Use DECL_PARM_INDEX for
computing the parameter index.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/mangle7.C: New test.
* g++.dg/reflect/parameters_of9.C: New test.
---
gcc/cp/mangle.cc | 9 +--
gcc/testsuite/g++.dg/reflect/mangle7.C | 65 +++++++++++++++++++
gcc/testsuite/g++.dg/reflect/parameters_of9.C | 45 +++++++++++++
3 files changed, 112 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/reflect/mangle7.C
create mode 100644 gcc/testsuite/g++.dg/reflect/parameters_of9.C
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 982864ebf0c..a287cded8ae 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -4220,13 +4220,8 @@ write_reflection (tree refl)
else if (strcmp (prefix, "pa") == 0)
{
tree fn = DECL_CONTEXT (arg);
- tree args = FUNCTION_FIRST_USER_PARM (fn);
- int idx = 0;
- while (arg != args)
- {
- args = DECL_CHAIN (args);
- ++idx;
- }
+ /* DECL_PARM_INDEX is 1-based but here we want a 0-based index. */
+ const int idx = DECL_PARM_INDEX (arg) - 1;
write_compact_number (idx);
write_encoding (fn);
}
diff --git a/gcc/testsuite/g++.dg/reflect/mangle7.C
b/gcc/testsuite/g++.dg/reflect/mangle7.C
new file mode 100644
index 00000000000..f6d9e347204
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/mangle7.C
@@ -0,0 +1,65 @@
+// PR c++/125498
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+using namespace std::meta;
+
+template<info>
+void
+xyzzy ()
+{
+}
+
+struct S {
+ void fn1 (const S &)
+ {
+ xyzzy<parameters_of (^^S::fn1)[0]> ();
+ }
+ void fn2 (this S)
+ {
+ xyzzy<parameters_of (^^S::fn2)[0]> ();
+ }
+ static void fn3 (int)
+ {
+ xyzzy<parameters_of (^^S::fn3)[0]> ();
+ }
+};
+
+struct V : virtual S {
+ void fn1 (const V &)
+ {
+ xyzzy<parameters_of (^^V::fn1)[0]> ();
+ }
+ void fn2 (this V)
+ {
+ xyzzy<parameters_of (^^V::fn2)[0]> ();
+ }
+ static void fn3 (int)
+ {
+ xyzzy<parameters_of (^^V::fn3)[0]> ();
+ }
+};
+
+void
+g (int)
+{
+ xyzzy<parameters_of (^^g)[0]> ();
+ S s;
+ s.fn1 (s);
+ s.fn2 ();
+ S::fn3 (42);
+ V v;
+ v.fn1 (v);
+ v.fn2 ();
+ V::fn3 (42);
+}
+
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1S3fn1ERKS0_EEvv" } }
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_NH1S3fn2ES0_EEvv" } }
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1S3fn3EiEEvv" } }
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1V3fn1ERKS0_EEvv" } }
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_NH1V3fn2ES0_EEvv" } }
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_N1V3fn3EiEEvv" } }
+// { dg-final { scan-assembler "_Z5xyzzyILDmpa_1giEEvv" } }
diff --git a/gcc/testsuite/g++.dg/reflect/parameters_of9.C
b/gcc/testsuite/g++.dg/reflect/parameters_of9.C
new file mode 100644
index 00000000000..ef7059a111a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/parameters_of9.C
@@ -0,0 +1,45 @@
+// PR c++/125498
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection -g" }
+
+#include <meta>
+
+struct tag {};
+
+struct S {
+ S(int) {}
+};
+
+struct B { };
+struct A : virtual B { A(int); };
+
+template <auto Param> struct GetAnnotations {
+ static constexpr auto value = std::define_static_array(
+ std::meta::annotations_of_with_type(Param, ^^tag));
+};
+
+consteval bool test() {
+ template for (constexpr auto member :
+ std::define_static_array(std::meta::members_of(
+ ^^S, std::meta::access_context::unchecked()))) {
+ if constexpr (std::meta::is_constructor(member)) {
+ constexpr auto parameters =
+ std::define_static_array(std::meta::parameters_of(member));
+ constexpr auto annotations = GetAnnotations<parameters[0]>::value;
+ return annotations.empty();
+ }
+ }
+}
+
+consteval bool test2() {
+ template for (constexpr auto member :
+ std::define_static_array(std::meta::members_of(
+ ^^A, std::meta::access_context::unchecked()))) {
+ if constexpr (std::meta::is_constructor(member)) {
+ constexpr auto parameters =
+ std::define_static_array(std::meta::parameters_of(member));
+ constexpr auto annotations = GetAnnotations<parameters[0]>::value;
+ return annotations.empty();
+ }
+ }
+}
base-commit: de7756c90f3bebdf02492842ec355d7e18745e7b
--
2.54.0