[{"id":3673796,"web_url":"http://patchwork.ozlabs.org/comment/3673796/","msgid":"<565a3f92-cb8a-4b88-b689-8bfe4233f2bd@redhat.com>","list_archive_url":null,"date":"2026-04-06T16:36:16","subject":"Re: [PATCH] c++, v3: Implement the annotations_of on parms part of\n P3795R1","submitter":{"id":4337,"url":"http://patchwork.ozlabs.org/api/people/4337/","name":"Jason Merrill","email":"jason@redhat.com"},"content":"On 4/6/26 2:18 AM, Jakub Jelinek wrote:\n> On Fri, Apr 03, 2026 at 04:37:20PM -0400, Jason Merrill wrote:\n>> \"void_node\"\n> \n> Changed.\n> \n>>> +\t    tree val = TREE_VALUE (a);\n>>> +\t    if (TREE_PURPOSE (val) == NULL_TREE)\n>>> +\t      TREE_PURPOSE (val) = void_node;\n>>> +\t    else if (TREE_CODE (TREE_PURPOSE (val)) == INTEGER_CST)\n>>\n>> It seems impossible to have INTEGER_CST this early, we can't have tried to\n>> mangle a function we haven't even built yet.  And indeed the testcase\n>> doesn't exercise this case.  Maybe assert NULL_TREE instead?\n> \n> Assert added instead.\n> \n>>> +\t/* For ^^fnparm or variable_of (parameters_of (^^fn)[N])\n>>> +\t   filter out annotations not specified on the function\n>>> +\t   definition.  */\n>>\n>> Let's also mention that purpose is set in grokfndecl or\n>> reflection_mangle_prefix.\n> \n> Done.\n> \n>> Also \"void_node\".\n> \n> Changed.\n> \n> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?\n\nOK.\n\n> 2026-04-06  Jakub Jelinek  <jakub@redhat.com>\n> \n> \t* decl.cc (grokfndecl): For -freflection mark annotations of\n> \tPARM_DECLs in a function definition.\n> \t* reflect.cc (eval_annotations_of): Allow annotations_of on\n> \tfunction parameters.  For r which is a PARM_DECL without REFLECT_PARM,\n> \tfilter out annotations not marked by grokfndecl.\n> \t(reflection_mangle_prefix): Preserve the grokfndecl marking of\n> \tannotations during mangling.\n> \n> \t* g++.dg/reflect/annotations15.C: New test.\n> \n> --- gcc/cp/decl.cc.jj\t2026-03-26 07:59:59.527656320 +0100\n> +++ gcc/cp/decl.cc\t2026-03-26 12:31:36.887319793 +0100\n> @@ -12218,7 +12218,28 @@ grokfndecl (tree ctype,\n>   \n>     DECL_ARGUMENTS (decl) = parms;\n>     for (t = parms; t; t = DECL_CHAIN (t))\n> -    DECL_CONTEXT (t) = decl;\n> +    {\n> +      DECL_CONTEXT (t) = decl;\n> +      if (flag_reflection\n> +\t  && initialized == SD_INITIALIZED\n> +\t  && DECL_ATTRIBUTES (t))\n> +\tfor (tree a = DECL_ATTRIBUTES (t);\n> +\t     (a = lookup_attribute (\"internal \", \"annotation \", a));\n> +\t     a = TREE_CHAIN (a))\n> +\t  {\n> +\t    gcc_checking_assert (TREE_CODE (TREE_VALUE (a)) == TREE_LIST);\n> +\t    /* Mark TREE_PURPOSE of the value that it is an annotation\n> +\t       on an argument of a function definition (rather than\n> +\t       annotation from function declaration).  For function parameter\n> +\t       reflection all annotations are listed, while for variable_of\n> +\t       only those marked here.  Annotation is marked as coming from\n> +\t       function definition's argument if it has TREE_PURPOSE\n> +\t       void_node or INTEGER_CST with signed type.  */\n> +\t    tree val = TREE_VALUE (a);\n> +\t    gcc_assert (TREE_PURPOSE (val) == NULL_TREE);\n> +\t    TREE_PURPOSE (val) = void_node;\n> +\t  }\n> +    }\n>   \n>     /* Propagate volatile out from type to decl.  */\n>     if (TYPE_VOLATILE (type))\n> --- gcc/cp/reflect.cc.jj\t2026-03-25 20:32:38.262640083 +0100\n> +++ gcc/cp/reflect.cc\t2026-03-26 12:30:48.440143055 +0100\n> @@ -3812,14 +3812,16 @@ eval_annotations_of (location_t loc, con\n>   \t|| eval_is_type_alias (r) == boolean_true_node\n>   \t|| eval_is_variable (r, kind) == boolean_true_node\n>   \t|| eval_is_function (r) == boolean_true_node\n> +\t|| eval_is_function_parameter (r, kind) == boolean_true_node\n>   \t|| eval_is_namespace (r) == boolean_true_node\n>   \t|| eval_is_enumerator (r) == boolean_true_node\n>   \t|| eval_is_base (r, kind) == boolean_true_node\n>   \t|| eval_is_nonstatic_data_member (r) == boolean_true_node))\n>       return throw_exception (loc, ctx,\n>   \t\t\t    \"reflection does not represent a type,\"\n> -\t\t\t    \" type alias, variable, function, namespace,\"\n> -\t\t\t    \" enumerator, direct base class relationship,\"\n> +\t\t\t    \" type alias, variable, function, function\"\n> +\t\t\t    \" parameter, namespace, enumerator,\"\n> +\t\t\t    \" direct base class relationship,\"\n>   \t\t\t    \" or non-static data member\",\n>   \t\t\t    fun, non_constant_p, jump_target);\n>   \n> @@ -3836,6 +3838,7 @@ eval_annotations_of (location_t loc, con\n>       }\n>   \n>     r = maybe_get_first_fn (r);\n> +  bool var_of = false;\n>     if (kind == REFLECT_BASE)\n>       {\n>         gcc_assert (TREE_CODE (r) == TREE_BINFO);\n> @@ -3860,7 +3863,11 @@ eval_annotations_of (location_t loc, con\n>   \tr = TYPE_ATTRIBUTES (r);\n>       }\n>     else if (DECL_P (r))\n> -    r = DECL_ATTRIBUTES (r);\n> +    {\n> +      if (TREE_CODE (r) == PARM_DECL && kind != REFLECT_PARM)\n> +\tvar_of = true;\n> +      r = DECL_ATTRIBUTES (r);\n> +    }\n>     else\n>       gcc_unreachable ();\n>     vec<constructor_elt, va_gc> *elts = nullptr;\n> @@ -3869,6 +3876,16 @@ eval_annotations_of (location_t loc, con\n>       {\n>         gcc_checking_assert (TREE_CODE (TREE_VALUE (a)) == TREE_LIST);\n>         tree val = TREE_VALUE (TREE_VALUE (a));\n> +      tree purpose = TREE_PURPOSE (TREE_VALUE (a));\n> +      if (var_of\n> +\t  && (purpose == NULL_TREE\n> +\t      || (TREE_CODE (purpose) == INTEGER_CST\n> +\t\t  && !TYPE_UNSIGNED (TREE_TYPE (purpose)))))\n> +\t/* For ^^fnparm or variable_of (parameters_of (^^fn)[N])\n> +\t   filter out annotations not specified on the function\n> +\t   definition.  TREE_PURPOSE is set in grokfndecl and/or in\n> +\t   reflection_mangle_prefix.  */\n> +\tcontinue;\n>         if (type)\n>   \t{\n>   \t  tree at = TREE_TYPE (val);\n> @@ -8749,7 +8765,13 @@ reflection_mangle_prefix (tree refl, cha\n>         strcpy (prefix, \"an\");\n>         if (TREE_PURPOSE (TREE_VALUE (h)) == NULL_TREE)\n>   \tTREE_PURPOSE (TREE_VALUE (h))\n> -\t  = build_int_cst (integer_type_node, annotation_idx++);\n> +\t  = bitsize_int (annotation_idx++);\n> +      /* TREE_PURPOSE void_node or INTEGER_CST with signed type\n> +\t means it is annotation which should appear in\n> +\t variable_of list.  */\n> +      else if (TREE_PURPOSE (TREE_VALUE (h)) == void_node)\n> +\tTREE_PURPOSE (TREE_VALUE (h))\n> +\t  = sbitsize_int (annotation_idx++);\n>         return TREE_PURPOSE (TREE_VALUE (h));\n>       }\n>     if (eval_is_type_alias (h) == boolean_true_node)\n> --- gcc/testsuite/g++.dg/reflect/annotations15.C.jj\t2026-03-26 12:40:48.910963751 +0100\n> +++ gcc/testsuite/g++.dg/reflect/annotations15.C\t2026-03-26 12:40:37.661154305 +0100\n> @@ -0,0 +1,44 @@\n> +// P3795R2 - Miscellaneous Reflection Cleanup\n> +// { dg-do compile { target c++26 } }\n> +// { dg-additional-options \"-freflection\" }\n> +\n> +#include <meta>\n> +\n> +void foo ([[=1]] int x);\n> +constexpr auto rf = parameters_of (^^foo)[0];\n> +void foo ([[=2, =3]] int x);\n> +\n> +void\n> +foo ([[=4, =5]] int x)\n> +{\n> +  static_assert (annotations_of (^^x).size () == 2);\n> +  static_assert ([: constant_of (annotations_of (^^x)[0]) :] == 4);\n> +  static_assert ([: constant_of (annotations_of (^^x)[1]) :] == 5);\n> +  static_assert (annotations_of (rf).size () == 5);\n> +  static_assert ([: constant_of (annotations_of (rf)[0]) :] == 1);\n> +  static_assert ([: constant_of (annotations_of (rf)[1]) :] == 2);\n> +  static_assert ([: constant_of (annotations_of (rf)[2]) :] == 3);\n> +  static_assert ([: constant_of (annotations_of (rf)[3]) :] == 4);\n> +  static_assert ([: constant_of (annotations_of (rf)[4]) :] == 5);\n> +  static_assert (annotations_of (variable_of (rf)).size () == 2);\n> +  static_assert ([: constant_of (annotations_of (variable_of (rf))[0]) :] == 4);\n> +  static_assert ([: constant_of (annotations_of (variable_of (rf))[1]) :] == 5);\n> +  static_assert (annotations_of (parameters_of (^^foo)[0]).size () == 5);\n> +  static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[0]) :] == 1);\n> +  static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[1]) :] == 2);\n> +  static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[2]) :] == 3);\n> +  static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[3]) :] == 4);\n> +  static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[4]) :] == 5);\n> +  static_assert (annotations_of (^^x)[0] == annotations_of (rf)[3]);\n> +  static_assert (annotations_of (^^x)[0] == annotations_of (variable_of (rf))[0]);\n> +  static_assert (annotations_of (^^x)[0] == annotations_of (parameters_of (^^foo)[0])[3]);\n> +}\n> +\n> +void foo ([[=6]] int x);\n> +static_assert (annotations_of (parameters_of (^^foo)[0]).size () == 6);\n> +static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[0]) :] == 1);\n> +static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[1]) :] == 2);\n> +static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[2]) :] == 3);\n> +static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[3]) :] == 4);\n> +static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[4]) :] == 5);\n> +static_assert ([: constant_of (annotations_of (parameters_of (^^foo)[0])[5]) :] == 6);\n> \n> \n> \tJakub\n>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=FXPUcGho;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=FXPUcGho","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fqFNb6Y9Dz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 07 Apr 2026 02:37:19 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id B15B84BA2E27\n\tfor <incoming@patchwork.ozlabs.org>; Mon,  6 Apr 2026 16:37:17 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id E79AA4BA23C8\n for <gcc-patches@gcc.gnu.org>; Mon,  6 Apr 2026 16:36:21 +0000 (GMT)","from mail-qv1-f71.google.com (mail-qv1-f71.google.com\n [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-564-feguhqR9MP63l9vYdCaizw-1; Mon, 06 Apr 2026 12:36:20 -0400","by mail-qv1-f71.google.com with SMTP id\n 6a1803df08f44-8a4f18b1b5aso198615726d6.0\n for <gcc-patches@gcc.gnu.org>; Mon, 06 Apr 2026 09:36:20 -0700 (PDT)","from [192.168.50.130]\n (130-44-146-247.s12789.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com.\n [130.44.146.247]) by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8aa70136e87sm35703676d6.22.2026.04.06.09.36.17\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Mon, 06 Apr 2026 09:36:17 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org B15B84BA2E27","OpenDKIM Filter v2.11.0 sourceware.org E79AA4BA23C8"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org E79AA4BA23C8","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org E79AA4BA23C8","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775493382; cv=none;\n b=xQmhyX3BC2kgIK4J2s/kAj9nlSLRKcSqycx0tzfa/0rtXnmng0PJTKn2TxbgA0hJq4bhNqViXg4/9qriuhXm03VpTbtmRBsR+0IWG/Q5gAPP1dPXLtEha7MlCx0RL/VWnGF/V3zVwDCcfm8mqLoo7VcHIPwiColFi+4ua2tLn0U=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775493382; c=relaxed/simple;\n bh=H8npP17+hruTTvTaWVeUf6yrAGVTmLh/yzwPObwAEMg=;\n h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From;\n b=lNlo8fq4r6e9YmOl9dHMrgkJCTW1sY6CEmAnSMb/NTFuyHTRii9NpowjF8jYAVKtuy5K6jbQFI4cxdXNaVmrdityMF1lEs0vorFMicEF8MVPWT68RctHeQagJNPh05uYO4jPEGPQVpjBhERIj1EymG0LWiFryQsRU66k6R/AgA4=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1775493381;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=XbzJx03NS1+sB6Xu+Revjhy1tX2/vdOyrNwExqjEWqQ=;\n b=FXPUcGhoBRoo1hp/1rVuwWjl5TLW7CW7RvzzdSdluF9hQYlRmJHVXm1YYUuVcXODY41bWf\n fRV0QHbqjaRvsAeZMiHS6EPTN7o23mB9apJykp/3EyblJG3Se5tt1OwBIQpcl0dYdFaKBl\n UMXAZNASy/Qi3dXo6LMJHHGp3YmjdZI=","X-MC-Unique":"feguhqR9MP63l9vYdCaizw-1","X-Mimecast-MFC-AGG-ID":"feguhqR9MP63l9vYdCaizw_1775493380","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775493380; x=1776098180;\n h=content-transfer-encoding:in-reply-to:from:content-language\n :references:cc:to:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=XbzJx03NS1+sB6Xu+Revjhy1tX2/vdOyrNwExqjEWqQ=;\n b=njenCqt3vK9rsH052zzBNMIfeA0OJisr16Ure2/eWaoZ67sogeV2/8OugJ2rROPhaK\n VONd6mUlYhOtvnRf7K2Unpo4hmbAqCBb+q3u4T6hYKSGMDJfOs2e/m+n57/nDQjJ9XIR\n rk31/0sIs2Xc06aKxoy/VBbTuEBAMTciC5W2JAvLNwY/Lz/oXKEIjhuVjdn/twGysFt3\n WwGQzgJ/MNP4lqw8qiodHU/fYHVHDS2pfp+aD7UjGSqj2qZc1t4FOVWeiKs5mqcMuvik\n Bj56+MaBzT4xcni2pQfDaJ0La/2CY5gEFvHhBVXnRkMS9FItTpVxN1ygFfxiUvWksjnc\n LTfw==","X-Forwarded-Encrypted":"i=1;\n AJvYcCVgWcMRLLGOtyFF27OECt8H2bCkl25ktKpyQGJdsk/rfPKd57zC5sEaBHSJpTjhlwiV3zGwD4r7A8X+Mw==@gcc.gnu.org","X-Gm-Message-State":"AOJu0YxE8Z22R/jlHm/95J7PBzz2PWaBfRZVawahRJGhWJdtC+AbsnzZ\n JHcW8WTR9PpNX8xxqeS/zglK8Ea86rWYykcat/aoPtup0IvNfk+3cbKmd+crEpctWeiJ1FWGEFD\n TdFFCWF3zfY0HzcuOb9BLENDW39QeWr7KDMxHAznduLNJVYdNjj9CtrWsuMc=","X-Gm-Gg":"AeBDiesiG89mEdnHS6N+OG6nSu1vToEtjzQ52QUcQY/FjllZxE332pCerPZAZZODYuE\n f5mwtHNrItURjZdjRANIjdX2eKnYCPxgZ76hzJDgrmRChG3VT0YFsGE1NM4CZ4XJ0R6ASjxXKuI\n m7RlxVq6VplHxhCUjPD/iABJmtW1cKg1FLRNWDub/0Es31N78VW9u9jwukhQw82PNgu58WBWl7k\n cOax+6pRJawyS9p1pT39jBxbAF2VmxuLOM2aH79DdR+aQcmSlMFraSpun0JOaQRlyp0dPAW0ZXO\n hQGtvGB2Q/jlWscrd3WjcfkkNRzUIgU4IbgUd9BEd+e206KU3YYyPSvDkvW1n7uAplEsQjhwUh5\n bY0F7/irhwMQRxcox/D77ABnqS+JhxGMHb5d9VgZalkQButvmAjWIUAB9rZL8PlS1C11Uv5eQG5\n S3rDnjmkV7nEpfwFwT7O7zh6anAmSHKWM=","X-Received":["by 2002:a05:6214:5016:b0:89c:3f38:a992 with SMTP id\n 6a1803df08f44-8a703265cefmr219861556d6.22.1775493379559;\n Mon, 06 Apr 2026 09:36:19 -0700 (PDT)","by 2002:a05:6214:5016:b0:89c:3f38:a992 with SMTP id\n 6a1803df08f44-8a703265cefmr219860806d6.22.1775493378972;\n Mon, 06 Apr 2026 09:36:18 -0700 (PDT)"],"Message-ID":"<565a3f92-cb8a-4b88-b689-8bfe4233f2bd@redhat.com>","Date":"Mon, 6 Apr 2026 12:36:16 -0400","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] c++, v3: Implement the annotations_of on parms part of\n P3795R1","To":"Jakub Jelinek <jakub@redhat.com>","Cc":"Marek Polacek <polacek@redhat.com>, gcc-patches@gcc.gnu.org","References":"<acUfPDbhcQHP9ywS@tucnak> <acgGna_99GU8C4Iz@tucnak>\n <e351a962-5123-4321-83b0-ea602f19795d@redhat.com> <adNQMG0418k3_Xpn@tucnak>","From":"Jason Merrill <jason@redhat.com>","In-Reply-To":"<adNQMG0418k3_Xpn@tucnak>","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"UGirofFu2VcARdmNaG1qtYEXjY9JZEC8gwqysnKIaYM_1775493380","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]