https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89285
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ah, so one problem is that while we save the inline bodies of functions before cp_fold_function, cp_fold_function is destructive and clobbers the saved copy. cp_fold itself is (hopefully) not destructive and creates new trees, but cp_fold_function is destructive and happily modifies the trees shared with something else (in this case with the constexpr funcdef table). One way out of this is throwing away cp_fold_r/cp_fold_function and teaching cp_fold to handle all the trees that cp_walk_tree can walk (dunno if we want to cache everything or not). That means handling e.g. STATEMENT_LIST, BIND_EXPR, *_STMT etc. Another possibility is to use cp_fold_r the way it is for non-constexpr functions, and for constexpr functions use instead a hand written walker that will handle everything that can appear in constexpr functions with copy on write behavior, say if it is processing a STATEMENT_LIST and determines a recursive call wants to fold one of the statements, unshare the whole STATEMENT_LIST, modify it on the copy (and the parent would notice and unshare etc.). Yet another possibility is to use the inliner's copy_tree_body_r for this in register_constexpr_fundef, but in a way that we don't create new decls. I'm afraid it would still create new VLA types, can those appear in constexpr functions? Jason, any preferences here? Note, the above would fix the [9 Regression] part of this PR, that we don't reject that #c4 testcase. We'd still need to figure out a fix for the [8 Regression] part that once this [9 Regression] part is fixed would become [8/9 Regression]. I guess it could fix various other accepts-invalid cases where the cp_folding which modifies the saved tree makes us accept invalid constexpr code.