Re: [PATCH] c++: ICE w/ maybe_warn_nodiscard on non-dep call [PR123495, PR126860]
Patrick Palka <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <920b3512-e733-8221-3ca8-91162628f515@idea> |
On Fri, 14 Aug 2026, Marek Polacek wrote:
> On Fri, Aug 14, 2026 at 12:22:55PM -0400, Patrick Palka wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
> > for trunk? It's a checking-only ICE so no big need to backport,
> > maybe to 16 at most.
> >
> > -- >8 --
> >
> > Another latent issue uncovered by the NON_DEPENDENT_EXPR removal.
> > cp_get_fndecl_from_callee, called from maybe_warn_nodiscard, tries to
> > fold the templated callee via constant evaluation, but constant
> > evaluation expects non-templated trees. So use fold_non_dependent_expr
> > which instantiates templated trees beforehand.
> >
> > PR c++/123495
> > PR c++/126860
> >
> > gcc/cp/ChangeLog:
> >
> > * cvt.cc (cp_get_fndecl_from_callee): Use fold_non_dependent_expr
> > instead of maybe_constant_init.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/template/non-dependent36.C: New test.
> > * g++.dg/template/non-dependent37.C: New test.
> > ---
> > gcc/cp/cvt.cc | 2 +-
> > gcc/testsuite/g++.dg/template/non-dependent36.C | 4 ++++
> > gcc/testsuite/g++.dg/template/non-dependent37.C | 9 +++++++++
> > 3 files changed, 14 insertions(+), 1 deletion(-)
> > create mode 100644 gcc/testsuite/g++.dg/template/non-dependent36.C
> > create mode 100644 gcc/testsuite/g++.dg/template/non-dependent37.C
> >
> > diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
> > index a378b51a2bed..33d528b3c324 100644
> > --- a/gcc/cp/cvt.cc
> > +++ b/gcc/cp/cvt.cc
> > @@ -1069,7 +1069,7 @@ cp_get_fndecl_from_callee (tree fn, bool fold /* = true */)
> > if (type == NULL_TREE || !INDIRECT_TYPE_P (type))
> > return NULL_TREE;
> > if (fold)
> > - fn = maybe_constant_init (fn);
> > + fn = fold_non_dependent_expr (fn);
>
> Since this is _init, I would expect fold_non_dependent_init.
> Was _expr a deliberate choice?
Ah I forgot about fold_non_dependent_init, so I defaulted to _expr,
but if I knew about it I would use _init for sake of consistency.
Testing that now. I'm not sure why we use _init here in the
first place though, maybe Jason knows?
>
> > STRIP_NOPS (fn);
> > if (TREE_CODE (fn) == ADDR_EXPR
> > || TREE_CODE (fn) == FDESC_EXPR)
> > diff --git a/gcc/testsuite/g++.dg/template/non-dependent36.C b/gcc/testsuite/g++.dg/template/non-dependent36.C
> > new file mode 100644
> > index 000000000000..a4bf06974028
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/non-dependent36.C
> > @@ -0,0 +1,4 @@
> > +// PR c++/123495
> > +
> > +template <int N>
> > +void foo () { ((int (*) ()) 0) (); }
> > diff --git a/gcc/testsuite/g++.dg/template/non-dependent37.C b/gcc/testsuite/g++.dg/template/non-dependent37.C
> > new file mode 100644
> > index 000000000000..ad58cf6f10ce
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/non-dependent37.C
> > @@ -0,0 +1,9 @@
> > +// PR c++/126860
> > +
> > +struct A {
> > + int (*foo)();
> > +};
> > +
> > +template <typename T> struct S : public A {
> > + void bar() { A::foo(); }
> > +};
> > --
> > 2.55.0.559.g11c6700f10
> >
>
> Marek
>
>