Hi!

https://eel.is/c++draft/meta.reflection#annotation-4
testcase also contains
[[=1]] int x, y;
static_assert(annotations_of(^^x)[0] == annotations_of(^^y)[0]);
so in case of an annotation shared by multiple declarations we need
to compare the TREE_VALUE of the attributes (which is shared in that
case) rather than the TREE_LIST with that TREE_VALUE and TREE_PURPOSE
being "internal ":"annotation ".
For mangling we already handle it right:
  if (eval_is_annotation (h, kind) == boolean_true_node)
    {
      strcpy (prefix, "an");
      if (TREE_PURPOSE (TREE_VALUE (h)) == NULL_TREE)
        TREE_PURPOSE (TREE_VALUE (h))
          = build_int_cst (integer_type_node, annotation_idx++);
      return TREE_PURPOSE (TREE_VALUE (h));
    }
so the annotation index is stored on TREE_PURPOSE of the TREE_VALUE,
so in shared annotation like the above it will have the same index
in both cases.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

When I was adding further tests for this, I've noticed that we don't
handle correctly
[[=1]] int x [[=2]], y [[=3]];
because the attributes list which is shared is clearly added as a shared
tail of the other attributes.  For now this is commented out in the
test, will try to deal with it somehow incrementally.

2026-03-10  Jakub Jelinek  <[email protected]>

        PR c++/124399
        * reflect.cc (compare_reflections): For REFLECT_ANNOTATION, compare
        TREE_VALUE of lhs and rhs instead of lhs and rhs.

        * g++.dg/reflect/annotations12.C: Add further tests.

--- gcc/cp/reflect.cc.jj        2026-03-09 11:04:26.056073667 +0100
+++ gcc/cp/reflect.cc   2026-03-09 11:41:58.060768044 +0100
@@ -8334,7 +8334,7 @@ compare_reflections (tree lhs, tree rhs)
                                   TREE_VEC_ELT (rhs, 3))
            && TREE_VEC_ELT (lhs, 4) == TREE_VEC_ELT (rhs, 4));
   else if (lkind == REFLECT_ANNOTATION)
-    return lhs == rhs;
+    return TREE_VALUE (lhs) == TREE_VALUE (rhs);
   else if (TYPE_P (lhs) && TYPE_P (rhs))
     {
       /* Given "using A = int;", "^^int != ^^A" should hold.  */
--- gcc/testsuite/g++.dg/reflect/annotations12.C.jj     2026-03-09 
12:10:39.212043644 +0100
+++ gcc/testsuite/g++.dg/reflect/annotations12.C        2026-03-09 
11:52:51.332668039 +0100
@@ -11,3 +11,15 @@ constexpr std::meta::info a1 = annotatio
 constexpr std::meta::info a2 = annotations_of (^^D <char>)[0];
 static_assert (a1 != a2);
 static_assert (constant_of (a1) == constant_of (a2));
+
+[[=1]] int x, y;
+static_assert (annotations_of (^^x)[0] == annotations_of (^^y)[0]);
+int z [[=2]], w [[=2]];
+static_assert (annotations_of (^^z)[0] != annotations_of (^^w)[0]);
+[[=3]] int u [[=3]], v [[=3]];
+static_assert ((annotations_of (^^u)[0] == annotations_of (^^v)[0])
+              != (annotations_of (^^u)[1] == annotations_of (^^v)[1]));
+//static_assert (annotations_of (^^u)[0] == annotations_of (^^v)[0]);
+//static_assert (annotations_of (^^u)[1] != annotations_of (^^v)[1]);
+static_assert (annotations_of (^^u)[0] != annotations_of (^^u)[1]);
+static_assert (annotations_of (^^v)[0] != annotations_of (^^v)[1]);

        Jakub

Reply via email to