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