{"id":2221534,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2221534/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/patch/adfVRQUvuvgBZXuF@tucnak/","project":{"id":17,"url":"http://patchwork.ozlabs.org/api/1.1/projects/17/?format=json","name":"GNU Compiler Collection","link_name":"gcc","list_id":"gcc-patches.gcc.gnu.org","list_email":"gcc-patches@gcc.gnu.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<adfVRQUvuvgBZXuF@tucnak>","date":"2026-04-09T16:35:17","name":"c++: Unshare expr in get_template_parm_object [PR124792]","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"47e53f61fb28e44e9a603685aacd907b93d4f994","submitter":{"id":671,"url":"http://patchwork.ozlabs.org/api/1.1/people/671/?format=json","name":"Jakub Jelinek","email":"jakub@redhat.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/gcc/patch/adfVRQUvuvgBZXuF@tucnak/mbox/","series":[{"id":499328,"url":"http://patchwork.ozlabs.org/api/1.1/series/499328/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/list/?series=499328","date":"2026-04-09T16:35:17","name":"c++: Unshare expr in get_template_parm_object [PR124792]","version":1,"mbox":"http://patchwork.ozlabs.org/series/499328/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2221534/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2221534/checks/","tags":{},"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=NG9OqtPz;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.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=NG9OqtPz","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 [38.145.34.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 4fs5Cg6rCjz1yHG\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 02:35:58 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id B2B244BA2E35\n\tfor <incoming@patchwork.ozlabs.org>; Thu,  9 Apr 2026 16:35:56 +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 286A74BA5439\n for <gcc-patches@gcc.gnu.org>; Thu,  9 Apr 2026 16:35:26 +0000 (GMT)","from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-164-FLXQ5ygdOBaAADsB7Qu4fg-1; Thu,\n 09 Apr 2026 12:35:24 -0400","from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 097C61800250; Thu,  9 Apr 2026 16:35:23 +0000 (UTC)","from tucnak.zalov.cz (unknown [10.44.33.241])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with\n ESMTPS\n id 4B7F7195608E; Thu,  9 Apr 2026 16:35:22 +0000 (UTC)","from tucnak.zalov.cz (localhost [127.0.0.1])\n by tucnak.zalov.cz (8.18.1/8.18.1) with ESMTPS id 639GZJSR732337\n (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT);\n Thu, 9 Apr 2026 18:35:19 +0200","(from jakub@localhost)\n by tucnak.zalov.cz (8.18.1/8.18.1/Submit) id 639GZHLG732336;\n Thu, 9 Apr 2026 18:35:17 +0200"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org B2B244BA2E35","OpenDKIM Filter v2.11.0 sourceware.org 286A74BA5439"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 286A74BA5439","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 286A74BA5439","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1775752526; cv=none;\n b=pzL13DDulvStqCDeVqMtzQ++WybGwD4rtr6G+H30kkEXO+GHPiATBW7ZhBOcJhohusO94Tg5ASiSQvsIeBj8vz7LkBAnHyNNF4ePT68ZXHUARuZW5tcqvCeB7cZ6xN2i728SeSDseOSB2zhuYvEY7ZHN2b/S9UvrscGVv6lXYSA=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1775752526; c=relaxed/simple;\n bh=KGd4BIrLOxFf/9kq95/6uLtPVi5WUEa7bjd4kGvgI5I=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=nnhWcUGRzMN+92yUHFSZwAHZrS+xYligvMKRzzfHE1VNWvYK/jeYVzIdiRWj3XOV2DCW1uVHkBpxi8szcHAkfbDNAJxrqa4xxJKjHrltQoKMVVGYvhAtjZpRrcv9F/b/tIhopypWeVuLQHsvYE3k2u9shU5JB3dDLt4JsMGtjWM=","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=1775752525;\n h=from:from:reply-to:reply-to:subject:subject:date:date:\n message-id:message-id:to:to:cc:cc:mime-version:mime-version:\n content-type:content-type:in-reply-to:in-reply-to:  references:references;\n bh=wSC+ipNw+TW+pxUCSIQg0kpmwEeZNcrAatWqpPFdCvA=;\n b=NG9OqtPzRp5NsAq9dCP5ks7G599Hvozo8DkgAuvskgCXbo5RzqZL/G/gje02Z2xB25GNmn\n MeOhE20ZtDBDU7YkymcLXYiGX7Ye/h5g4D3vIaHwB6wyofUQZG8Bz3WcARfZsoGOdw+vkg\n DBF5wl+0Defd0djEz1AmiAKpVyi4eKU=","X-MC-Unique":"FLXQ5ygdOBaAADsB7Qu4fg-1","X-Mimecast-MFC-AGG-ID":"FLXQ5ygdOBaAADsB7Qu4fg_1775752523","Date":"Thu, 9 Apr 2026 18:35:17 +0200","From":"Jakub Jelinek <jakub@redhat.com>","To":"Jason Merrill <jason@redhat.com>","Cc":"Patrick Palka <ppalka@redhat.com>, chzn@mail.ustc.edu.cn,\n gcc-patches@gcc.gnu.org","Subject":"[PATCH] c++: Unshare expr in get_template_parm_object [PR124792]","Message-ID":"<adfVRQUvuvgBZXuF@tucnak>","References":"<15b4a0ee.835e2.19d6ab44456.Coremail.chzn@mail.ustc.edu.cn>\n <58536bff.85d93.19d6cecd862.Coremail.chzn@mail.ustc.edu.cn>\n <0ce6469a-6ef2-2d0a-f9e2-6c54d7caff01@idea>\n <1be00eb4-570e-41af-8349-770940eee76e@redhat.com>\n <addVcdge2uqtSg2T@tucnak>\n <a59bb4a6-0b88-40c9-b84a-2df21f214704@redhat.com>","MIME-Version":"1.0","In-Reply-To":"<a59bb4a6-0b88-40c9-b84a-2df21f214704@redhat.com>","X-Scanned-By":"MIMEDefang 3.0 on 10.30.177.17","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"feqhGyC47eVVMEynLjEN62hxrPIb2pNj_0izvrwua8A_1775752523","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","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>","Reply-To":"Jakub Jelinek <jakub@redhat.com>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"},"content":"On Thu, Apr 09, 2026 at 12:07:42PM -0400, Jason Merrill wrote:\n> > With reflection, we can create the NTTPOs during constant evaluation rather than\n> > after cxx_eval_outermost_constant_expr has unshared those, so later\n> > processing within the same cxx_eval_outermost_constant_expr call can modify\n> > those not unshared trees.\n> > Now, from reflect.cc get_template_parm_object is called directly from\n> > eval_reflect_constant_string (I think not a problem, the argument should be\n> > always STRING_CST in that case), eval_reflect_constant_array (also not\n> > a problem IMHO, as the outer CONSTRUCTOR is freshly created by\n> > get_range_elts and what is inside of it is unshared by\n> >              if (VAR_P (expr))\n> >                expr = unshare_expr (DECL_INITIAL (expr));\n> > ) and then indirectly (convert_reflect_constant_arg ->\n> > convert_nontype_argument -> create_template_parm_object) from\n> > within get_range_elts, eval_reflect_constant, eval_reflect_object,\n> > eval_reflect_function.  So, if we don't do unsharing in\n> > get_template_parm_object because it is philosophically attractive but\n> > wastes compile time memory too much when things are usually unshared,\n> \n> Actually, I'm not sure it does waste too much memory; a quick check with\n> -fmem-report shows no difference in the totals on compiling stdc++.h as\n> C++26.  And since we'd only unshare in the case where we're actually\n> creating a new variable, it might actually mean less unsharing in the case\n> of repetitive patterns.\n> \n> > (and yet another question is unshare_constructor vs. unshare_expr),\n> \n> Or even unshare_expr_without_location (like PR91165) if we unshare in\n> get_TPO since all occurrences of the same value get the same variable.\n> \n> It seems that many places use unshare_constructor to protect against things\n> like split_nonconstant_init or cxx_eval_store_expression but not a modifying\n> walk_tree like cp_genericize.\n\nSo, do you want something like the patch below then?\nI think in the modules.cc (aka !check_init) case the CONSTRUCTOR is already\nnot shared because it has been read from the module, but I could be wrong.\n\nAnd another question is about that\n      /* If EXPR contains any PTRMEM_CST, they will get clobbered by\n         lower_var_init before we're done mangling.  So store the original\n         value elsewhere.  We only need to unshare EXPR if it's not yet\n         been processed.  */\n      tree copy = check_init ? unshare_constructor (expr) : expr;\n      hash_map_safe_put<hm_ggc> (tparm_obj_values, decl, copy);\nI guess lower_var_init is done late these days, but still, if we need\ntparm_obj_values at all, couldn't we do it solely for the cases where\nexpr contains any PTRMEM_CSTs inside of it (so search all the nested\nCONSTRUCTORs if we find PTRMEM_CSTs, similarly how cplus_expand_constant\ndoes that, just don't expand anything, just return bool that it contains\nthem and unshare/register in that case), and otherwise just use\nDECL_INITIAL?\n\n2026-04-09  Jakub Jelinek  <jakub@redhat.com>\n\n\tPR c++/124792\n\t* pt.cc (get_template_parm_object): Call unshare_expr_without_location\n\ton expr if check_init.\n\n\t* g++.dg/reflect/pr124792.C: New test.\n\n\n\n\tJakub","diff":"--- gcc/cp/pt.cc.jj\t2026-04-09 18:18:26.461536563 +0200\n+++ gcc/cp/pt.cc\t2026-04-09 18:23:33.840288646 +0200\n@@ -7551,6 +7551,8 @@ get_template_parm_object (tree expr, tre\n   DECL_NAME (decl) = name;\n   SET_DECL_ASSEMBLER_NAME (decl, name);\n   comdat_linkage (decl);\n+  if (check_init)\n+    expr = unshare_expr_without_location (expr);\n \n   if (!zero_init_p (type))\n     {\n--- gcc/testsuite/g++.dg/reflect/pr124792.C.jj\t2026-04-09 18:18:08.189674154 +0200\n+++ gcc/testsuite/g++.dg/reflect/pr124792.C\t2026-04-09 18:18:08.189674154 +0200\n@@ -0,0 +1,11 @@\n+// PR c++/124792\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+struct S { const char *name = nullptr; };\n+\n+constexpr auto a = std::define_static_array (std::vector { S { std::define_static_string (\"foo\") } });\n+constexpr auto b = std::define_static_array (std::vector { S { std::define_static_string (\"foo\") },\n+\t\t\t\t\t\t\t   S { std::define_static_string (\"bar\") } });\n","prefixes":[]}