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
>

Reply via email to