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.

>    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
> 

Marek

Reply via email to