On Thu, Dec 12, 2024 at 3:29 PM Patrick Palka <ppa...@redhat.com> wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk/14?
Ping. > > This fixes the testcase in the PR but doesn't thoroughly fix the > underlying issue since if we replace fnPtr with e.g. a constexpr variable > so that the callee is truly potentially constant then the ICE reappears > (due to encountering CAST_EXPR during constexpr evaluation from > maybe_warn_nodiscard), but with the previous patch this should now only > happen in checking mode. I suspect a call to fold_non_dependent_expr is > missing, but I'm not sure where would be best to put it. > > -- >8 -- > > We're incorrectly treating the templated callee (FnPtr)fnPtr, represented > as CAST_EXPR of TREE_LIST, as potentially constant here due to failing > to look through the TREE_LIST in the CAST_EXPR case of p_c_e_1. > > PR c++/117925 > > gcc/cp/ChangeLog: > > * constexpr.cc (potential_constant_expression_1) <case CAST_EXPR>: > Fix check for class conversion to literal type to properly look > through the TREE_LIST operand of a CAST_EXPR. > > gcc/testsuite/ChangeLog: > > * g++.dg/template/non-dependent35.C: New test. > --- > gcc/cp/constexpr.cc | 11 ++++++++--- > gcc/testsuite/g++.dg/template/non-dependent35.C | 8 ++++++++ > 2 files changed, 16 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/template/non-dependent35.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index 221d57f6ffa..cda49008f81 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -10262,9 +10262,14 @@ potential_constant_expression_1 (tree t, bool > want_rval, bool strict, bool now, > && (dependent_type_p (TREE_TYPE (t)) > || !COMPLETE_TYPE_P (TREE_TYPE (t)) > || literal_type_p (TREE_TYPE (t))) > - && TREE_OPERAND (t, 0)) > - { > - tree type = TREE_TYPE (TREE_OPERAND (t, 0)); > + && TREE_OPERAND (t, 0) > + && (TREE_CODE (t) != CAST_EXPR > + || !TREE_CHAIN (TREE_OPERAND (t, 0)))) > + { > + tree from = TREE_OPERAND (t, 0); > + if (TREE_CODE (t) == CAST_EXPR) > + from = TREE_VALUE (from); > + tree type = TREE_TYPE (from); > /* If this is a dependent type, it could end up being a class > with conversions. */ > if (type == NULL_TREE || WILDCARD_TYPE_P (type)) > diff --git a/gcc/testsuite/g++.dg/template/non-dependent35.C > b/gcc/testsuite/g++.dg/template/non-dependent35.C > new file mode 100644 > index 00000000000..7e3ba99b023 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/non-dependent35.C > @@ -0,0 +1,8 @@ > +// PR c++/117925 > + > +typedef int(*FnPtr)(); > + > +template<class T> > +void fnICE(void* fnPtr) { > + ((FnPtr)fnPtr)(); > +} > -- > 2.47.1.440.gcaacdb5dfd >