re PR c++/60992 (ICE in tsubst_copy, at cp/pt.c:12637)
authorJason Merrill <jason@redhat.com>
Fri, 30 May 2014 15:09:40 +0000 (11:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 30 May 2014 15:09:40 +0000 (11:09 -0400)
PR c++/60992
* pt.c (tsubst_init): Split out from...
(tsubst_expr) [DECL_EXPR]: Here.
(tsubst_copy) [VAR_DECL]: Use it.
* semantics.c (finish_id_expression): Return the decl for static/const.

From-SVN: r211084

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/semantics.c

index dbcd3c6ddf8da83382c24cdf8ee189e4e3d7ad97..b3138014f4486d91965ea17a88474f8e4ed0c6e5 100644 (file)
@@ -1,3 +1,11 @@
+2014-05-30  Jason Merrill  <jason@redhat.com>
+
+       PR c++/60992
+       * pt.c (tsubst_init): Split out from...
+       (tsubst_expr) [DECL_EXPR]: Here.
+       (tsubst_copy) [VAR_DECL]: Use it.
+       * semantics.c (finish_id_expression): Return the decl for static/const.
+
 2014-05-28  Jason Merrill  <jason@redhat.com>
 
        PR c++/47202
index 0b3cd7f4e510d1b93c8e8bc37894a9699acc925b..a24e0443c9ffb014ef4c995ad89d46fe7b18af5a 100644 (file)
@@ -12513,6 +12513,37 @@ tsubst_qualified_id (tree qualified_id, tree args,
   return expr;
 }
 
+/* tsubst the initializer for a VAR_DECL.  INIT is the unsubstituted
+   initializer, DECL is the substituted VAR_DECL.  Other arguments are as
+   for tsubst.  */
+
+static tree
+tsubst_init (tree init, tree decl, tree args,
+            tsubst_flags_t complain, tree in_decl)
+{
+  if (!init)
+    return NULL_TREE;
+
+  init = tsubst_expr (init, args, complain, in_decl, false);
+
+  if (!init)
+    {
+      /* If we had an initializer but it
+        instantiated to nothing,
+        value-initialize the object.  This will
+        only occur when the initializer was a
+        pack expansion where the parameter packs
+        used in that expansion were of length
+        zero.  */
+      init = build_value_init (TREE_TYPE (decl),
+                              complain);
+      if (TREE_CODE (init) == AGGR_INIT_EXPR)
+       init = get_target_expr_sfinae (init, complain);
+    }
+
+  return init;
+}
+
 /* Like tsubst, but deals with expressions.  This function just replaces
    template parms; to finish processing the resultant expression, use
    tsubst_copy_and_build or tsubst_expr.  */
@@ -12670,11 +12701,34 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                     local static or constant.  Building a new VAR_DECL
                     should be OK in all those cases.  */
                  r = tsubst_decl (t, args, complain);
-                 if (decl_constant_var_p (r))
-                   /* A use of a local constant must decay to its value.  */
-                   return integral_constant_value (r);
+                 if (decl_maybe_constant_var_p (r))
+                   {
+                     /* We can't call cp_finish_decl, so handle the
+                        initializer by hand.  */
+                     tree init = tsubst_init (DECL_INITIAL (t), r, args,
+                                              complain, in_decl);
+                     if (!processing_template_decl)
+                       init = maybe_constant_init (init);
+                     if (processing_template_decl
+                         ? potential_constant_expression (init)
+                         : reduced_constant_expression_p (init))
+                       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
+                         = TREE_CONSTANT (r) = true;
+                     DECL_INITIAL (r) = init;
+                   }
                  gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
+                             || decl_constant_var_p (r)
                              || errorcount || sorrycount);
+                 if (!processing_template_decl)
+                   {
+                     if (TREE_STATIC (r))
+                       rest_of_decl_compilation (r, toplevel_bindings_p (),
+                                                 at_eof);
+                     else if (decl_constant_var_p (r))
+                       /* A use of a local constant decays to its value.
+                          FIXME update for core DR 696.  */
+                       return integral_constant_value (r);
+                   }
                  return r;
                }
            }
@@ -13544,26 +13598,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                        init = cp_fname_init (name, &TREE_TYPE (decl));
                      }
                    else
-                     {
-                       tree t = RECUR (init);
-
-                       if (init && !t)
-                         {
-                           /* If we had an initializer but it
-                              instantiated to nothing,
-                              value-initialize the object.  This will
-                              only occur when the initializer was a
-                              pack expansion where the parameter packs
-                              used in that expansion were of length
-                              zero.  */
-                           init = build_value_init (TREE_TYPE (decl),
-                                                    complain);
-                           if (TREE_CODE (init) == AGGR_INIT_EXPR)
-                             init = get_target_expr_sfinae (init, complain);
-                         }
-                       else
-                         init = t;
-                     }
+                     init = tsubst_init (init, decl, args, complain, in_decl);
 
                    if (VAR_P (decl))
                      const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
index edab3309b361d8f76088003fc47ad7eacdc47aa6..396a893bd57ea9039afdf5d976cd870867ee03de 100644 (file)
@@ -3166,12 +3166,7 @@ finish_id_expression (tree id_expression,
       else if (TREE_STATIC (decl)
               /* It's not a use (3.2) if we're in an unevaluated context.  */
               || cp_unevaluated_operand)
-       {
-         if (processing_template_decl)
-           /* For a use of an outer static/unevaluated var, return the id
-              so that we'll look it up again in the instantiation.  */
-           return id_expression;
-       }
+       /* OK */;
       else
        {
          tree context = DECL_CONTEXT (decl);
@@ -3190,13 +3185,13 @@ finish_id_expression (tree id_expression,
             the complexity of the problem"
 
             FIXME update for final resolution of core issue 696.  */
-         if (decl_constant_var_p (decl))
+         if (decl_maybe_constant_var_p (decl))
            {
              if (processing_template_decl)
                /* In a template, the constant value may not be in a usable
-                  form, so look it up again at instantiation time.  */
-               return id_expression;
-             else
+                  form, so wait until instantiation time.  */
+               return decl;
+             else if (decl_constant_var_p (decl))
                return integral_constant_value (decl);
            }