OSDN Git Service

* cp-tree.h (commonparms): Remove prototype.
[pf3gnuchains/gcc-fork.git] / gcc / cp / tree.c
index 39f6557..0a0b3ec 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-dependent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -42,8 +42,6 @@ static int list_hash_eq (const void *, const void *);
 static hashval_t list_hash_pieces (tree, tree, tree);
 static hashval_t list_hash (const void *);
 static cp_lvalue_kind lvalue_p_1 (tree, int);
-static tree mark_local_for_remap_r (tree *, int *, void *);
-static tree cp_unsave_r (tree *, int *, void *);
 static tree build_target_expr (tree, tree);
 static tree count_trees_r (tree *, int *, void *);
 static tree verify_stmt_tree_r (tree *, int *, void *);
@@ -128,9 +126,13 @@ lvalue_p_1 (tree ref,
 
       /* A currently unresolved scope ref.  */
     case SCOPE_REF:
-      abort ();
+      gcc_unreachable ();
     case MAX_EXPR:
     case MIN_EXPR:
+      /* Disallow <? and >? as lvalues if either argument side-effects.  */
+      if (TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 0))
+         || TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 1)))
+       return clk_none;
       op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
                                    treat_class_rvalues_as_lvalues);
       op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
@@ -213,20 +215,6 @@ lvalue_p (tree ref)
     (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
 }
 
-/* Return nonzero if REF is an lvalue valid for this language;
-   otherwise, print an error message and return zero.  */
-
-int
-lvalue_or_else (tree ref, const char* string)
-{
-  if (!lvalue_p (ref))
-    {
-      error ("non-lvalue in %s", string);
-      return 0;
-    }
-  return 1;
-}
-
 /* Build a TARGET_EXPR, initializing the DECL with the VALUE.  */
 
 static tree
@@ -234,8 +222,8 @@ build_target_expr (tree decl, tree value)
 {
   tree t;
 
-  t = build (TARGET_EXPR, TREE_TYPE (decl), decl, value,
-            cxx_maybe_build_cleanup (decl), NULL_TREE);
+  t = build4 (TARGET_EXPR, TREE_TYPE (decl), decl, value,
+             cxx_maybe_build_cleanup (decl), NULL_TREE);
   /* We always set TREE_SIDE_EFFECTS so that expand_expr does not
      ignore the TARGET_EXPR.  If there really turn out to be no
      side-effects, then the optimizer should be able to get rid of
@@ -253,6 +241,7 @@ build_local_temp (tree type)
 {
   tree slot = build_decl (VAR_DECL, NULL_TREE, type);
   DECL_ARTIFICIAL (slot) = 1;
+  DECL_IGNORED_P (slot) = 1;
   DECL_CONTEXT (slot) = current_function_decl;
   layout_decl (slot, 0);
   return slot;
@@ -300,8 +289,8 @@ build_cplus_new (tree type, tree init)
      type, don't mess with AGGR_INIT_EXPR.  */
   if (is_ctor || TREE_ADDRESSABLE (type))
     {
-      rval = build (AGGR_INIT_EXPR, void_type_node, fn,
-                   TREE_OPERAND (init, 1), slot);
+      rval = build3 (AGGR_INIT_EXPR, void_type_node, fn,
+                    TREE_OPERAND (init, 1), slot);
       TREE_SIDE_EFFECTS (rval) = 1;
       AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
     }
@@ -321,7 +310,7 @@ build_target_expr_with_type (tree init, tree type)
 {
   tree slot;
 
-  my_friendly_assert (!VOID_TYPE_P (type), 20040130);
+  gcc_assert (!VOID_TYPE_P (type));
 
   if (TREE_CODE (init) == TARGET_EXPR)
     return init;
@@ -349,7 +338,7 @@ force_target_expr (tree type, tree init)
 {
   tree slot;
 
-  my_friendly_assert (!VOID_TYPE_P (type), 20040130);
+  gcc_assert (!VOID_TYPE_P (type));
 
   slot = build_local_temp (type);
   return build_target_expr (slot, init);
@@ -467,7 +456,7 @@ cp_build_qualified_type_real (tree type,
        {
          /* Make a new array type, just like the old one, but with the
             appropriately qualified element type.  */
-         t = build_type_copy (type);
+         t = build_variant_type_copy (type);
          TREE_TYPE (t) = element_type;
        }
 
@@ -534,7 +523,7 @@ cp_build_qualified_type_real (tree type,
          tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
 
          if (!(complain & tf_ignore_bad_quals))
-           error ("`%V' qualifiers cannot be applied to `%T'",
+           error ("%qV qualifiers cannot be applied to %qT",
                   bad_type, type);
        }
     }
@@ -608,8 +597,8 @@ copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
       int ix;
       tree base_binfo;
 
-      my_friendly_assert (!BINFO_DEPENDENT_BASE_P (binfo), 20040712);
-      my_friendly_assert (type == BINFO_TYPE (binfo), 20040714);
+      gcc_assert (!BINFO_DEPENDENT_BASE_P (binfo));
+      gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), type));
 
       BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
       BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);
@@ -622,7 +611,7 @@ copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
        {
          tree new_base_binfo;
 
-         my_friendly_assert (!BINFO_DEPENDENT_BASE_P (base_binfo), 20040713);
+         gcc_assert (!BINFO_DEPENDENT_BASE_P (base_binfo));
          new_base_binfo = copy_binfo (base_binfo, BINFO_TYPE (base_binfo),
                                       t, igo_prev,
                                       BINFO_VIRTUAL_P (base_binfo));
@@ -747,21 +736,6 @@ hash_tree_chain (tree value, tree chain)
 {
   return hash_tree_cons (NULL_TREE, value, chain);
 }
-
-/* Similar, but used for concatenating two lists.  */
-
-tree
-hash_chainon (tree list1, tree list2)
-{
-  if (list2 == 0)
-    return list1;
-  if (list1 == 0)
-    return list2;
-  if (TREE_CHAIN (list1) == NULL_TREE)
-    return hash_tree_chain (TREE_VALUE (list1), list2);
-  return hash_tree_chain (TREE_VALUE (list1),
-                         hash_chainon (TREE_CHAIN (list1), list2));
-}
 \f
 void
 debug_binfo (tree elem)
@@ -795,23 +769,6 @@ debug_binfo (tree elem)
 }
 
 int
-count_functions (tree t)
-{
-  int i;
-  if (TREE_CODE (t) == FUNCTION_DECL)
-    return 1;
-  else if (TREE_CODE (t) == OVERLOAD)
-    {
-      for (i = 0; t; t = OVL_CHAIN (t))
-       i++;
-      return i;
-    }
-
-  abort ();
-  return 0;
-}
-
-int
 is_overloaded_fn (tree x)
 {
   /* A baselink is also considered an overloaded function.  */
@@ -842,23 +799,13 @@ really_overloaded_fn (tree x)
 tree
 get_first_fn (tree from)
 {
-  my_friendly_assert (is_overloaded_fn (from), 9);
+  gcc_assert (is_overloaded_fn (from));
   /* A baselink is also considered an overloaded function.  */
   if (BASELINK_P (from))
     from = BASELINK_FUNCTIONS (from);
   return OVL_CURRENT (from);
 }
 
-/* Returns nonzero if T is a ->* or .* expression that refers to a
-   member function.  */
-
-int
-bound_pmf_p (tree t)
-{
-  return (TREE_CODE (t) == OFFSET_REF
-         && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1))));
-}
-
 /* Return a new OVL node, concatenating it with the old one.  */
 
 tree
@@ -917,8 +864,7 @@ cxx_printable_name (tree decl, int v)
        ring_counter += 1;
       if (ring_counter == PRINT_RING_SIZE)
        ring_counter = 0;
-      if (decl_ring[ring_counter] == current_function_decl)
-       abort ();
+      gcc_assert (decl_ring[ring_counter] != current_function_decl);
     }
 
   if (print_ring[ring_counter])
@@ -944,7 +890,7 @@ build_exception_variant (tree type, tree raises)
       return v;
 
   /* Need to build a new variant.  */
-  v = build_type_copy (type);
+  v = build_variant_type_copy (type);
   TYPE_RAISES_EXCEPTIONS (v) = raises;
   return v;
 }
@@ -1018,8 +964,7 @@ verify_stmt_tree_r (tree* tp,
 
   /* If this statement is already present in the hash table, then
      there is a circularity in the statement tree.  */
-  if (htab_find (*statements, t))
-    abort ();
+  gcc_assert (!htab_find (*statements, t));
 
   slot = htab_find_slot (*statements, t, INSERT);
   *slot = t;
@@ -1154,9 +1099,9 @@ cxx_print_statistics (void)
 tree
 array_type_nelts_top (tree type)
 {
-  return fold (build (PLUS_EXPR, sizetype,
-                     array_type_nelts (type),
-                     integer_one_node));
+  return fold (build2 (PLUS_EXPR, sizetype,
+                      array_type_nelts (type),
+                      integer_one_node));
 }
 
 /* Return, as an INTEGER_CST node, the number of elements for TYPE
@@ -1171,7 +1116,7 @@ array_type_nelts_total (tree type)
   while (TREE_CODE (type) == ARRAY_TYPE)
     {
       tree n = array_type_nelts_top (type);
-      sz = fold (build (MULT_EXPR, sizetype, sz, n));
+      sz = fold (build2 (MULT_EXPR, sizetype, sz, n));
       type = TREE_TYPE (type);
     }
   return sz;
@@ -1366,25 +1311,6 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
   return t;
 }
 
-/* Returns an INTEGER_CST (of type `int') corresponding to I.
-   Multiple calls with the same value of I may or may not yield the
-   same node; therefore, callers should never modify the node
-   returned.  */
-
-static GTY(()) tree shared_int_cache[256];
-
-tree
-build_shared_int_cst (int i)
-{
-  if (i >= 256)
-    return build_int_cst (NULL_TREE, i, 0);
-
-  if (!shared_int_cache[i])
-    shared_int_cache[i] = build_int_cst (NULL_TREE, i, 0);
-
-  return shared_int_cache[i];
-}
-
 tree
 get_type_decl (tree t)
 {
@@ -1392,13 +1318,8 @@ get_type_decl (tree t)
     return t;
   if (TYPE_P (t))
     return TYPE_STUB_DECL (t);
-  if (t == error_mark_node)
-    return t;
-
-  abort ();
-
-  /* Stop compiler from complaining control reaches end of non-void function.  */
-  return 0;
+  gcc_assert (t == error_mark_node);
+  return t;
 }
 
 /* Returns the namespace that contains DECL, whether directly or
@@ -1527,6 +1448,12 @@ cp_tree_equal (tree t1, tree t2)
     case IDENTIFIER_NODE:
       return false;
 
+    case BASELINK:
+      return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2)
+             && BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2)
+             && cp_tree_equal (BASELINK_FUNCTIONS (t1),
+                               BASELINK_FUNCTIONS (t2)));
+
     case TEMPLATE_PARM_INDEX:
       return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
              && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
@@ -1579,18 +1506,23 @@ cp_tree_equal (tree t1, tree t2)
 
       return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
 
+    case OVERLOAD:
+      if (OVL_FUNCTION (t1) != OVL_FUNCTION (t2))
+       return false;
+      return cp_tree_equal (OVL_CHAIN (t1), OVL_CHAIN (t2));
+
     default:
       break;
     }
 
   switch (TREE_CODE_CLASS (code1))
     {
-    case '1':
-    case '2':
-    case '<':
-    case 'e':
-    case 'r':
-    case 's':
+    case tcc_unary:
+    case tcc_binary:
+    case tcc_comparison:
+    case tcc_expression:
+    case tcc_reference:
+    case tcc_statement:
       {
        int i;
 
@@ -1601,11 +1533,12 @@ cp_tree_equal (tree t1, tree t2)
        return true;
       }
 
-    case 't':
+    case tcc_type:
       return same_type_p (t1, t2);
+    default:
+      gcc_unreachable ();
     }
-
-  my_friendly_assert (0, 20030617);
+  /* We can get here with --disable-checking.  */
   return false;
 }
 
@@ -1681,7 +1614,7 @@ maybe_dummy_object (tree type, tree* binfop)
 
   if (current_class_type
       && (binfo = lookup_base (current_class_type, type,
-                              ba_ignore | ba_quiet, NULL)))
+                              ba_unique | ba_quiet, NULL)))
     context = current_class_type;
   else
     {
@@ -1736,7 +1669,7 @@ pod_type_p (tree t)
     return 1; /* pointer to member */
 
   if (TREE_CODE (t) == VECTOR_TYPE)
-    return 1; /* vectors are (small) arrays if scalars */
+    return 1; /* vectors are (small) arrays of scalars */
 
   if (! CLASS_TYPE_P (t))
     return 0; /* other non-class type (reference or function) */
@@ -1791,13 +1724,13 @@ handle_java_interface_attribute (tree* node,
       || !CLASS_TYPE_P (*node)
       || !TYPE_FOR_JAVA (*node))
     {
-      error ("`%E' attribute can only be applied to Java class definitions",
+      error ("%qE attribute can only be applied to Java class definitions",
             name);
       *no_add_attrs = true;
       return NULL_TREE;
     }
   if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
-    *node = build_type_copy (*node);
+    *node = build_variant_type_copy (*node);
   TYPE_JAVA_INTERFACE (*node) = 1;
 
   return NULL_TREE;
@@ -1820,13 +1753,12 @@ handle_com_interface_attribute (tree* node,
       || !CLASS_TYPE_P (*node)
       || *node != TYPE_MAIN_VARIANT (*node))
     {
-      warning ("`%E' attribute can only be applied to class definitions",
-              name);
+      warning ("%qE attribute can only be applied to class definitions", name);
       return NULL_TREE;
     }
 
   if (!warned++)
-    warning ("`%E' is obsolete; g++ vtables are now COM-compatible by default",
+    warning ("%qE is obsolete; g++ vtables are now COM-compatible by default",
             name);
 
   return NULL_TREE;
@@ -1871,7 +1803,7 @@ handle_init_priority_attribute (tree* node,
         init_priority value, so don't allow it.  */
       || current_function_decl)
     {
-      error ("can only use `%E' attribute on file-scope definitions "
+      error ("can only use %qE attribute on file-scope definitions "
              "of objects of class type", name);
       *no_add_attrs = true;
       return NULL_TREE;
@@ -1899,7 +1831,7 @@ handle_init_priority_attribute (tree* node,
     }
   else
     {
-      error ("`%E' attribute is not supported on this platform", name);
+      error ("%qE attribute is not supported on this platform", name);
       *no_add_attrs = true;
       return NULL_TREE;
     }
@@ -1950,7 +1882,7 @@ cp_build_type_attribute_variant (tree type, tree attributes)
 
 tree
 cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
-                 void *data, void *htab)
+                 void *data, struct pointer_set_t *pset)
 {
   enum tree_code code = TREE_CODE (*tp);
   location_t save_locus;
@@ -1959,7 +1891,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
 #define WALK_SUBTREE(NODE)                             \
   do                                                   \
     {                                                  \
-      result = walk_tree (&(NODE), func, data, htab);  \
+      result = walk_tree (&(NODE), func, data, pset);  \
       if (result) goto out;                            \
     }                                                  \
   while (0)
@@ -2103,16 +2035,6 @@ cp_add_pending_fn_decls (void* fns_p, tree prev_fn)
   return prev_fn;
 }
 
-/* Determine whether a tree node is an OVERLOAD node.  Used to decide
-   whether to copy a node or to preserve its chain when inlining a
-   function.  */
-
-int
-cp_is_overload_p (tree t)
-{
-  return TREE_CODE (t) == OVERLOAD;
-}
-
 /* Determine whether VAR is a declaration of an automatic variable in
    function FN.  */
 
@@ -2123,20 +2045,6 @@ cp_auto_var_in_fn_p (tree var, tree fn)
          && nonstatic_local_decl_p (var));
 }
 
-/* FN body has been duplicated.  Update language specific fields.  */
-
-void
-cp_update_decl_after_saving (tree fn,
-                             void* decl_map_)
-{
-  splay_tree decl_map = (splay_tree)decl_map_;
-  tree nrv = DECL_SAVED_FUNCTION_DATA (fn)->x_return_value;
-  if (nrv)
-    {
-      DECL_SAVED_FUNCTION_DATA (fn)->x_return_value
-       = (tree) splay_tree_lookup (decl_map, (splay_tree_key) nrv)->value;
-    }
-}
 /* Initialize tree.c.  */
 
 void
@@ -2145,110 +2053,6 @@ init_tree (void)
   list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
 }
 
-/* Called via walk_tree.  If *TP points to a DECL_EXPR for a local
-   declaration, copies the declaration and enters it in the splay_tree
-   pointed to by DATA (which is really a `splay_tree *').  */
-
-static tree
-mark_local_for_remap_r (tree* tp,
-                        int* walk_subtrees ATTRIBUTE_UNUSED ,
-                        void* data)
-{
-  tree t = *tp;
-  splay_tree st = (splay_tree) data;
-  tree decl;
-
-
-  if (TREE_CODE (t) == DECL_EXPR
-      && nonstatic_local_decl_p (DECL_EXPR_DECL (t)))
-    decl = DECL_EXPR_DECL (t);
-  else if (TREE_CODE (t) == LABEL_EXPR)
-    decl = LABEL_EXPR_LABEL (t);
-  else if (TREE_CODE (t) == TARGET_EXPR
-          && nonstatic_local_decl_p (TREE_OPERAND (t, 0)))
-    decl = TREE_OPERAND (t, 0);
-  else if (TREE_CODE (t) == CASE_LABEL_EXPR)
-    decl = CASE_LABEL (t);
-  else
-    decl = NULL_TREE;
-
-  if (decl)
-    {
-      tree copy;
-
-      /* Make a copy.  */
-      copy = copy_decl_for_inlining (decl,
-                                    DECL_CONTEXT (decl),
-                                    DECL_CONTEXT (decl));
-
-      /* Remember the copy.  */
-      splay_tree_insert (st,
-                        (splay_tree_key) decl,
-                        (splay_tree_value) copy);
-    }
-
-  return NULL_TREE;
-}
-
-/* Called via walk_tree when an expression is unsaved.  Using the
-   splay_tree pointed to by ST (which is really a `splay_tree'),
-   remaps all local declarations to appropriate replacements.  */
-
-static tree
-cp_unsave_r (tree* tp,
-             int* walk_subtrees,
-             void* data)
-{
-  splay_tree st = (splay_tree) data;
-  splay_tree_node n;
-
-  /* Only a local declaration (variable or label).  */
-  if (nonstatic_local_decl_p (*tp))
-    {
-      /* Lookup the declaration.  */
-      n = splay_tree_lookup (st, (splay_tree_key) *tp);
-
-      /* If it's there, remap it.  */
-      if (n)
-       *tp = (tree) n->value;
-    }
-  else if (TREE_CODE (*tp) == SAVE_EXPR)
-    remap_save_expr (tp, st, walk_subtrees);
-  else
-    {
-      copy_tree_r (tp, walk_subtrees, NULL);
-
-      /* Do whatever unsaving is required.  */
-      unsave_expr_1 (*tp);
-    }
-
-  /* Keep iterating.  */
-  return NULL_TREE;
-}
-
-/* Called whenever an expression needs to be unsaved.  */
-
-tree
-cxx_unsave_expr_now (tree tp)
-{
-  splay_tree st;
-
-  /* Create a splay-tree to map old local variable declarations to new
-     ones.  */
-  st = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
-
-  /* Walk the tree once figuring out what needs to be remapped.  */
-  walk_tree (&tp, mark_local_for_remap_r, st, NULL);
-
-  /* Walk the tree again, copying, remapping, and unsaving.  */
-  walk_tree (&tp, cp_unsave_r, st, NULL);
-
-  /* Clean up.  */
-  splay_tree_delete (st);
-
-  return tp;
-}
-
 /* Returns the kind of special function that DECL (a FUNCTION_DECL)
    is.  Note that sfk_none is zero, so this function can be used as a
    predicate to test whether or not DECL is a special function.  */
@@ -2279,22 +2083,6 @@ special_function_p (tree decl)
   return sfk_none;
 }
 
-/* Returns true if and only if NODE is a name, i.e., a node created
-   by the parser when processing an id-expression.  */
-
-bool
-name_p (tree node)
-{
-  if (TREE_CODE (node) == TEMPLATE_ID_EXPR)
-    node = TREE_OPERAND (node, 0);
-  return (/* An ordinary unqualified name.  */
-         TREE_CODE (node) == IDENTIFIER_NODE
-         /* A destructor name.  */
-         || TREE_CODE (node) == BIT_NOT_EXPR
-         /* A qualified name.  */
-         || TREE_CODE (node) == SCOPE_REF);
-}
-
 /* Returns nonzero if TYPE is a character type, including wchar_t.  */
 
 int
@@ -2379,6 +2167,19 @@ stabilize_expr (tree exp, tree* initp)
   return exp;
 }
 
+/* Add NEW, an expression whose value we don't care about, after the
+   similar expression ORIG.  */
+
+tree
+add_stmt_to_compound (tree orig, tree new)
+{
+  if (!new || !TREE_SIDE_EFFECTS (new))
+    return orig;
+  if (!orig || !TREE_SIDE_EFFECTS (orig))
+    return new;
+  return build2 (COMPOUND_EXPR, void_type_node, orig, new);
+}
+
 /* Like stabilize_expr, but for a call whose args we want to
    pre-evaluate.  */
 
@@ -2391,21 +2192,15 @@ stabilize_call (tree call, tree *initp)
   if (call == error_mark_node)
     return;
 
-  if (TREE_CODE (call) != CALL_EXPR
-      && TREE_CODE (call) != AGGR_INIT_EXPR)
-    abort ();
+  gcc_assert (TREE_CODE (call) == CALL_EXPR
+             || TREE_CODE (call) == AGGR_INIT_EXPR);
 
   for (t = TREE_OPERAND (call, 1); t; t = TREE_CHAIN (t))
     if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
       {
        tree init;
        TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
-       if (!init)
-         /* Nothing.  */;
-       else if (inits)
-         inits = build (COMPOUND_EXPR, void_type_node, inits, init);
-       else
-         inits = init;
+       inits = add_stmt_to_compound (inits, init);
       }
 
   *initp = inits;
@@ -2433,6 +2228,8 @@ stabilize_init (tree init, tree *initp)
        t = TREE_OPERAND (t, 1);
       if (TREE_CODE (t) == TARGET_EXPR)
        t = TARGET_EXPR_INITIAL (t);
+      if (TREE_CODE (t) == COMPOUND_EXPR)
+       t = expr_last (t);
       if (TREE_CODE (t) == CONSTRUCTOR
          && CONSTRUCTOR_ELTS (t) == NULL_TREE)
        {
@@ -2452,6 +2249,19 @@ stabilize_init (tree init, tree *initp)
   return true;
 }
 
+/* Like "fold", but should be used whenever we might be processing the
+   body of a template.  */
+
+tree
+fold_if_not_in_template (tree expr)
+{
+  /* In the body of a template, there is never any need to call
+     "fold".  We will call fold later when actually instantiating the
+     template.  Integral constant expressions in templates will be
+     evaluated via fold_non_dependent_expr, as necessary.  */
+  return (processing_template_decl ? expr : fold (expr));
+}
+
 \f
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 /* Complain that some language-specific thing hanging off a tree