OSDN Git Service

Restore canonical type comparison for dependent type(def)s
[pf3gnuchains/gcc-fork.git] / gcc / cp / tree.c
index b8f76b0..d1d306e 100644 (file)
@@ -441,7 +441,8 @@ build_cplus_new (tree type, tree init)
 
   if (TREE_CODE (rval) == AGGR_INIT_EXPR)
     slot = AGGR_INIT_EXPR_SLOT (rval);
-  else if (TREE_CODE (rval) == CALL_EXPR)
+  else if (TREE_CODE (rval) == CALL_EXPR
+          || TREE_CODE (rval) == CONSTRUCTOR)
     slot = build_local_temp (type);
   else
     return rval;
@@ -452,14 +453,41 @@ build_cplus_new (tree type, tree init)
   return rval;
 }
 
-/* Return a TARGET_EXPR which expresses the direct-initialization of one
-   array from another.  */
+/* Return a TARGET_EXPR which expresses the initialization of an array to
+   be named later, either default-initialization or copy-initialization
+   from another array of the same type.  */
 
 tree
-build_array_copy (tree init)
+build_vec_init_expr (tree type, tree init)
 {
-  tree type = TREE_TYPE (init);
-  tree slot = build_local_temp (type);
+  tree slot;
+  tree inner_type = strip_array_types (type);
+
+  gcc_assert (init == NULL_TREE
+             || (same_type_ignoring_top_level_qualifiers_p
+                 (type, TREE_TYPE (init))));
+
+  /* Since we're deferring building the actual constructor calls until
+     gimplification time, we need to build one now and throw it away so
+     that the relevant constructor gets mark_used before cgraph decides
+     what functions are needed.  Here we assume that init is either
+     NULL_TREE or another array to copy.  */
+  if (CLASS_TYPE_P (inner_type))
+    {
+      VEC(tree,gc) *argvec = make_tree_vector ();
+      if (init)
+       {
+         tree dummy = build_dummy_object (inner_type);
+         if (!real_lvalue_p (init))
+           dummy = move (dummy);
+         VEC_quick_push (tree, argvec, dummy);
+       }
+      build_special_member_call (NULL_TREE, complete_ctor_identifier,
+                                &argvec, inner_type, LOOKUP_NORMAL,
+                                tf_warning_or_error);
+    }
+
+  slot = build_local_temp (type);
   init = build2 (VEC_INIT_EXPR, type, slot, init);
   SET_EXPR_LOCATION (init, input_location);
   init = build_target_expr (slot, init);
@@ -468,6 +496,12 @@ build_array_copy (tree init)
   return init;
 }
 
+tree
+build_array_copy (tree init)
+{
+  return build_vec_init_expr (TREE_TYPE (init), init);
+}
+
 /* Build a TARGET_EXPR using INIT to initialize a new temporary of the
    indicated TYPE.  */
 
@@ -1062,22 +1096,6 @@ strip_typedefs (tree t)
   return cp_build_qualified_type (result, cp_type_quals (t));
 }
 
-/* Setup a TYPE_DECL node as a typedef representation.
-   See comments of set_underlying_type in c-common.c.  */
-
-void
-cp_set_underlying_type (tree t)
-{
-  set_underlying_type (t);
-  /* If T is a template type parm, make it require structural equality.
-     This is useful when comparing two template type parms,
-     because it forces the comparison of the template parameters of their
-     decls.  */
-  if (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
-    SET_TYPE_STRUCTURAL_EQUALITY (TREE_TYPE (t));
-}
-
-\f
 /* Makes a copy of BINFO and TYPE, which is to be inherited into a
    graph dominated by T.  If BINFO is NULL, TYPE is a dependent base,
    and we do a shallow copy.  If BINFO is non-NULL, we do a deep copy.
@@ -3018,18 +3036,23 @@ stabilize_expr (tree exp, tree* initp)
 
   if (!TREE_SIDE_EFFECTS (exp))
     init_expr = NULL_TREE;
-  else if (!real_lvalue_p (exp)
-          || !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
+  /* There are no expressions with REFERENCE_TYPE, but there can be call
+     arguments with such a type; just treat it as a pointer.  */
+  else if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE
+          || !lvalue_or_rvalue_with_address_p (exp))
     {
       init_expr = get_target_expr (exp);
       exp = TARGET_EXPR_SLOT (init_expr);
     }
   else
     {
+      bool xval = !real_lvalue_p (exp);
       exp = cp_build_addr_expr (exp, tf_warning_or_error);
       init_expr = get_target_expr (exp);
       exp = TARGET_EXPR_SLOT (init_expr);
       exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
+      if (xval)
+       exp = move (exp);
     }
   *initp = init_expr;
 
@@ -3196,6 +3219,7 @@ bool
 cast_valid_in_integral_constant_expression_p (tree type)
 {
   return (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+         || cxx_dialect >= cxx0x
          || dependent_type_p (type)
          || type == error_mark_node);
 }