On 3/10/26 9:15 AM, Marek Polacek wrote:
On Tue, Mar 10, 2026 at 07:58:55AM +0100, Jakub Jelinek wrote:
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);

We can't use cp_tree_equal because of

struct [[=42, =42.0f]] S1;
struct [[=42, =40]] S2;
static_assert (annotations_of (^^S1)[0] != annotations_of (^^S2)[0]);

where cp_tree_equal would compare them ==.

So, patch LGTM.

OK.

Jason

Reply via email to