On Fri, Oct 23, 2026 at 01:36:21PM -0400, Jason Merrill wrote:
> On 10/23/26 9:27 AM, Marek Polacek wrote:
> > On Tue, Oct 20, 2026 at 06:08:54PM -0400, Jason Merrill wrote:
> > > On 10/8/26 5:26 PM, Marek Polacek wrote:
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > 
> > > > -- >8 --
> > > > [expr.prim.splice]/2 doesn't actually allow templates in
> > > > a splice-expression of the form splice-specifier, but we are not
> > > > currently detecting that in check_splice_expr, which can mean
> > > > that we crash if the user attempts to use such a splice.
> > > > 
> > > > As an extension, we allow function templates, and assume that the
> > > > user forgot to type 'template'.
> > > 
> > > Do we still give a diagnostic by default in that case?
> > 
> > No, the missing "expected template keyword" is subject of PR127802.
> 
> We could give that diagnostic here?

Yes, that was my plan.  I thought I'd do it in a follow-up patch in
case it gets messy.  This one was just supposed to fix the ICE.  But
if you want both in the same patch, I could do that.
 
> > > > mangle3.C was testing invalid cases so remove that.
> > > > 
> > > >         PR c++/125631
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > >         * reflect.cc (check_splice_expr): Reject (non-function) 
> > > > templates.
> > > > 
> > > > gcc/testsuite/ChangeLog:
> > > > 
> > > >         * g++.dg/reflect/crash6.C: Adjust dg-error.
> > > >         * g++.dg/reflect/mangle3.C: Remove some invalid tests.
> > > >         * g++.dg/reflect/error15.C: New test.
> > > > ---
> > > >    gcc/cp/reflect.cc                      | 15 +++++
> > > >    gcc/testsuite/g++.dg/reflect/crash6.C  |  4 +-
> > > >    gcc/testsuite/g++.dg/reflect/error15.C | 84 
> > > > ++++++++++++++++++++++++++
> > > >    gcc/testsuite/g++.dg/reflect/mangle3.C |  9 ---
> > > >    4 files changed, 101 insertions(+), 11 deletions(-)
> > > >    create mode 100644 gcc/testsuite/g++.dg/reflect/error15.C
> > > > 
> > > > diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
> > > > index 8bf518df64f..62c4e168108 100644
> > > > --- a/gcc/cp/reflect.cc
> > > > +++ b/gcc/cp/reflect.cc
> > > > @@ -9362,6 +9362,21 @@ check_splice_expr (location_t loc, location_t 
> > > > start_loc, tree t,
> > > >          return false;
> > > >        }
> > > > +  /* [expr.prim.splice]/2 doesn't allow for the splice-expression of 
> > > > the form
> > > > +     splice-specifier to designate a template.  But we accept a 
> > > > function
> > > > +     template here as an extension, because it would be valid if the 
> > > > 'template'
> > > > +     keyword were present.  */
> > > > +  if (!template_p
> > > > +      && !targs_p
> > > > +      && !member_access_p
> > > > +      && TREE_CODE (t) == TEMPLATE_DECL
> > > > +      && !DECL_FUNCTION_TEMPLATE_P (t))
> > > > +    {
> > > > +      if (complain_p)
> > > > +       error_at (loc, "cannot use template %qE in a splice 
> > > > expression", t);
> > > > +      return false;
> > > > +    }
> > > > +
> > > >      /* [expr.prim.splice]/2: "The expression is ill-formed if S [the 
> > > > construct
> > > >         designated by splice-specifier] is
> > > >         -- a local entity such that there is a lambda scope that 
> > > > intervenes
> > > > diff --git a/gcc/testsuite/g++.dg/reflect/crash6.C 
> > > > b/gcc/testsuite/g++.dg/reflect/crash6.C
> > > > index a455a61cd65..4dd2f5fc7b8 100644
> > > > --- a/gcc/testsuite/g++.dg/reflect/crash6.C
> > > > +++ b/gcc/testsuite/g++.dg/reflect/crash6.C
> > > > @@ -10,8 +10,8 @@ template<info R>
> > > >    void
> > > >    f ()
> > > >    {
> > > > -  [:R:] r; // { dg-error "expected" }
> > > > -  [:R:]<int> r; // { dg-error "expected" }
> > > > +  [:R:] r; // { dg-error "expected|cannot use template" }
> > > > +  [:R:]<int> r; // { dg-error "expected|cannot use template" }
> > > >    }
> > > >    void
> > > > diff --git a/gcc/testsuite/g++.dg/reflect/error15.C 
> > > > b/gcc/testsuite/g++.dg/reflect/error15.C
> > > > new file mode 100644
> > > > index 00000000000..a2fdf4a52ed
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/g++.dg/reflect/error15.C
> > > > @@ -0,0 +1,84 @@
> > > > +// PR c++/125631
> > > > +// { dg-do compile { target c++26 } }
> > > > +// { dg-additional-options "-freflection" }
> > > > +
> > > > +#include <tuple>
> > > > +
> > > > +template<auto Templ, class Tuple>
> > > > +const auto
> > > > +make_from_tuple (Tuple&& t)
> > > > +{
> > > > +  return [:Templ:]{}; // { dg-error "expected|cannot use template 
> > > > .std::tuple. in a splice expression" }
> > > > +}
> > > > +auto p = make_from_tuple<^^std::tuple>(std::tuple());
> > > > +
> > > > +template<auto N> int tv;
> > > > +template<auto N> concept C = requires { true; };
> > > > +template<typename T> struct S { };
> > > > +template<typename T>
> > > > +using A = S<T>;
> > > > +template<typename> using I = int;
> > > > +
> > > > +template<auto R>
> > > > +void
> > > > +g1 ()
> > > > +{
> > > > +  auto a = [:R:];  // { dg-error "cannot use template .tv<N>. in a 
> > > > splice expression" }
> > > > +}
> > > > +
> > > > +template<auto R>
> > > > +void
> > > > +g2 ()
> > > > +{
> > > > +  auto a = [:R:];  // { dg-error "cannot use template .C. in a splice 
> > > > expression" }
> > > > +}
> > > > +
> > > > +template<auto R>
> > > > +void
> > > > +g3 ()
> > > > +{
> > > > +  auto a = [:R:];  // { dg-error "cannot use template .S. in a splice 
> > > > expression" }
> > > > +}
> > > > +
> > > > +template<auto R>
> > > > +void
> > > > +g4 ()
> > > > +{
> > > > +  auto a = [:R:];  // { dg-error "cannot use template .A. in a splice 
> > > > expression" }
> > > > +}
> > > > +
> > > > +template<auto R>
> > > > +void
> > > > +g5 ()
> > > > +{
> > > > +  auto a = [:R:];  // { dg-error "cannot use template .I. in a splice 
> > > > expression" }
> > > > +}
> > > > +
> > > > +template<template<class> class TT>
> > > > +void
> > > > +g6 ()
> > > > +{
> > > > +  auto x = [:^^TT:];  // { dg-error "cannot use template .S. in a 
> > > > splice expression" }
> > > > +}
> > > > +
> > > > +template<auto R>
> > > > +void
> > > > +g7 ()
> > > > +{
> > > > +  &[:R:];  // { dg-error "cannot use template .S. in a splice 
> > > > expression" }
> > > > +}
> > > > +
> > > > +template<auto R> auto g8 () -> decltype([:R:]);        // { dg-error 
> > > > "cannot use template .tv<N>. in a splice expression" }
> > > > +
> > > > +void
> > > > +h ()
> > > > +{
> > > > +  g1<^^tv>();
> > > > +  g2<^^C>();
> > > > +  g3<^^S>();
> > > > +  g4<^^A>();
> > > > +  g5<^^I>();
> > > > +  g6<S>();
> > > > +  g7<^^S>();
> > > > +  g8<^^tv>(); // { dg-error "no matching function" }
> > > > +}
> > > > diff --git a/gcc/testsuite/g++.dg/reflect/mangle3.C 
> > > > b/gcc/testsuite/g++.dg/reflect/mangle3.C
> > > > index 390f249fb0c..1e1302d1377 100644
> > > > --- a/gcc/testsuite/g++.dg/reflect/mangle3.C
> > > > +++ b/gcc/testsuite/g++.dg/reflect/mangle3.C
> > > > @@ -15,8 +15,6 @@ using Alias = int;
> > > >    template<auto>
> > > >    struct TCls { };
> > > > -template <auto> int TVar;
> > > > -
> > > >    template<typename T>
> > > >    struct B {
> > > >      T t;
> > > > @@ -41,7 +39,6 @@ namespace N {
> > > >    }
> > > >    namespace NSAlias = N;
> > > > -template <auto> concept Concept = requires { true; };
> > > >    constexpr auto ctx = std::meta::access_context::current ();
> > > >    template<typename T>
> > > > @@ -160,18 +157,12 @@ g (int p)
> > > >    // { dg-final { scan-assembler "_Z2f4ILDmsb2a1EE4TClsIXszDST_EEEv" } 
> > > > }
> > > >      f4<^^A>();
> > > >    // { dg-final { scan-assembler 
> > > > "_Z2f4ILDmen4Enum1AEE4TClsIXszDST_EEEv" } }
> > > > -  f4<^^TVar>();
> > > > -// { dg-final { scan-assembler "_Z2f4ILDmvt4TVarEE4TClsIXszDST_EEEv" } 
> > > > }
> > > >      f5<^^i>();
> > > >    // { dg-final { scan-assembler "_Z2f5ILDmvr1iEEDtDST_EEv" } }
> > > >      f5<^^a1>();
> > > >    // { dg-final { scan-assembler "_Z2f5ILDmsb2a1EEDtDST_EEv" } }
> > > >      f5<^^A>();
> > > >    // { dg-final { scan-assembler "_Z2f5ILDmen4Enum1AEEDtDST_EEv" } }
> > > > -  f5<^^TVar>();
> > > > -// { dg-final { scan-assembler "_Z2f5ILDmvt4TVarEEDtDST_EEv" } }
> > > > -  f5<^^Concept>();
> > > > -// { dg-final { scan-assembler "_Z2f5ILDmco7ConceptEEDtDST_EEv" } }
> > > >      f5<^^p>();
> > > >    // { dg-final { scan-assembler "_Z2f5ILDmvrZ1giE1pEEDtDST_EEv" } }
> > > >      f5<std::meta::reflect_constant (42)>();
> > > > 
> > > > base-commit: 9b2bbe9104aef2e6bd9e8d7ace5fed3e2726f4d3

Marek

Reply via email to