From 2fa586ad989926559871b01f9825e0adfe9fd186 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 7 Dec 2015 14:34:11 -0500 Subject: [PATCH] re PR c++/68464 (ICE in valid constexpr function: ../../src/gcc/tree.c:11497) PR c++/68464 * cp-gimplify.c (cp_fold): Don't assume X has TREE_TYPE. (cp_genericize): Don't do cp_fold_r here. (cp_fold_function): New. * cp-tree.h: Declare it. * decl.c (finish_function): Call it and the pre-genericize plugin before NRV processing. From-SVN: r231381 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/cp-gimplify.c | 17 +++++++++++------ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 9 ++++++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7c045e3ab26..5232534dfd8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2015-12-07 Jason Merrill + PR c++/68464 + * cp-gimplify.c (cp_fold): Don't assume X has TREE_TYPE. + (cp_genericize): Don't do cp_fold_r here. + (cp_fold_function): New. + * cp-tree.h: Declare it. + * decl.c (finish_function): Call it and the pre-genericize plugin + before NRV processing. + PR c++/68170 * pt.c (maybe_new_partial_specialization): The injected-class-name is not a new partial specialization. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 177e2717aa5..373c9e11aec 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -991,6 +991,15 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) return NULL; } +/* Fold ALL the trees! FIXME we should be able to remove this, but + apparently that still causes optimization regressions. */ + +void +cp_fold_function (tree fndecl) +{ + cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, NULL, NULL); +} + /* Perform any pre-gimplification lowering of C++ front end trees to GENERIC. */ @@ -1475,10 +1484,6 @@ cp_genericize (tree fndecl) { tree t; - /* Fold ALL the trees! FIXME we should be able to remove this, but - apparently that still causes optimization regressions. */ - cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, NULL, NULL); - /* Fix up the types of parms passed by invisible reference. */ for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t)) if (TREE_ADDRESSABLE (TREE_TYPE (t))) @@ -1936,11 +1941,11 @@ cp_fold (tree x) location_t loc; bool rval_ops = true; - if (!x || error_operand_p (x)) + if (!x || x == error_mark_node) return x; if (processing_template_decl - || (EXPR_P (x) && !TREE_TYPE (x))) + || (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))) return x; /* Don't bother to cache DECLs or constants. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 1b2563d00ee..6190f4ed0e5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6812,6 +6812,7 @@ extern tree cxx_omp_clause_dtor (tree, tree); extern void cxx_omp_finish_clause (tree, gimple_seq *); extern bool cxx_omp_privatize_by_reference (const_tree); extern bool cxx_omp_disregard_value_expr (tree, bool); +extern void cp_fold_function (tree); extern tree cp_fully_fold (tree); /* in name-lookup.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0af7bd49224..62636c9eefa 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14580,6 +14580,14 @@ finish_function (int flags) the NRV transformation. */ maybe_save_function_definition (fndecl); + /* Invoke the pre-genericize plugin before we start munging things. */ + if (!processing_template_decl) + invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); + + /* Perform delayed folding before NRV transformation. */ + if (!processing_template_decl) + cp_fold_function (fndecl); + /* Set up the named return value optimization, if we can. Candidate variables are selected in check_return_expr. */ if (current_function_return_value) @@ -14686,7 +14694,6 @@ finish_function (int flags) if (!processing_template_decl) { struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl); - invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl); cp_genericize (fndecl); /* Clear out the bits we don't need. */ f->x_current_class_ptr = NULL; -- 2.30.2