[{"id":3680805,"web_url":"http://patchwork.ozlabs.org/comment/3680805/","msgid":"<16f7c127-f24e-692a-202d-092fa960020b@idea>","list_archive_url":null,"date":"2026-04-22T18:24:17","subject":"Re: [PATCH v2] c++/reflection: reflect on dependent class template\n [PR124926]","submitter":{"id":78319,"url":"http://patchwork.ozlabs.org/api/people/78319/","name":"Patrick Palka","email":"ppalka@redhat.com"},"content":"On Wed, 22 Apr 2026, Marek Polacek wrote:\n\n> On Wed, Apr 22, 2026 at 01:43:30PM -0400, Patrick Palka wrote:\n> > On Wed, 22 Apr 2026, Marek Polacek wrote:\n> > \n> > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?\n> > > \n> > > -- >8 --\n> > > Here we issue a bogus error for\n> > > \n> > >   ^^Cls<T>::template Inner\n> > > \n> > > where Inner turns out to be a class type, but we created a SCOPE_REF\n> > > because we can't know in advance what it will substitute into, and\n> > > \n> > >   ^^typename Cls<T>::template Inner\n> > > \n> > > is invalid.  The typename can only be used in\n> > > \n> > >   ^^typename Cls<T>::template Inner<int>\n> > > \n> > > We're taking a reflection so both types and non-types are valid, so\n> > > I think we shouldn't give the error for ^^, and take the reflection\n> > > of the TEMPLATE_DECL.\n> > > \n> > > \tPR c++/124926\n> > > \n> > > gcc/cp/ChangeLog:\n> > > \n> > > \t* pt.cc (tsubst_qualified_id): New bool parameter.  Don't give the\n> > > \t\"instantiation yields a type\" error when the new parameter is true.\n> > > \t(tsubst_expr) <case REFLECT_EXPR>: Adjust the call to\n> > > \ttsubst_qualified_id.\n> > > \n> > > gcc/testsuite/ChangeLog:\n> > > \n> > > \t* g++.dg/reflect/dep15.C: New test.\n> > > ---\n> > >  gcc/cp/pt.cc                         | 13 +++--\n> > >  gcc/testsuite/g++.dg/reflect/dep15.C | 85 ++++++++++++++++++++++++++++\n> > >  2 files changed, 94 insertions(+), 4 deletions(-)\n> > >  create mode 100644 gcc/testsuite/g++.dg/reflect/dep15.C\n> > > \n> > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc\n> > > index 5d97ca7997f..f73805b2557 100644\n> > > --- a/gcc/cp/pt.cc\n> > > +++ b/gcc/cp/pt.cc\n> > > @@ -18238,12 +18238,14 @@ tsubst_baselink (tree baselink, tree object_type,\n> > >     true if the qualified-id will be a postfix-expression in-and-of\n> > >     itself; false if more of the postfix-expression follows the\n> > >     QUALIFIED_ID.  ADDRESS_P is true if the qualified-id is the operand\n> > > -   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.  */\n> > > +   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.\n> > > +   REFLECTING_P is true if this SCOPE_REF is an operand of ^^.  */\n> > >  \n> > >  static tree\n> > >  tsubst_qualified_id (tree qualified_id, tree args,\n> > >  \t\t     tsubst_flags_t complain, tree in_decl,\n> > > -\t\t     bool done, bool address_p, bool name_lookup_p = true)\n> > > +\t\t     bool done, bool address_p, bool name_lookup_p = true,\n> > > +\t\t     bool reflecting_p = false)\n> > >  {\n> > >    tree expr;\n> > >    tree scope;\n> > > @@ -18322,7 +18324,9 @@ tsubst_qualified_id (tree qualified_id, tree args,\n> > >        else\n> > >  \texpr = lookup_qualified_name (scope, expr, LOOK_want::NORMAL, false);\n> > >        if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL\n> > > -\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)\n> > > +\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL\n> > > +\t  /* For ^^T::X, we'll take both types and non-types.  */\n> > > +\t  && !reflecting_p)\n> > >  \t{\n> > >  \t  if (complain & tf_error)\n> > >  \t    {\n> > > @@ -23355,7 +23359,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)\n> > >  \telse if (TREE_CODE (h) == SCOPE_REF)\n> > >  \t  h = tsubst_qualified_id (h, args, complain, in_decl,\n> > >  \t\t\t\t   /*done=*/true, /*address_p=*/false,\n> > > -\t\t\t\t   /*name_lookup_p=*/false);\n> > > +\t\t\t\t   /*name_lookup_p=*/false,\n> > > +\t\t\t\t   /*reflecting_p=*/true);\n> > \n> > Should we just merge name_lookup_p with reflecting_p at this point?\n> > More descriptive flag names are nice but having fewer flags is also nice :)\n> > And at first glance name_lookup_p doesn't seem precisely named, there\n> > are name lookup calls in tsubst_qualified_id that aren't suppressed by\n> > that flag (such as the ones immediately before the error in question).\n> \n> Yeah, that's a good point.  name_lookup_p was false only when called from\n> tsubst_expr/REFLECT_EXPR anyway.  So I think we should indeed merge them\n> as you suggest.\n> \n> dg.exp passed so far, ok for 17?\n\nOK\n\n> \n> -- >8 --\n> Here we issue a bogus error for\n> \n>   ^^Cls<T>::template Inner\n> \n> where Inner turns out to be a class type, but we created a SCOPE_REF\n> because we can't know in advance what it will substitute into, and\n> \n>   ^^typename Cls<T>::template Inner\n> \n> is invalid.  The typename can only be used in\n> \n>   ^^typename Cls<T>::template Inner<int>\n> \n> We're taking a reflection so both types and non-types are valid, so\n> I think we shouldn't give the error for ^^, and take the reflection\n> of the TEMPLATE_DECL.\n> \n> \tPR c++/124926\n> \n> gcc/cp/ChangeLog:\n> \n> \t* pt.cc (tsubst_qualified_id): Rename name_lookup_p parameter to\n> \treflecting_p.  Check !reflecting_p instead of name_lookup_p.  Do\n> \tnot give the \"instantiation yields a type\" error when reflecting_p\n> \tis true.\n> \t(tsubst_expr) <case REFLECT_EXPR>: Adjust the call to\n> \ttsubst_qualified_id.\n> \n> gcc/testsuite/ChangeLog:\n> \n> \t* g++.dg/reflect/dep15.C: New test.\n> ---\n>  gcc/cp/pt.cc                         | 12 ++--\n>  gcc/testsuite/g++.dg/reflect/dep15.C | 85 ++++++++++++++++++++++++++++\n>  2 files changed, 92 insertions(+), 5 deletions(-)\n>  create mode 100644 gcc/testsuite/g++.dg/reflect/dep15.C\n> \n> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc\n> index 5d97ca7997f..551c8bcbb68 100644\n> --- a/gcc/cp/pt.cc\n> +++ b/gcc/cp/pt.cc\n> @@ -18238,12 +18238,12 @@ tsubst_baselink (tree baselink, tree object_type,\n>     true if the qualified-id will be a postfix-expression in-and-of\n>     itself; false if more of the postfix-expression follows the\n>     QUALIFIED_ID.  ADDRESS_P is true if the qualified-id is the operand\n> -   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.  */\n> +   of \"&\".  REFLECTING_P is true if this SCOPE_REF is an operand of ^^.  */\n>  \n>  static tree\n>  tsubst_qualified_id (tree qualified_id, tree args,\n>  \t\t     tsubst_flags_t complain, tree in_decl,\n> -\t\t     bool done, bool address_p, bool name_lookup_p = true)\n> +\t\t     bool done, bool address_p, bool reflecting_p = false)\n>  {\n>    tree expr;\n>    tree scope;\n> @@ -18322,7 +18322,9 @@ tsubst_qualified_id (tree qualified_id, tree args,\n>        else\n>  \texpr = lookup_qualified_name (scope, expr, LOOK_want::NORMAL, false);\n>        if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL\n> -\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)\n> +\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL\n> +\t  /* For ^^T::X, we'll take both types and non-types.  */\n> +\t  && !reflecting_p)\n>  \t{\n>  \t  if (complain & tf_error)\n>  \t    {\n> @@ -18368,7 +18370,7 @@ tsubst_qualified_id (tree qualified_id, tree args,\n>  \t\t\t\t expr, input_location);\n>    /* For ^^S::mem, we do not want to create the dummy object that\n>       finish_non_static_data_member would give us.  */\n> -  else if (TYPE_P (scope) && name_lookup_p)\n> +  else if (TYPE_P (scope) && !reflecting_p)\n>      {\n>        expr = (adjust_result_of_qualified_name_lookup\n>  \t      (expr, scope, current_nonlambda_class_type ()));\n> @@ -23355,7 +23357,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)\n>  \telse if (TREE_CODE (h) == SCOPE_REF)\n>  \t  h = tsubst_qualified_id (h, args, complain, in_decl,\n>  \t\t\t\t   /*done=*/true, /*address_p=*/false,\n> -\t\t\t\t   /*name_lookup_p=*/false);\n> +\t\t\t\t   /*reflecting_p=*/true);\n>  \telse\n>  \t  {\n>  \t    /* [expr.reflect] The id-expression of a reflect-expression is\n> diff --git a/gcc/testsuite/g++.dg/reflect/dep15.C b/gcc/testsuite/g++.dg/reflect/dep15.C\n> new file mode 100644\n> index 00000000000..40273955164\n> --- /dev/null\n> +++ b/gcc/testsuite/g++.dg/reflect/dep15.C\n> @@ -0,0 +1,85 @@\n> +// PR c++/124926\n> +// { dg-do compile { target c++26 } }\n> +// { dg-additional-options \"-freflection\" }\n> +\n> +template <typename T, typename U>\n> +constexpr bool is_same_v = false;\n> +\n> +template <typename T>\n> +constexpr bool is_same_v<T, T> = true;\n> +\n> +// Class template\n> +template <typename>\n> +struct C1 {\n> +  template <typename> struct Inner {};\n> +};\n> +\n> +template <typename T>\n> +constexpr auto vt1 = ^^C1<T>::template Inner;\n> +constexpr auto r1 = vt1<int>;\n> +typename [:r1:]<int> a;\n> +static_assert(r1 == ^^C1<int>::template Inner);\n> +static_assert(is_same_v<decltype(a), C1<int>::Inner<int>>);\n> +\n> +// Class template with typename\n> +template <typename>\n> +struct C6 {\n> +  template <typename> struct Inner {};\n> +};\n> +\n> +template <typename T>\n> +constexpr auto vt6 = ^^typename C6<T>::template Inner<T>;\n> +constexpr auto r6 = vt6<int>;\n> +typename [:r6:] d;\n> +static_assert(r6 == ^^C6<int>::template Inner<int>);\n> +static_assert(is_same_v<decltype(d), C6<int>::Inner<int>>);\n> +\n> +// Variable template\n> +template <typename>\n> +struct C2 {\n> +  template <typename> static constexpr int Inner = 42;\n> +};\n> +\n> +template <typename T>\n> +constexpr auto vt2 = ^^C2<T>::template Inner;\n> +constexpr auto r2 = vt2<int>;\n> +constexpr int i = template [:r2:]<int>;\n> +static_assert(i == 42);\n> +static_assert(vt2<int> == ^^C2<int>::template Inner);\n> +\n> +// Function template\n> +template <typename>\n> +struct C3 {\n> +  template <typename T> static constexpr int Inner (T t) { return t; };\n> +};\n> +template <typename T>\n> +constexpr auto vt3 = ^^C3<T>::template Inner;\n> +constexpr auto r3 = vt3<int>;\n> +static_assert(template [:r3:](42) == 42);\n> +static_assert(vt3<int> == ^^C3<int>::template Inner);\n> +\n> +// Alias template\n> +template <typename>\n> +struct C4 {\n> +  template <typename T> using Inner = C4<T>;\n> +};\n> +template <typename T>\n> +constexpr auto vt4 = ^^C4<T>::template Inner;\n> +constexpr auto r4 = vt4<int>;\n> +typename [:r4:]<int> b;\n> +static_assert(is_same_v<decltype(b), C4<int>>);\n> +static_assert(vt4<int> == ^^C4<int>::template Inner);\n> +\n> +// Alias template with typename\n> +template<typename T> struct X { };\n> +\n> +template <typename>\n> +struct C5 {\n> +  template <typename T> using Inner = X<T>;\n> +};\n> +template <typename T>\n> +constexpr auto vt5 = ^^typename C5<T>::template Inner<T>;\n> +constexpr auto r5 = vt5<int>;\n> +typename [:r5:] c;\n> +static_assert(is_same_v<decltype(c), X<int>>);\n> +static_assert(vt5<int> == ^^C5<int>::template Inner<int>);\n> \n> base-commit: 6bf53f242bc7783894bf3148a2829d626a8a1602\n> -- \n> 2.53.0\n> \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=LSyXfOF+;\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=LSyXfOF+","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\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 4g17Fn2tFfz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 04:35:41 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 6698E42CABD0\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 18:35:39 +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 C2A764427EDC\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:24:21 +0000 (GMT)","from mail-qt1-f199.google.com (mail-qt1-f199.google.com\n [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-379-Spb7GykUOWGuv89IVtsShw-1; Wed, 22 Apr 2026 14:24:20 -0400","by mail-qt1-f199.google.com with SMTP id\n d75a77b69052e-50e5c781193so7539041cf.0\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 11:24:20 -0700 (PDT)","from [2600:4040:aa66:bf00:9e8e:99ff:fed1:71f]\n ([2600:4040:aa66:bf00:9e8e:99ff:fed1:71f])\n by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-50e394903dfsm143521741cf.26.2026.04.22.11.24.17\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 22 Apr 2026 11:24:17 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 6698E42CABD0","OpenDKIM Filter v2.11.0 sourceware.org C2A764427EDC"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org C2A764427EDC","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org C2A764427EDC","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776882261; cv=none;\n b=Fjsj0QLhL2EkrPO4nCTcrqcLo7osDWD+YPbm0pjmGyRNLjLf0PTjfktN8ZRP/oeA/EGYz6EM81C7XucqUutpqw0hZ4FCArKFymo1eQVbVE1JUDO7JNkljsilu87opu7j8ChcEO+Xj8DN95q3wrGZLxA+wCx8YuF+21gmUm7prVI=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776882261; c=relaxed/simple;\n bh=QUhi+6h/G9btplVdyAU894UxxLPD/8Dvil3ncqwrdeA=;\n h=DKIM-Signature:From:Date:To:Subject:Message-ID:MIME-Version;\n b=GS8yCJig5CoZ4ZMeTg7pRgYRNSKFgjdjA5pbCVuxCHUHn4Z/9BJ9coWiduzWlIcl7vHSkRh/bE3O9y9SGTGTl52zRyW9Krg94S+SaFUSUCwJZpEARF4R0WYNXGN7Gj13uPJYxAMap+boysriAD8q2Miyj7y7wfoh/Vd6frNdrqA=","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=1776882261;\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 in-reply-to:in-reply-to:references:references;\n bh=MYO7F1SlFKFv7ofV6Bg//tVmqOExCK8IE4uHIWVfxCA=;\n b=LSyXfOF+2J2R/VA5XYC1rkXum+xivhxyHNPzn+9WjtkmubkNjVhVQ5EDH4jdqlQuAe8ieB\n MdPw257ZTvx2KM1VB7A86Ll+64TXIJALCIOs68xddB+RhMFAKGfWfia+LTqgtliH68UTum\n CLiJfVu2Yr6/eec/+t52Pymj+/8O9QQ=","X-MC-Unique":"Spb7GykUOWGuv89IVtsShw-1","X-Mimecast-MFC-AGG-ID":"Spb7GykUOWGuv89IVtsShw_1776882259","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776882259; x=1777487059;\n h=mime-version:references:message-id:in-reply-to:subject:cc:to:date\n :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=MYO7F1SlFKFv7ofV6Bg//tVmqOExCK8IE4uHIWVfxCA=;\n b=D+7N34ZmQdyaDeDo+8zEgA8YEDWHz2vhTwM/2UqNa1mFGqYbeRo9wLV4RpRx3koR9o\n 0b7wXe7oT49yJnxrrusC6xR2nctUcF7UXyWhdFl6GJ/PJ7L5+qC1rsHL48YT520en/PS\n lf1XfUl7tT8gxULFhKz13AAXLPqsmqKlLi2PV8lk/pJixTAbqqGPEcNYN42P7rKVFSEe\n ZKGjQMt4fu0uZaC1hvYCqurOiaoX2DRhXmhzy8EmZ6FH0yLIw5mGjptlJYNv3dU0xslM\n hJVJAdH1bBUJnw5ZR4pnshBnM8Fb0E3OTuXbrNZwQjt+yyJCVF6B44KQNCHRxpGhTG5p\n AH8g==","X-Forwarded-Encrypted":"i=1;\n AFNElJ/8ax1l9ja8gUDZOvCrAI91MTlPWSltdHMjmm/ma04F15O2HA10QTJBCMDMzMxg+E11CPc4T9VPcAn1Eg==@gcc.gnu.org","X-Gm-Message-State":"AOJu0Yz7p3lTTxw7EbBlRQSvt+l4+fDF2XH7Dt4N4CrI4DHOIIwDgxF2\n f3mMz3bw3jpioINXQNK9CNsH9QAcrakHVBVUwK47YxSOtnUQUCHOUk1F7MwYtJDtdwy92krVnte\n +/KnxWdpHVOtyjGLUIvwge+SbkD8TomHZt4CH3Whk+Huf3GWbV0ztOtUPIto=","X-Gm-Gg":"AeBDieu5dt0vHurwouOBCnBK/Hzi/6dzDvricbTKEHXeV45cjvMJ9VLKyhuHZI+BCtS\n um8kscu0iIDc+THdJWdPbxBHtzmOL8UcHY+S3HpL+8RvUPWEaBa+7zCK0Tjt6l6DuzNSdArwJrm\n K7l56Zk+ENRuW57TjjPgxTnFofG4MVFah/DKRw96KQlfpFELUIdKkSZi3K+AbVqCPPeIY37N2NK\n umKIC0lMBp6kKhJCPCTTPffYNGhcjGsLMIXneAnVsE1xMra8GOdnyaCfBf9FY12P8Wwicfl0Wwp\n 7M0roC+OuTVK09NInkbyZkAn84Ww5UPz6dGyzkFX2uKsGc2WmypBC+gSFnGtMR5IHDXaAcP9Ue8\n 0bD2eWB/lNi/y2pzKsqE10E+5n82nTRLn8Xb+talbX4Lx+Ua/jVoypab6HFd56QYZ","X-Received":["by 2002:a05:622a:44c:b0:50f:a53b:9d5 with SMTP id\n d75a77b69052e-50fa53b0cbcmr110334681cf.2.1776882259149;\n Wed, 22 Apr 2026 11:24:19 -0700 (PDT)","by 2002:a05:622a:44c:b0:50f:a53b:9d5 with SMTP id\n d75a77b69052e-50fa53b0cbcmr110334331cf.2.1776882258545;\n Wed, 22 Apr 2026 11:24:18 -0700 (PDT)"],"From":"Patrick Palka <ppalka@redhat.com>","X-Google-Original-From":"Patrick Palka <patrick@idea>","Date":"Wed, 22 Apr 2026 14:24:17 -0400 (EDT)","To":"Marek Polacek <polacek@redhat.com>","cc":"Patrick Palka <ppalka@redhat.com>, GCC Patches <gcc-patches@gcc.gnu.org>,\n Jason Merrill <jason@redhat.com>","Subject":"Re: [PATCH v2] c++/reflection: reflect on dependent class template\n [PR124926]","In-Reply-To":"<aekPzv3Jab_Gm0sk@redhat.com>","Message-ID":"<16f7c127-f24e-692a-202d-092fa960020b@idea>","References":"<20260422172510.801133-1-polacek@redhat.com>\n <0ee0590a-3c48-6588-dfdf-10ed0fd511fb@idea> <aekPzv3Jab_Gm0sk@redhat.com>","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"d0WTP8wZ83l21JyyjnLcrmPpAf3q7CFJLu7COIoPJhU_1776882259","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=US-ASCII","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"}},{"id":3680823,"web_url":"http://patchwork.ozlabs.org/comment/3680823/","msgid":"<a633d6d5-dd36-d7e8-7a64-2b668a865353@idea>","list_archive_url":null,"date":"2026-04-22T18:26:21","subject":"Re: [PATCH v2] c++/reflection: reflect on dependent class template\n [PR124926]","submitter":{"id":78319,"url":"http://patchwork.ozlabs.org/api/people/78319/","name":"Patrick Palka","email":"ppalka@redhat.com"},"content":"On Wed, 22 Apr 2026, Patrick Palka wrote:\n\n> On Wed, 22 Apr 2026, Marek Polacek wrote:\n> \n> > On Wed, Apr 22, 2026 at 01:43:30PM -0400, Patrick Palka wrote:\n> > > On Wed, 22 Apr 2026, Marek Polacek wrote:\n> > > \n> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?\n> > > > \n> > > > -- >8 --\n> > > > Here we issue a bogus error for\n> > > > \n> > > >   ^^Cls<T>::template Inner\n> > > > \n> > > > where Inner turns out to be a class type, but we created a SCOPE_REF\n> > > > because we can't know in advance what it will substitute into, and\n> > > > \n> > > >   ^^typename Cls<T>::template Inner\n> > > > \n> > > > is invalid.  The typename can only be used in\n> > > > \n> > > >   ^^typename Cls<T>::template Inner<int>\n> > > > \n> > > > We're taking a reflection so both types and non-types are valid, so\n> > > > I think we shouldn't give the error for ^^, and take the reflection\n> > > > of the TEMPLATE_DECL.\n> > > > \n> > > > \tPR c++/124926\n> > > > \n> > > > gcc/cp/ChangeLog:\n> > > > \n> > > > \t* pt.cc (tsubst_qualified_id): New bool parameter.  Don't give the\n> > > > \t\"instantiation yields a type\" error when the new parameter is true.\n> > > > \t(tsubst_expr) <case REFLECT_EXPR>: Adjust the call to\n> > > > \ttsubst_qualified_id.\n> > > > \n> > > > gcc/testsuite/ChangeLog:\n> > > > \n> > > > \t* g++.dg/reflect/dep15.C: New test.\n> > > > ---\n> > > >  gcc/cp/pt.cc                         | 13 +++--\n> > > >  gcc/testsuite/g++.dg/reflect/dep15.C | 85 ++++++++++++++++++++++++++++\n> > > >  2 files changed, 94 insertions(+), 4 deletions(-)\n> > > >  create mode 100644 gcc/testsuite/g++.dg/reflect/dep15.C\n> > > > \n> > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc\n> > > > index 5d97ca7997f..f73805b2557 100644\n> > > > --- a/gcc/cp/pt.cc\n> > > > +++ b/gcc/cp/pt.cc\n> > > > @@ -18238,12 +18238,14 @@ tsubst_baselink (tree baselink, tree object_type,\n> > > >     true if the qualified-id will be a postfix-expression in-and-of\n> > > >     itself; false if more of the postfix-expression follows the\n> > > >     QUALIFIED_ID.  ADDRESS_P is true if the qualified-id is the operand\n> > > > -   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.  */\n> > > > +   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.\n> > > > +   REFLECTING_P is true if this SCOPE_REF is an operand of ^^.  */\n> > > >  \n> > > >  static tree\n> > > >  tsubst_qualified_id (tree qualified_id, tree args,\n> > > >  \t\t     tsubst_flags_t complain, tree in_decl,\n> > > > -\t\t     bool done, bool address_p, bool name_lookup_p = true)\n> > > > +\t\t     bool done, bool address_p, bool name_lookup_p = true,\n> > > > +\t\t     bool reflecting_p = false)\n> > > >  {\n> > > >    tree expr;\n> > > >    tree scope;\n> > > > @@ -18322,7 +18324,9 @@ tsubst_qualified_id (tree qualified_id, tree args,\n> > > >        else\n> > > >  \texpr = lookup_qualified_name (scope, expr, LOOK_want::NORMAL, false);\n> > > >        if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL\n> > > > -\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)\n> > > > +\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL\n> > > > +\t  /* For ^^T::X, we'll take both types and non-types.  */\n> > > > +\t  && !reflecting_p)\n> > > >  \t{\n> > > >  \t  if (complain & tf_error)\n> > > >  \t    {\n> > > > @@ -23355,7 +23359,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)\n> > > >  \telse if (TREE_CODE (h) == SCOPE_REF)\n> > > >  \t  h = tsubst_qualified_id (h, args, complain, in_decl,\n> > > >  \t\t\t\t   /*done=*/true, /*address_p=*/false,\n> > > > -\t\t\t\t   /*name_lookup_p=*/false);\n> > > > +\t\t\t\t   /*name_lookup_p=*/false,\n> > > > +\t\t\t\t   /*reflecting_p=*/true);\n> > > \n> > > Should we just merge name_lookup_p with reflecting_p at this point?\n> > > More descriptive flag names are nice but having fewer flags is also nice :)\n> > > And at first glance name_lookup_p doesn't seem precisely named, there\n> > > are name lookup calls in tsubst_qualified_id that aren't suppressed by\n> > > that flag (such as the ones immediately before the error in question).\n> > \n> > Yeah, that's a good point.  name_lookup_p was false only when called from\n> > tsubst_expr/REFLECT_EXPR anyway.  So I think we should indeed merge them\n> > as you suggest.\n> > \n> > dg.exp passed so far, ok for 17?\n> \n> OK\n\nAnd OK for 16.2, I reckon reflection-only fixes are fair game for\nbackporting.\n\n> \n> > \n> > -- >8 --\n> > Here we issue a bogus error for\n> > \n> >   ^^Cls<T>::template Inner\n> > \n> > where Inner turns out to be a class type, but we created a SCOPE_REF\n> > because we can't know in advance what it will substitute into, and\n> > \n> >   ^^typename Cls<T>::template Inner\n> > \n> > is invalid.  The typename can only be used in\n> > \n> >   ^^typename Cls<T>::template Inner<int>\n> > \n> > We're taking a reflection so both types and non-types are valid, so\n> > I think we shouldn't give the error for ^^, and take the reflection\n> > of the TEMPLATE_DECL.\n> > \n> > \tPR c++/124926\n> > \n> > gcc/cp/ChangeLog:\n> > \n> > \t* pt.cc (tsubst_qualified_id): Rename name_lookup_p parameter to\n> > \treflecting_p.  Check !reflecting_p instead of name_lookup_p.  Do\n> > \tnot give the \"instantiation yields a type\" error when reflecting_p\n> > \tis true.\n> > \t(tsubst_expr) <case REFLECT_EXPR>: Adjust the call to\n> > \ttsubst_qualified_id.\n> > \n> > gcc/testsuite/ChangeLog:\n> > \n> > \t* g++.dg/reflect/dep15.C: New test.\n> > ---\n> >  gcc/cp/pt.cc                         | 12 ++--\n> >  gcc/testsuite/g++.dg/reflect/dep15.C | 85 ++++++++++++++++++++++++++++\n> >  2 files changed, 92 insertions(+), 5 deletions(-)\n> >  create mode 100644 gcc/testsuite/g++.dg/reflect/dep15.C\n> > \n> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc\n> > index 5d97ca7997f..551c8bcbb68 100644\n> > --- a/gcc/cp/pt.cc\n> > +++ b/gcc/cp/pt.cc\n> > @@ -18238,12 +18238,12 @@ tsubst_baselink (tree baselink, tree object_type,\n> >     true if the qualified-id will be a postfix-expression in-and-of\n> >     itself; false if more of the postfix-expression follows the\n> >     QUALIFIED_ID.  ADDRESS_P is true if the qualified-id is the operand\n> > -   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.  */\n> > +   of \"&\".  REFLECTING_P is true if this SCOPE_REF is an operand of ^^.  */\n> >  \n> >  static tree\n> >  tsubst_qualified_id (tree qualified_id, tree args,\n> >  \t\t     tsubst_flags_t complain, tree in_decl,\n> > -\t\t     bool done, bool address_p, bool name_lookup_p = true)\n> > +\t\t     bool done, bool address_p, bool reflecting_p = false)\n> >  {\n> >    tree expr;\n> >    tree scope;\n> > @@ -18322,7 +18322,9 @@ tsubst_qualified_id (tree qualified_id, tree args,\n> >        else\n> >  \texpr = lookup_qualified_name (scope, expr, LOOK_want::NORMAL, false);\n> >        if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL\n> > -\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)\n> > +\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL\n> > +\t  /* For ^^T::X, we'll take both types and non-types.  */\n> > +\t  && !reflecting_p)\n> >  \t{\n> >  \t  if (complain & tf_error)\n> >  \t    {\n> > @@ -18368,7 +18370,7 @@ tsubst_qualified_id (tree qualified_id, tree args,\n> >  \t\t\t\t expr, input_location);\n> >    /* For ^^S::mem, we do not want to create the dummy object that\n> >       finish_non_static_data_member would give us.  */\n> > -  else if (TYPE_P (scope) && name_lookup_p)\n> > +  else if (TYPE_P (scope) && !reflecting_p)\n> >      {\n> >        expr = (adjust_result_of_qualified_name_lookup\n> >  \t      (expr, scope, current_nonlambda_class_type ()));\n> > @@ -23355,7 +23357,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)\n> >  \telse if (TREE_CODE (h) == SCOPE_REF)\n> >  \t  h = tsubst_qualified_id (h, args, complain, in_decl,\n> >  \t\t\t\t   /*done=*/true, /*address_p=*/false,\n> > -\t\t\t\t   /*name_lookup_p=*/false);\n> > +\t\t\t\t   /*reflecting_p=*/true);\n> >  \telse\n> >  \t  {\n> >  \t    /* [expr.reflect] The id-expression of a reflect-expression is\n> > diff --git a/gcc/testsuite/g++.dg/reflect/dep15.C b/gcc/testsuite/g++.dg/reflect/dep15.C\n> > new file mode 100644\n> > index 00000000000..40273955164\n> > --- /dev/null\n> > +++ b/gcc/testsuite/g++.dg/reflect/dep15.C\n> > @@ -0,0 +1,85 @@\n> > +// PR c++/124926\n> > +// { dg-do compile { target c++26 } }\n> > +// { dg-additional-options \"-freflection\" }\n> > +\n> > +template <typename T, typename U>\n> > +constexpr bool is_same_v = false;\n> > +\n> > +template <typename T>\n> > +constexpr bool is_same_v<T, T> = true;\n> > +\n> > +// Class template\n> > +template <typename>\n> > +struct C1 {\n> > +  template <typename> struct Inner {};\n> > +};\n> > +\n> > +template <typename T>\n> > +constexpr auto vt1 = ^^C1<T>::template Inner;\n> > +constexpr auto r1 = vt1<int>;\n> > +typename [:r1:]<int> a;\n> > +static_assert(r1 == ^^C1<int>::template Inner);\n> > +static_assert(is_same_v<decltype(a), C1<int>::Inner<int>>);\n> > +\n> > +// Class template with typename\n> > +template <typename>\n> > +struct C6 {\n> > +  template <typename> struct Inner {};\n> > +};\n> > +\n> > +template <typename T>\n> > +constexpr auto vt6 = ^^typename C6<T>::template Inner<T>;\n> > +constexpr auto r6 = vt6<int>;\n> > +typename [:r6:] d;\n> > +static_assert(r6 == ^^C6<int>::template Inner<int>);\n> > +static_assert(is_same_v<decltype(d), C6<int>::Inner<int>>);\n> > +\n> > +// Variable template\n> > +template <typename>\n> > +struct C2 {\n> > +  template <typename> static constexpr int Inner = 42;\n> > +};\n> > +\n> > +template <typename T>\n> > +constexpr auto vt2 = ^^C2<T>::template Inner;\n> > +constexpr auto r2 = vt2<int>;\n> > +constexpr int i = template [:r2:]<int>;\n> > +static_assert(i == 42);\n> > +static_assert(vt2<int> == ^^C2<int>::template Inner);\n> > +\n> > +// Function template\n> > +template <typename>\n> > +struct C3 {\n> > +  template <typename T> static constexpr int Inner (T t) { return t; };\n> > +};\n> > +template <typename T>\n> > +constexpr auto vt3 = ^^C3<T>::template Inner;\n> > +constexpr auto r3 = vt3<int>;\n> > +static_assert(template [:r3:](42) == 42);\n> > +static_assert(vt3<int> == ^^C3<int>::template Inner);\n> > +\n> > +// Alias template\n> > +template <typename>\n> > +struct C4 {\n> > +  template <typename T> using Inner = C4<T>;\n> > +};\n> > +template <typename T>\n> > +constexpr auto vt4 = ^^C4<T>::template Inner;\n> > +constexpr auto r4 = vt4<int>;\n> > +typename [:r4:]<int> b;\n> > +static_assert(is_same_v<decltype(b), C4<int>>);\n> > +static_assert(vt4<int> == ^^C4<int>::template Inner);\n> > +\n> > +// Alias template with typename\n> > +template<typename T> struct X { };\n> > +\n> > +template <typename>\n> > +struct C5 {\n> > +  template <typename T> using Inner = X<T>;\n> > +};\n> > +template <typename T>\n> > +constexpr auto vt5 = ^^typename C5<T>::template Inner<T>;\n> > +constexpr auto r5 = vt5<int>;\n> > +typename [:r5:] c;\n> > +static_assert(is_same_v<decltype(c), X<int>>);\n> > +static_assert(vt5<int> == ^^C5<int>::template Inner<int>);\n> > \n> > base-commit: 6bf53f242bc7783894bf3148a2829d626a8a1602\n> > -- \n> > 2.53.0\n> > \n> > \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=FOpjHjHf;\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=FOpjHjHf","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\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 4g17Pd00fzz1yGs\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 04:42:27 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id B95D440A1A37\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 18:42:25 +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 EC5854363008\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:26:26 +0000 (GMT)","from mail-qt1-f197.google.com (mail-qt1-f197.google.com\n [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-547-Whl7XJgcOXCqU0VWITs48Q-1; Wed, 22 Apr 2026 14:26:24 -0400","by mail-qt1-f197.google.com with SMTP id\n d75a77b69052e-5073ed1ec6fso17242601cf.1\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 11:26:24 -0700 (PDT)","from [2600:4040:aa66:bf00:9e8e:99ff:fed1:71f]\n ([2600:4040:aa66:bf00:9e8e:99ff:fed1:71f])\n by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-50e6123c3d7sm77909431cf.12.2026.04.22.11.26.22\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 22 Apr 2026 11:26:22 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org B95D440A1A37","OpenDKIM Filter v2.11.0 sourceware.org EC5854363008"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org EC5854363008","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org EC5854363008","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776882387; cv=none;\n b=sL1L9r2Bno4VFk2n3VnD182GmkAX+dUsL012dFMXf9aveKYVAe/xnj7ZycrhVtZZcR3B9qHEHGRdt0cnLmQBVvM2CCsdy5y4YXUHMxAc7EYsLreeUTtgL6bg5FWgJ5abFPMuETCrobMzsA9vb5mwAdcnBrb80bz4zFoLc47hKng=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776882387; c=relaxed/simple;\n bh=NM21hkbmSVVCI02gb+SJt9xqpCwpPLc/BJEhZZGxNYk=;\n h=DKIM-Signature:From:Date:To:Subject:Message-ID:MIME-Version;\n b=DvrnmYJshB9YL1GMUh0xkO0ysRk1iQ2z8KuQb+pM1W5BW5wqsfkbfsdVfYh54szBKjBanNUd3JE37bZ4B7VaK2/8LPjsatqtZFgnJZzfh50d4K3xTIJtL6uqAISbK8I7TDPuVB5y8tguoIp99mbLRf9cqTC6giHc05oqb+Fv7f8=","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=1776882386;\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 in-reply-to:in-reply-to:references:references;\n bh=Qoa0eh4QSPNiVKFvdVIKvMTcMeBAaOZjatSMHRDhvXU=;\n b=FOpjHjHfG/bdIfXYZAH7cSC3t9dhK8CQCgL1dogfT+rViKQpCGi0C0SdkhkdGg7QRnZNP5\n j9oocBrJ6voV2p8O5nXeMVzxsyQVbBsK4B92ZcDQLBsboj8q+yvQWksRKzDC1zekvBzcOr\n p/vPjxG56zsdRVAyT0gj61QSJPyIV8M=","X-MC-Unique":"Whl7XJgcOXCqU0VWITs48Q-1","X-Mimecast-MFC-AGG-ID":"Whl7XJgcOXCqU0VWITs48Q_1776882384","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776882384; x=1777487184;\n h=mime-version:references:message-id:in-reply-to:subject:cc:to:date\n :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=Qoa0eh4QSPNiVKFvdVIKvMTcMeBAaOZjatSMHRDhvXU=;\n b=idJ8N+v/yJV+VYEVtNhwTdJZ1R2/Tmmch+nQ9AsM8TiVIMe/Gx6cfrVfPzD0+L8fTQ\n ZDBj/m4uPT8Cqm3pESR1XqbW6eupfLmKAuTT2ujzXkgBU556WH6atGzi4rKZOdVLIUzL\n TJOVtmBXBfE9g4sBDcxW64VIg3mpuFvHsZ95SIqT4ozSs+hvPmp30JsfVlXwPdrgXeb4\n oWvOsjC5GTc5Sg6OjLgNwnnBae5IP2WwxD2eMJ/awYiuIghcaEIz6XLmzeW9mvwfahzJ\n MWhxvqOWZkdEgd07YW3Q9kHeRY/IfzeooPwDtZxLzpz8nrmXe5IJYz6dd4oZMOHH3+wM\n 5sKQ==","X-Forwarded-Encrypted":"i=1;\n AFNElJ+KIs9PwSpGAkfR4dHUmV5EZsuel70O0930Zv+NXH8gZoCMTegL9zvPm+aXaWD5DuUDxUclBfbNbpL7yA==@gcc.gnu.org","X-Gm-Message-State":"AOJu0Yx4+YqUOFlQTbwwClUFFz4UR410KDjFf6DCJAgDVKOUjGgYAdgr\n yZ1N1n5Wj9TQL+byNT0OGZv89Z1cLI6lm+fGia8Vq1nvG7Rjq023AssXEGWocmo3GB4EGGO3bOk\n Ue8PcorZwxZt51WAcwgtyrTvv7BmfvTueQDaPp7xQIS1KKmklhiu0+gzYXVQ=","X-Gm-Gg":"AeBDiesxKoxDVQ2C84GJiMvihRuAhJh6ckAC914Qy93ML23vu6d6q5YX6jDs5Yky/JV\n PzSRns1T61NfHAS3whgri7KzajnUjwjZlZhHPtY2drDnKPOMI4Dj+L9MSs2EsehsCJsd7MbKXgr\n lRvBepDTczPOG9g4n6Rid167jgfvM/GjUqbUwMx21bFh/mxFHo/+n6rR2YMHksk/NDqAp+nrhsX\n OMaq5nCEwoLuCeO6jD1BwCJtzz9qq6rFn80Bzww4exyl+gLgs/Ue9mgraSfANvbwKctoo8rPt8u\n 72llZ9HaSEy+LN5EUixs5evi0MkSDnxIIEQHqP7LgcjMjHlUNqE3/0PqV6lDczEwsSSFsdMWYld\n yeasw7Bbd80iDGrCdQ86DXZe42Heugl3VZM05DCzqnaMxLLWUOChnTl6MS0Hy17gT","X-Received":["by 2002:ac8:5e4b:0:b0:50d:aa1f:68be with SMTP id\n d75a77b69052e-50e36c1a80emr232779311cf.4.1776882383774;\n Wed, 22 Apr 2026 11:26:23 -0700 (PDT)","by 2002:ac8:5e4b:0:b0:50d:aa1f:68be with SMTP id\n d75a77b69052e-50e36c1a80emr232778741cf.4.1776882383127;\n Wed, 22 Apr 2026 11:26:23 -0700 (PDT)"],"From":"Patrick Palka <ppalka@redhat.com>","X-Google-Original-From":"Patrick Palka <patrick@idea>","Date":"Wed, 22 Apr 2026 14:26:21 -0400 (EDT)","To":"Patrick Palka <ppalka@redhat.com>","cc":"Marek Polacek <polacek@redhat.com>, GCC Patches <gcc-patches@gcc.gnu.org>,\n Jason Merrill <jason@redhat.com>","Subject":"Re: [PATCH v2] c++/reflection: reflect on dependent class template\n [PR124926]","In-Reply-To":"<16f7c127-f24e-692a-202d-092fa960020b@idea>","Message-ID":"<a633d6d5-dd36-d7e8-7a64-2b668a865353@idea>","References":"<20260422172510.801133-1-polacek@redhat.com>\n <0ee0590a-3c48-6588-dfdf-10ed0fd511fb@idea> <aekPzv3Jab_Gm0sk@redhat.com>\n <16f7c127-f24e-692a-202d-092fa960020b@idea>","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"uXlPSDWxDDTuvtJQnQezGXLt-PEEFxvUAQOoa1zkNdM_1776882384","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=US-ASCII","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"}},{"id":3680838,"web_url":"http://patchwork.ozlabs.org/comment/3680838/","msgid":"<aekTyNTihAbmix0t@redhat.com>","list_archive_url":null,"date":"2026-04-22T18:30:32","subject":"Re: [PATCH v2] c++/reflection: reflect on dependent class template\n [PR124926]","submitter":{"id":14370,"url":"http://patchwork.ozlabs.org/api/people/14370/","name":"Marek Polacek","email":"polacek@redhat.com"},"content":"On Wed, Apr 22, 2026 at 02:26:21PM -0400, Patrick Palka wrote:\n> On Wed, 22 Apr 2026, Patrick Palka wrote:\n> \n> > On Wed, 22 Apr 2026, Marek Polacek wrote:\n> > \n> > > On Wed, Apr 22, 2026 at 01:43:30PM -0400, Patrick Palka wrote:\n> > > > On Wed, 22 Apr 2026, Marek Polacek wrote:\n> > > > \n> > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?\n> > > > > \n> > > > > -- >8 --\n> > > > > Here we issue a bogus error for\n> > > > > \n> > > > >   ^^Cls<T>::template Inner\n> > > > > \n> > > > > where Inner turns out to be a class type, but we created a SCOPE_REF\n> > > > > because we can't know in advance what it will substitute into, and\n> > > > > \n> > > > >   ^^typename Cls<T>::template Inner\n> > > > > \n> > > > > is invalid.  The typename can only be used in\n> > > > > \n> > > > >   ^^typename Cls<T>::template Inner<int>\n> > > > > \n> > > > > We're taking a reflection so both types and non-types are valid, so\n> > > > > I think we shouldn't give the error for ^^, and take the reflection\n> > > > > of the TEMPLATE_DECL.\n> > > > > \n> > > > > \tPR c++/124926\n> > > > > \n> > > > > gcc/cp/ChangeLog:\n> > > > > \n> > > > > \t* pt.cc (tsubst_qualified_id): New bool parameter.  Don't give the\n> > > > > \t\"instantiation yields a type\" error when the new parameter is true.\n> > > > > \t(tsubst_expr) <case REFLECT_EXPR>: Adjust the call to\n> > > > > \ttsubst_qualified_id.\n> > > > > \n> > > > > gcc/testsuite/ChangeLog:\n> > > > > \n> > > > > \t* g++.dg/reflect/dep15.C: New test.\n> > > > > ---\n> > > > >  gcc/cp/pt.cc                         | 13 +++--\n> > > > >  gcc/testsuite/g++.dg/reflect/dep15.C | 85 ++++++++++++++++++++++++++++\n> > > > >  2 files changed, 94 insertions(+), 4 deletions(-)\n> > > > >  create mode 100644 gcc/testsuite/g++.dg/reflect/dep15.C\n> > > > > \n> > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc\n> > > > > index 5d97ca7997f..f73805b2557 100644\n> > > > > --- a/gcc/cp/pt.cc\n> > > > > +++ b/gcc/cp/pt.cc\n> > > > > @@ -18238,12 +18238,14 @@ tsubst_baselink (tree baselink, tree object_type,\n> > > > >     true if the qualified-id will be a postfix-expression in-and-of\n> > > > >     itself; false if more of the postfix-expression follows the\n> > > > >     QUALIFIED_ID.  ADDRESS_P is true if the qualified-id is the operand\n> > > > > -   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.  */\n> > > > > +   of \"&\".  NAME_LOOKUP_P is true if we intend to perform name lookup.\n> > > > > +   REFLECTING_P is true if this SCOPE_REF is an operand of ^^.  */\n> > > > >  \n> > > > >  static tree\n> > > > >  tsubst_qualified_id (tree qualified_id, tree args,\n> > > > >  \t\t     tsubst_flags_t complain, tree in_decl,\n> > > > > -\t\t     bool done, bool address_p, bool name_lookup_p = true)\n> > > > > +\t\t     bool done, bool address_p, bool name_lookup_p = true,\n> > > > > +\t\t     bool reflecting_p = false)\n> > > > >  {\n> > > > >    tree expr;\n> > > > >    tree scope;\n> > > > > @@ -18322,7 +18324,9 @@ tsubst_qualified_id (tree qualified_id, tree args,\n> > > > >        else\n> > > > >  \texpr = lookup_qualified_name (scope, expr, LOOK_want::NORMAL, false);\n> > > > >        if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL\n> > > > > -\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)\n> > > > > +\t\t     ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL\n> > > > > +\t  /* For ^^T::X, we'll take both types and non-types.  */\n> > > > > +\t  && !reflecting_p)\n> > > > >  \t{\n> > > > >  \t  if (complain & tf_error)\n> > > > >  \t    {\n> > > > > @@ -23355,7 +23359,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)\n> > > > >  \telse if (TREE_CODE (h) == SCOPE_REF)\n> > > > >  \t  h = tsubst_qualified_id (h, args, complain, in_decl,\n> > > > >  \t\t\t\t   /*done=*/true, /*address_p=*/false,\n> > > > > -\t\t\t\t   /*name_lookup_p=*/false);\n> > > > > +\t\t\t\t   /*name_lookup_p=*/false,\n> > > > > +\t\t\t\t   /*reflecting_p=*/true);\n> > > > \n> > > > Should we just merge name_lookup_p with reflecting_p at this point?\n> > > > More descriptive flag names are nice but having fewer flags is also nice :)\n> > > > And at first glance name_lookup_p doesn't seem precisely named, there\n> > > > are name lookup calls in tsubst_qualified_id that aren't suppressed by\n> > > > that flag (such as the ones immediately before the error in question).\n> > > \n> > > Yeah, that's a good point.  name_lookup_p was false only when called from\n> > > tsubst_expr/REFLECT_EXPR anyway.  So I think we should indeed merge them\n> > > as you suggest.\n> > > \n> > > dg.exp passed so far, ok for 17?\n> > \n> > OK\n\nThanks.\n \n> And OK for 16.2, I reckon reflection-only fixes are fair game for\n> backporting.\n\nYeah, I would definitely like to fix this in 16.2 as well since it's\nrejects-valid.\n\nMarek","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=LpIEWjqb;\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=LpIEWjqb","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 4g17ZK5R8sz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 04:50:01 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id E992241F9E26\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 18:49:59 +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 9AAAA4331BD1\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 18:30:59 +0000 (GMT)","from mail-qv1-f70.google.com (mail-qv1-f70.google.com\n [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-676-X-w5pomPMvaDH0QFrY0gIg-1; Wed, 22 Apr 2026 14:30:58 -0400","by mail-qv1-f70.google.com with SMTP id\n 6a1803df08f44-8abd6e281c0so146786656d6.1\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 11:30:57 -0700 (PDT)","from redhat.com ([2603:7002:1f00:31d2::1db4])\n by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8b02ac462d9sm139872976d6.7.2026.04.22.11.30.34\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 22 Apr 2026 11:30:34 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org E992241F9E26","OpenDKIM Filter v2.11.0 sourceware.org 9AAAA4331BD1"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 9AAAA4331BD1","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 9AAAA4331BD1","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776882659; cv=none;\n b=gcrBZ1Sj55fLmjwUsASQgUgQndjed4XPL4ujXa1HOIbvojt1TRBd6VXFbFvQgaZy2pdlcQcZc5PvOHdAc0yNdj/6tfkBYwwNxRcTqf4gLpZMvPrvtOh0ASefvBUf+lwLLdW8V9uXOID6yJowzLDTmlQeQ+wyFf/SDcsnMOItizg=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776882659; c=relaxed/simple;\n bh=lwgJ/V+XcFBBGxMPYkvQjjM4idhM/NMiJMNEtU3eXIg=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=k59grXlceir7fomS9+7+hgnwyHsShbIjplYilk50QhklbIAD8FM8NQVof9psnPbyO+dAcgc9cg6p38pE0W4neLirshedxqBYLwoVTQSdQIyWvug0jO3Khw3b2/PH/QwAdeGjTIot8huFOKt8FJHtA2FnffwFpgsk1y/1islChvg=","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=1776882659;\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 in-reply-to:in-reply-to:references:references;\n bh=S4kbC91iLRPJ98E4IJiS0I1Y4x89cu75RIdC8Mz4KYI=;\n b=LpIEWjqbinhk7xef22gdkcivSo/E1A+hmstQhnC7DpYRt/2g34JnKAnzjAygPyhbu/uJMf\n 6gf9jWi3ogpSXjThNaqH8hAKheiqhbwFC/N/WlWcq2FzxEcCT7lQaO++oJAqjXRK4bcUPr\n od2cvmpctP7uT9LryuF3lDhzGgblwfE=","X-MC-Unique":"X-w5pomPMvaDH0QFrY0gIg-1","X-Mimecast-MFC-AGG-ID":"X-w5pomPMvaDH0QFrY0gIg_1776882657","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776882657; x=1777487457;\n h=user-agent:in-reply-to:content-disposition:mime-version:references\n :message-id:subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=S4kbC91iLRPJ98E4IJiS0I1Y4x89cu75RIdC8Mz4KYI=;\n b=b36RZf+35m9bAUsVuYVnklxmeUrHc8wDL03Zh6zF76Iv4RNPD8MrZ8EC3JbtRGy3T/\n 39d0bxjbbi4wchzy+QhXZuRKyKfVvOZNr/1YMnjCpBKnp6AIxW2of7t/BTKICHJgwmqE\n p2QQl38IZ1DwAPofFN/nMkUIBJo4kXT42KDgKXCzpaWEIpQj175lVIN3LczttMFo8Tko\n KM4NF0Dv15GFgbZM3evjPCZToBQxnmlYk1E2dEkXkNYT2gd1vCnCOCUKEdQEyYdvhgyd\n xEKeSXaWNGHFebkLBnS5FyQ5xTfaMaQZ3oBu0oTJzu/ZD3nEw/a3VyuJ+vAlBRzB+YLP\n 23Ow==","X-Gm-Message-State":"AOJu0Yx5Rs4TCSKhlRABBsf21htXhRQRjQ9v+cWjABPIRsgosK00juOF\n yNYjWZat4ZfQqvFFVlacONG4dYTEkORMXNex6RhIPDJY+jGEmfsbBjI1Adm03y8a2YdS7ssB9Y0\n gcZvnKUqcCl19GCmMYgwXBr8GUqxZ5QpolNRFeRwN3cIgA9fIiKPPfu47KTk=","X-Gm-Gg":"AeBDieu+f5lZnM6C52ortyvbTWx0hPple127McXbOUEJufx6pPCfBEUmY6klqlpZRHp\n YJo3kRqzl+0Cq+5Rw5Dhw8MccVK//1PwZDa+EJzu9bobvROazYmcrQTLJ9tElIzHsfSUWstd+l/\n xik9CjLFUeqHImJmad9blUGJWaoRKNMxNrChxJ3PVZHV0KWmP1ZNgzgSUGRs30Rl9bgwQ700uB5\n iDLX0j7ZaOeOmFVm90nJmINz/8A+zrm4b7GRggwbdSVvmqywcqoL8BHKb1BD9u114+UgIC+Y8kz\n 7WcBaMx0uJZkgCBM14gOTFlg5sYOq4ThoTxhH6+0+XEXjuPNtbyN+mkgmj1V5dPlOdbZgYz0t2P\n QWEfvsLowJHGca7Y=","X-Received":["by 2002:a05:6214:1ccf:b0:8ac:b402:9ae2 with SMTP id\n 6a1803df08f44-8b03addd7d1mr293515966d6.4.1776882645431;\n Wed, 22 Apr 2026 11:30:45 -0700 (PDT)","by 2002:a05:6214:1ccf:b0:8ac:b402:9ae2 with SMTP id\n 6a1803df08f44-8b03addd7d1mr293494726d6.4.1776882634918;\n Wed, 22 Apr 2026 11:30:34 -0700 (PDT)"],"Date":"Wed, 22 Apr 2026 14:30:32 -0400","From":"Marek Polacek <polacek@redhat.com>","To":"Patrick Palka <ppalka@redhat.com>","Cc":"GCC Patches <gcc-patches@gcc.gnu.org>, Jason Merrill <jason@redhat.com>","Subject":"Re: [PATCH v2] c++/reflection: reflect on dependent class template\n [PR124926]","Message-ID":"<aekTyNTihAbmix0t@redhat.com>","References":"<20260422172510.801133-1-polacek@redhat.com>\n <0ee0590a-3c48-6588-dfdf-10ed0fd511fb@idea>\n <aekPzv3Jab_Gm0sk@redhat.com>\n <16f7c127-f24e-692a-202d-092fa960020b@idea>\n <a633d6d5-dd36-d7e8-7a64-2b668a865353@idea>","MIME-Version":"1.0","In-Reply-To":"<a633d6d5-dd36-d7e8-7a64-2b668a865353@idea>","User-Agent":"Mutt/2.3.1 (2026-03-20)","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"WFPUCwS1NCA5ydJLYeIKwAosfPReOQAS_-2mq2H9pwg_1776882657","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>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]