re PR c++/68464 (ICE in valid constexpr function: ../../src/gcc/tree.c:11497)
authorJason Merrill <jason@redhat.com>
Mon, 7 Dec 2015 19:34:11 +0000 (14:34 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 7 Dec 2015 19:34:11 +0000 (14:34 -0500)
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
gcc/cp/cp-gimplify.c
gcc/cp/cp-tree.h
gcc/cp/decl.c

index 7c045e3ab269699d2d385975d75461e29ff53910..5232534dfd891b519af8a1bdc15dfcb7b21dc33d 100644 (file)
@@ -1,5 +1,13 @@
 2015-12-07  Jason Merrill  <jason@redhat.com>
 
+       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.
index 177e2717aa5e6a19320319d1b7b90d4dd5f8559c..373c9e11aecbb23ac9447272adfb506955edbbb4 100644 (file)
@@ -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.  */
index 1b2563d00ee00449219b1ed3590ccb6429cb3535..6190f4ed0e52f5d9174e561acadaf6abce1311d3 100644 (file)
@@ -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 */
index 0af7bd49224e76f56af3d370c2c0bd8db953bbc5..62636c9eefaed72def3ec29d6b5950b0711ed0af 100644 (file)
@@ -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;