[{"id":3679435,"web_url":"http://patchwork.ozlabs.org/comment/3679435/","msgid":"<76c5f3bd-3f4e-4797-9bce-8ce42d880772@redhat.com>","list_archive_url":null,"date":"2026-04-20T15:12:12","subject":"Re: [PATCH v2] c++/reflection: support splices with CTAD [PR124706]","submitter":{"id":4337,"url":"http://patchwork.ozlabs.org/api/people/4337/","name":"Jason Merrill","email":"jason@redhat.com"},"content":"On 4/20/26 10:52 AM, Marek Polacek wrote:\n> On Fri, Apr 17, 2026 at 05:57:42PM -0400, Jason Merrill wrote:\n>> On 4/17/26 4:28 PM, Marek Polacek wrote:\n>>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?\n>>\n>> OK.\n> \n> I realized I'd forgotten to update tsubst_splice_scope so CTAD\n> still didn't work with dependent splices.  I'd like to push this\n> patch instead.\n> \n> We should also improve the \"is not usable in a splice\" messages\n> but that's for a follow up patch.\n> \n> Test reflect/*, ok for trunk?\n\nOK.\n\n> -- >8 --\n> This PR points out that we don't handle a splice-type-spec that\n> designates a deducible template, which then serves as a placeholder\n> for CTAD.  This is allowed by [dcl.type.simple]/3.  This patch\n> fixes that problem by calling make_template_placeholder if we\n> get a deducible template.\n> \n> \tPR c++/124706\n> \n> gcc/cp/ChangeLog:\n> \n> \t* parser.cc (cp_parser_splice_type_specifier): For ctad_template_p\n> \tcall make_template_placeholder.\n> \t* pt.cc (tsubst_splice_scope): Likewise.\n> \n> gcc/testsuite/ChangeLog:\n> \n> \t* g++.dg/reflect/error10.C: Adjust dg-error.\n> \t* g++.dg/reflect/type9.C: Likewise.\n> \t* g++.dg/reflect/ctad1.C: New test.\n> \t* g++.dg/reflect/ctad2.C: New test.\n> ---\n>   gcc/cp/parser.cc                       |  6 ++++\n>   gcc/cp/pt.cc                           |  2 ++\n>   gcc/testsuite/g++.dg/reflect/ctad1.C   | 28 ++++++++++++++++++\n>   gcc/testsuite/g++.dg/reflect/ctad2.C   | 41 ++++++++++++++++++++++++++\n>   gcc/testsuite/g++.dg/reflect/error10.C |  5 ++--\n>   gcc/testsuite/g++.dg/reflect/type9.C   |  2 +-\n>   6 files changed, 80 insertions(+), 4 deletions(-)\n>   create mode 100644 gcc/testsuite/g++.dg/reflect/ctad1.C\n>   create mode 100644 gcc/testsuite/g++.dg/reflect/ctad2.C\n> \n> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc\n> index cc59065848a..9f2641f2ab2 100644\n> --- a/gcc/cp/parser.cc\n> +++ b/gcc/cp/parser.cc\n> @@ -6258,6 +6258,12 @@ cp_parser_splice_type_specifier (cp_parser *parser)\n>     if (dependent_splice_p (type))\n>       return make_splice_scope (type, /*type_p=*/true);\n>   \n> +  /* [dcl.type.simple]/3: A type-specifier is a placeholder for a deduced\n> +     class type if [...] it is of the form typename[opt] splice-specifier and\n> +     the splice-specifier designates a class template or alias template.  */\n> +  if (ctad_template_p (type))\n> +    type = make_template_placeholder (type);\n> +\n>     if (!valid_splice_type_p (type))\n>       {\n>         if (!cp_parser_simulate_error (parser))\n> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc\n> index ca2c5301cca..2cf14e2c801 100644\n> --- a/gcc/cp/pt.cc\n> +++ b/gcc/cp/pt.cc\n> @@ -16901,6 +16901,8 @@ tsubst_splice_scope (tree t, tree args, tsubst_flags_t complain, tree in_decl)\n>       return r;\n>     if (dependent_splice_p (r))\n>       return make_splice_scope (r, SPLICE_SCOPE_TYPE_P (t));\n> +  if (SPLICE_SCOPE_TYPE_P (t) && ctad_template_p (r))\n> +    r = make_template_placeholder (r);\n>     if (SPLICE_SCOPE_TYPE_P (t)\n>         ? !valid_splice_type_p (r)\n>         : !valid_splice_scope_p (r))\n> diff --git a/gcc/testsuite/g++.dg/reflect/ctad1.C b/gcc/testsuite/g++.dg/reflect/ctad1.C\n> new file mode 100644\n> index 00000000000..b733b8ba949\n> --- /dev/null\n> +++ b/gcc/testsuite/g++.dg/reflect/ctad1.C\n> @@ -0,0 +1,28 @@\n> +// PR c++/124706\n> +// { dg-do compile { target c++26 } }\n> +// { dg-additional-options \"-freflection\" }\n> +\n> +using info = decltype(^^::);\n> +\n> +template <class T> struct X;\n> +template <> struct X<int> {\n> +    constexpr X(int) {}\n> +};\n> +X(int) -> X<int>;\n> +\n> +static constexpr auto template_info = ^^X;\n> +\n> +[:template_info:] y{ 13 };\n> +\n> +template<info R>\n> +void\n> +g ()\n> +{\n> +  typename [:R:] q{ 42 };\n> +}\n> +\n> +void\n> +f ()\n> +{\n> +  g<template_info>();\n> +}\n> diff --git a/gcc/testsuite/g++.dg/reflect/ctad2.C b/gcc/testsuite/g++.dg/reflect/ctad2.C\n> new file mode 100644\n> index 00000000000..09e7e26af2a\n> --- /dev/null\n> +++ b/gcc/testsuite/g++.dg/reflect/ctad2.C\n> @@ -0,0 +1,41 @@\n> +// PR c++/124706\n> +// { dg-do compile { target c++26 } }\n> +// { dg-additional-options \"-freflection\" }\n> +\n> +using info = decltype(^^::);\n> +\n> +template <class T>\n> +struct A\n> +{\n> +  A(T);\n> +};\n> +[:^^A:] a(42);\n> +typename [:^^A:] a2(42);\n> +\n> +template<typename T> struct B { T x; };\n> +[:^^B:] b{0};\n> +typename [:^^B:] b2{0};\n> +\n> +template<class T, class U>\n> +struct X { X(U) {} };\n> +\n> +template<class U>\n> +using Y = X<void, U>;\n> +\n> +[:^^Y:] y{1};\n> +typename [:^^Y:] y2{1};\n> +\n> +template<info R>\n> +void\n> +g ()\n> +{\n> +  typename [:R:] x(42);\n> +}\n> +\n> +void\n> +f ()\n> +{\n> +  g<^^A>();\n> +  g<^^B>();\n> +  g<^^Y>();\n> +}\n> diff --git a/gcc/testsuite/g++.dg/reflect/error10.C b/gcc/testsuite/g++.dg/reflect/error10.C\n> index 891a643c1a0..1ac171c73cc 100644\n> --- a/gcc/testsuite/g++.dg/reflect/error10.C\n> +++ b/gcc/testsuite/g++.dg/reflect/error10.C\n> @@ -39,8 +39,7 @@ template<int>\n>   struct S {};\n>   \n>   void\n> -fn5 (int, typename [: ^^S :] i) // { dg-error \"expected a reflection of a type|declared\" }\n> -// { dg-message \"but .S. is a class template\" \"\" { target *-*-* } 39 }\n> +fn5 (int, typename [: ^^S :] i) // { dg-error \"template placeholder not permitted in parameter\" }\n>   {\n>   }\n>   \n> @@ -49,6 +48,6 @@ void bar ();\n>   \n>   void\n>   fn6 (int, typename [: ^^bar :] i) // { dg-error \"expected a reflection of a type|declared\" }\n> -// { dg-message \"but .bar. is a function template\" \"\" { target *-*-* } 48 }\n> +// { dg-message \"but .bar. is a function template\" \"\" { target *-*-* } 47 }\n>   {\n>   }\n> diff --git a/gcc/testsuite/g++.dg/reflect/type9.C b/gcc/testsuite/g++.dg/reflect/type9.C\n> index 56bed4590a5..2d0409e4b86 100644\n> --- a/gcc/testsuite/g++.dg/reflect/type9.C\n> +++ b/gcc/testsuite/g++.dg/reflect/type9.C\n> @@ -32,7 +32,7 @@ template<info R> void fn9 () { int n = typename [:R:](42); } // { dg-error \"not\n>   template<info R> void fn10 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n>   template<info R> void fn11 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n>   template<info R> void fn12 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n> -template<info R> void fn13 () { int n = typename [:R:](42); } // { dg-error \"not usable in a splice type\" }\n> +template<info R> void fn13 () { int n = typename [:R:](42); } // { dg-error \"class template argument deduction failed|no matching\" }\n>   \n>   template void fn1<^^foo<int>>();  // { dg-message \"required from here\" }\n>   template void fn2<^^foo>();\t  // { dg-message \"required from here\" }\n> \n> base-commit: a8234bec74bda4ae1e507e1706053a5d781a4aa6","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=IcFje7FR;\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=IcFje7FR","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.129.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 4fzps76cmQz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 01:12:54 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 596ED4B3589F\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 20 Apr 2026 15:12:52 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id 534A34BA23DB\n for <gcc-patches@gcc.gnu.org>; Mon, 20 Apr 2026 15:12:19 +0000 (GMT)","from mail-qt1-f198.google.com (mail-qt1-f198.google.com\n [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-533-3w8nZHxXOmOhTnG_Fid_GQ-1; Mon, 20 Apr 2026 11:12:17 -0400","by mail-qt1-f198.google.com with SMTP id\n d75a77b69052e-50e5a336b44so20750171cf.0\n for <gcc-patches@gcc.gnu.org>; Mon, 20 Apr 2026 08:12:17 -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 d75a77b69052e-50e39305285sm100132991cf.13.2026.04.20.08.12.13\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Mon, 20 Apr 2026 08:12:14 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 596ED4B3589F","OpenDKIM Filter v2.11.0 sourceware.org 534A34BA23DB"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 534A34BA23DB","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 534A34BA23DB","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776697939; cv=none;\n b=Y/E/pd02bUWxJIxRUQDNt1uG/hEC3Eyu2mScapvImq2nopgaJf1DiJsM+qxK4fv96rRzcSrMbzHASyBFTPqiQLOPbp2QV7CfIw2dFTVN3Aq2tf/J8odgmUKbZh79Ws/Lb5K5NNWqChuF4hgzCeNWWHW2Dg7uTV52zMAprRettw0=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776697939; c=relaxed/simple;\n bh=Jdw8OOBpiB7SOOidB/frim7h24gum5GJlfJ5BilkoUw=;\n h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From;\n b=M9RfhNC0Lx+PgAXUijDxBcxI83sCcTY9WLV4QhuCddDL6FUYypfHO949hIxZJjwppvsB2yWHVQux/TtWC/ppq2nDZbMEvcO7vrWhvSd+uNUmiWFkspDScVFzkHaKgAarVfEfJkzDbqqYilPa9Yl5KW4NaX3oEW4UoSi7PmRebmA=","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=1776697939;\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=i96CvxlEIDi4eGbv4wxSAe4oH83ucFgihS+mDKIig68=;\n b=IcFje7FRFwaGEG9s2eTJTeE94XSam+y/uI9jnSPgiBqFdugY4XJlskso9H1F1s2QtGxWyV\n mm/iIdT8mGDfO1miTNz5Z677kzQZ8VWzCgtDOXBh5+fRtbThELYfrqMoCZmavYcz3SXOAv\n +0UItTKXDuuab4hdQZR8aaXc5RSUN5o=","X-MC-Unique":"3w8nZHxXOmOhTnG_Fid_GQ-1","X-Mimecast-MFC-AGG-ID":"3w8nZHxXOmOhTnG_Fid_GQ_1776697937","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776697936; x=1777302736;\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=i96CvxlEIDi4eGbv4wxSAe4oH83ucFgihS+mDKIig68=;\n b=WSjD58QiCtMZJZjoRVyGr5M7t1DjmvdQM3A1MGcXwWt32Nfs7axqoz8jZqBEXFGUMw\n sAeNB1kx0MOdwo74Ks6UhcHO2qh4eqQ26zT2q62+U4Cjbdh5aD4EdONctX69jHVIX3OJ\n IW6vWjVP4LCsDRqOLwDZCIawu9dpIYc3RNqH2wfiCEaGwkqSzMmfyHj9VB5RAwBAzvSr\n lWD7gG/PiybFkjRbhA7iahcuE2TM9Nh1xk6kUu+Gxms1NslrAmnTgB3qR/I8ayq7u9Fg\n kHGn07meD7rL+zDEtsMbceOgux4ydxDPBPfptTlm89dUbh9v63uUIx6lDmwirJTMg1Gy\n GzhQ==","X-Gm-Message-State":"AOJu0YxDkz3nCmMLLW/6UO1GJj+iR5eiwPQQyKCeE7iC7el1SjLlCLuz\n D7yd83aNvr5v3GNgIm2v7Gt/Xy5CBWVv2T0lGMs09yykDH4OG5hd/Y8UZ8knnCyt3QMVh86C5cC\n PuAEdP4lVPSeCIH9XIU9oB/9IQPzFKYVS6HX4eKiwz74qb0d8zbJXKmT1G1++g0M5cgHKGQ==","X-Gm-Gg":"AeBDieuEzZCAsfd3pbR6prrVpYklLR4v+xSzpE7by7HwQW51iJFa5BuVJ9EGu1bAqJ0\n 5avcDY1q8xE38PFdK4YnXDg6PLJGFeSmhmvQ6GbW4yfMynd10GBdLL+nUpMOygXdY42WLQtwBGj\n +YRfuLRtsGBdE5xZEODwP49lmNri0uCk8GTcrLK4lnaTlxmRoBnXaNDhRlFGz+d4rgGpdqz4Rl6\n 6ilxqWJSDShlynazkY4HTq2tuSvo/FNAVmxsNEgKEGGci/+LZf/VtN8c9dMSHsLdJStBzyF9VNs\n YA/d6gqwkVmEe94vHDMltVi3/E2nEff3X0kqH36F9bPX4RPpqWC+XTuzHCuqhlP893Ehqw6ZUCA\n 1Io31KFgSS0TGWJcsc5NDJDWE0GAJbLVkI5oIqu2A7AQ2wr+KXONvilTqsR1Ta1mwgaLKZksd+Q\n vmuFGavlDkm4gQQnD5ygCbmA32A3hER2abi42b8SXlWA==","X-Received":["by 2002:ac8:5e14:0:b0:50d:7ca3:379a with SMTP id\n d75a77b69052e-50e365f8d0cmr138327341cf.3.1776697936204;\n Mon, 20 Apr 2026 08:12:16 -0700 (PDT)","by 2002:ac8:5e14:0:b0:50d:7ca3:379a with SMTP id\n d75a77b69052e-50e365f8d0cmr138326691cf.3.1776697935525;\n Mon, 20 Apr 2026 08:12:15 -0700 (PDT)"],"Message-ID":"<76c5f3bd-3f4e-4797-9bce-8ce42d880772@redhat.com>","Date":"Mon, 20 Apr 2026 11:12:12 -0400","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] c++/reflection: support splices with CTAD [PR124706]","To":"Marek Polacek <polacek@redhat.com>","Cc":"GCC Patches <gcc-patches@gcc.gnu.org>","References":"<20260417202807.373863-1-polacek@redhat.com>\n <18c81c0b-da77-4423-960f-3c5e88bf336b@redhat.com>\n <aeY9k589Zfb7zboB@redhat.com>","From":"Jason Merrill <jason@redhat.com>","In-Reply-To":"<aeY9k589Zfb7zboB@redhat.com>","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"LE7U1ag1pmTjcq95ijrQ878L806IkdWaFcOHMJU6GZk_1776697937","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"}}]