On Tue, Jan 23, 2018 at 1:06 PM, David Malcolm <dmalc...@redhat.com> wrote:
> On Tue, 2018-01-23 at 09:54 -0500, Jason Merrill wrote:
>> On Tue, Jan 23, 2018 at 9:27 AM, David Malcolm <dmalc...@redhat.com>
>> wrote:
>> > PR c++/83974 reports an ICE within fold_for_warn when calling
>> > cxx_eval_constant_expression on a CAST_EXPR.
>> >
>> > This comes from a pointer-to-member-function.  The result of
>> > build_ptrmemfunc (within cp_convert_to_pointer for a null ptr) is
>> > a CONSTRUCTOR containing, amongst other things a CAST_EXPR of a
>> > TREE_LIST containing the zero INTEGER_CST.
>> >
>> > After r256804, fold_for_warn within a template calls
>> > fold_non_dependent_expr.
>> >
>> > For this tree, is_nondependent_constant_expression returns true.
>> >
>> > potential_constant_expression_1 has these cases:
>> >
>> >     case TREE_LIST:
>> >       {
>> >         gcc_assert (TREE_PURPOSE (t) == NULL_TREE
>> >                     || DECL_P (TREE_PURPOSE (t)));
>> >         if (!RECUR (TREE_VALUE (t), want_rval))
>> >           return false;
>> >         if (TREE_CHAIN (t) == NULL_TREE)
>> >           return true;
>> >         return RECUR (TREE_CHAIN (t), want_rval);
>> >       }
>> >
>> > and:
>> >
>> >     case CAST_EXPR:
>> >     case CONST_CAST_EXPR:
>> >     case STATIC_CAST_EXPR:
>> >     case REINTERPRET_CAST_EXPR:
>> >     case IMPLICIT_CONV_EXPR:
>> >       if (cxx_dialect < cxx11
>> >           && !dependent_type_p (TREE_TYPE (t))
>> >           && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)))
>> >         /* In C++98, a conversion to non-integral type can't be
>> > part of a
>> >            constant expression.  */
>> >           {
>> >           // reject it
>> >           }
>> >         // accept it
>> >
>> > and thus returns true for the CAST_EXPR and TREE_LIST, and hence
>> > for the
>> > CONSTRUCTOR as a whole.
>> >
>> > However, cxx_eval_constant_expression does not support these tree
>> > codes,
>>
>> Because they are template-only codes, that
>> cxx_eval_constant_expression should never see.  They shouldn't
>> survive
>> the call to instantiate_non_dependent_expr_internal from
>> fold_non_dependent_expr.
>>
>> Jason
>
> Aha - thanks.
>
> instantiate_non_dependent_expr_internal calls tsubst_copy_and_build, and
> tsubst_copy_and_build is bailing out here:
>
> 18103           /* digest_init will do the wrong thing if we let it.  */
> 18104           if (type && TYPE_PTRMEMFUNC_P (type))
> 18105             RETURN (t);
>
> leaving the CONSTRUCTOR uncopied, and thus containing the CAST_EXPR and
> TREE_LIST, leading to the ICE within cxx_eval_constant_expression.

Wow, how has that not broken things before now?

The patch is OK.

Jason

Reply via email to