On 3/5/26 6:30 PM, Marek Polacek wrote:
On Thu, Mar 05, 2026 at 06:18:13PM -0500, Jason Merrill wrote:
On 3/5/26 5:35 PM, Marek Polacek wrote:
On Thu, Mar 05, 2026 at 05:13:32PM -0500, Jason Merrill wrote:
On 3/5/26 2:07 PM, Marek Polacek wrote:
On Wed, Mar 04, 2026 at 07:13:33PM +0000, Boris Staletic wrote:
Bootstrapped and tested on x86_64-pc-linux-gnu.
I have only ran g++.dg/reflect/* tests.
If needed/wanted, I can run the entire `make check`, though
that will take me the rest of the night.
-- >8 --
With an annotation like [[=func]] gcc ends up calling
handle_annotation_attribute with TREE_VALUE (args) being a
VIEW_CONVERT_EXPR, whose type is a FUNCTION_TYPE.
That kind of annotation value should be decayed before checking
if the type is structural.

Signed-off-by: Boris Staletic <[email protected]>

        PR c++/124177

gcc/cp/ChangeLog:

        * tree.cc (handle_annotation_attribute): Decay annotation
        values.

This can fit on one line (80 is the limit).

I prefer to wrap at 76 in commit messages because git log adds 4 spaces at
the beginning.

Fair.

gcc/testsuite/ChangeLog:

        * g++.dg/reflect/annotations11.C: New test.
---
    gcc/cp/tree.cc                               |  1 +
    gcc/testsuite/g++.dg/reflect/annotations11.C | 17 +++++++++++++++++
    2 files changed, 18 insertions(+)
    create mode 100644 gcc/testsuite/g++.dg/reflect/annotations11.C

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 20288ed04e..5c7df0a1d9 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5912,6 +5912,7 @@ handle_annotation_attribute (tree *node, tree ARG_UNUSED 
(name),
          *no_add_attrs = true;
          return NULL_TREE;
        }
+  TREE_VALUE (args) = decay_conversion (TREE_VALUE (args), 
tf_warning_or_error);

I'm not sure if it's reasonable to call decay_conversion on something
type-dependent, so perhaps this should be moved inside of the following
block.

Good point.

But annotations are treated as late attributes so I'm not sure
how we'd get here with anything type-dependent, and I couldn't construct
such a test.  Maybe the !t_d_e_p check could be dropped?

Or turned into an assert.

Sounds good.  I can do it later.

We're supposed to treat the expression as reflect_constant(arg) but
doing the whole convert_reflect_constant_arg thing here seems unpleasant.

Hmm, why unpleasant?  It seems straightforward and might be needed to get
some messy cases right.

I think it might need

    /* Figure out the type for reflect_constant.  */
    type = TREE_TYPE (convert_from_reference (r));
    type = type_decays_to (type);
    type = cv_unqualified (type);

convert_for_reference shouldn't be needed here.

Without it we don't compile this:

   constexpr int a = 3;
   constexpr const int &ref = a;
   static_assert (type_of (constant_of (^^ref)) == ^^int);

Ah, by "here" I meant handle_annotation_attribute, which isn't used by this example. Certainly constant_of needs to convert_from_reference, as part of implementing the splice in

  return reflect_constant([: R :]);

but there's no splice in the annotation.

due to

   error: 'const int&' must be a cv-unqualified structural type that is not a 
reference type

type_decays_to/cv_unqualified to correspond to the [type.deduct.call]
changes in maybe_adjust_types_for_deduction, sure.  And then we wouldn't
need the decay_conversion after all.

for the type, then check !structural_type_p and copy constructibility,
then call convert_reflect_constant_arg, and check for error_mark_node.

Agreed.

But I think convert_reflect_constant_arg isn't entirely correct yet
(FIXME in reflect_constant6.C).

Perhaps, but that doesn't seem like an argument against using it here.

I agree, it will probably work for all our annotation uses.


Boris, let me know if you want me to take this over.

Marek


Reply via email to