OSDN Git Service

Fix PR c++/47398
[pf3gnuchains/gcc-fork.git] / gcc / cp / tree.c
index 93d13a1..d62d242 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, 2004, 2005, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
@@ -27,7 +27,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "cp-tree.h"
 #include "flags.h"
-#include "toplev.h"
 #include "tree-inline.h"
 #include "debug.h"
 #include "convert.h"
@@ -67,7 +66,8 @@ lvalue_kind (const_tree ref)
          == REFERENCE_TYPE)
     return lvalue_kind (TREE_OPERAND (ref, 0));
 
-  if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
+  if (TREE_TYPE (ref)
+      && TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
     {
       /* unnamed rvalue references are rvalues */
       if (TYPE_REF_IS_RVALUE (TREE_TYPE (ref))
@@ -146,9 +146,12 @@ lvalue_kind (const_tree ref)
        return clk_ordinary;
       break;
 
-      /* A currently unresolved scope ref.  */
+      /* A scope ref in a template, left as SCOPE_REF to support later
+        access checking.  */
     case SCOPE_REF:
-      gcc_unreachable ();
+      gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE(ref)));
+      return lvalue_kind (TREE_OPERAND (ref, 1));
+
     case MAX_EXPR:
     case MIN_EXPR:
       /* Disallow <? and >? as lvalues if either argument side-effects.  */
@@ -441,7 +444,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,22 +456,84 @@ 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);
+  tree elt_init = integer_zero_node;
+  bool value_init = false;
+
+  /* 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, void_type_node (indicating value-initialization), or
+     another array to copy.  */
+  if (integer_zerop (array_type_nelts_total (type)))
+    {
+      /* No actual initialization to do.  */;
+      init = NULL_TREE;
+    }
+  else if (init == void_type_node)
+    {
+      elt_init = build_value_init (inner_type, tf_warning_or_error);
+      value_init = true;
+      init = NULL_TREE;
+    }
+  else
+    {
+      gcc_assert (init == NULL_TREE
+                 || (same_type_ignoring_top_level_qualifiers_p
+                     (type, TREE_TYPE (init))));
+
+      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);
+           }
+         elt_init
+           = 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);
+
+  if (current_function_decl
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
+    {
+      if (potential_constant_expression (elt_init))
+       VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
+      else if (!processing_template_decl)
+       require_potential_constant_expression (elt_init);
+    }
+  VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
+
   init = build_target_expr (slot, init);
   TARGET_EXPR_IMPLICIT_P (init) = 1;
 
   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.  */
 
@@ -810,7 +876,7 @@ cp_build_qualified_type_real (tree type,
       /* See if we already have an identically qualified type.  Tests
         should be equivalent to those in check_qualified_type.  */
       for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-       if (cp_type_quals (t) == type_quals
+       if (TREE_TYPE (t) == element_type
            && TYPE_NAME (t) == TYPE_NAME (type)
            && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
            && attribute_list_equal (TYPE_ATTRIBUTES (t),
@@ -1062,22 +1128,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.
@@ -1725,11 +1775,10 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
   splay_tree target_remap = ((splay_tree) data);
   tree t = *tp;
 
-  if (!TYPE_P (t) && TREE_CONSTANT (t))
+  if (!TYPE_P (t) && TREE_CONSTANT (t) && !TREE_SIDE_EFFECTS (t))
     {
       /* There can't be any TARGET_EXPRs or their slot variables below
-        this point.  We used to check !TREE_SIDE_EFFECTS, but then we
-        failed to copy an ADDR_EXPR of the slot VAR_DECL.  */
+        this point.  */
       *walk_subtrees = 0;
       return NULL_TREE;
     }
@@ -2127,6 +2176,9 @@ cp_tree_equal (tree t1, tree t2)
                                BASELINK_FUNCTIONS (t2)));
 
     case TEMPLATE_PARM_INDEX:
+      if (TEMPLATE_PARM_NUM_SIBLINGS (t1)
+         != TEMPLATE_PARM_NUM_SIBLINGS (t2))
+       return false;
       return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
              && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
              && (TEMPLATE_PARM_PARAMETER_PACK (t1)
@@ -2334,12 +2386,12 @@ maybe_dummy_object (tree type, tree* binfop)
   if (binfop)
     *binfop = binfo;
 
-  if (current_class_ref && context == current_class_type
-      /* Kludge: Make sure that current_class_type is actually
-        correct.  It might not be if we're in the middle of
-        tsubst_default_argument.  */
-      && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)),
-                     current_class_type))
+  if (current_class_ref
+      /* current_class_ref might not correspond to current_class_type if
+        we're in tsubst_default_argument or a lambda-declarator; in either
+        case, we want to use current_class_ref if it matches CONTEXT.  */
+      && (same_type_ignoring_top_level_qualifiers_p
+         (TREE_TYPE (current_class_ref), context)))
     decl = current_class_ref;
   else if (current != current_class_type
           && context == nonlambda_method_basetype ())
@@ -2709,7 +2761,8 @@ cp_build_type_attribute_variant (tree type, tree attributes)
 bool
 cxx_type_hash_eq (const_tree typea, const_tree typeb)
 {
-  gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE);
+  gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE
+             || TREE_CODE (typea) == METHOD_TYPE);
 
   return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea),
                            TYPE_RAISES_EXCEPTIONS (typeb), ce_exact);
@@ -3018,18 +3071,21 @@ 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)))
+  else if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp))
+          || !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 +3252,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);
 }