OSDN Git Service

PR c++/48322
[pf3gnuchains/gcc-fork.git] / gcc / cp / tree.c
index 678c7ef..d206fd2 100644 (file)
@@ -203,10 +203,13 @@ lvalue_kind (const_tree ref)
       return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
 
     case NON_DEPENDENT_EXPR:
-      /* We used to just return clk_ordinary for NON_DEPENDENT_EXPR because
-        it was safe enough for C++98, but in C++0x lvalues don't bind to
-        rvalue references, so we get bogus errors (c++/44870).  */
-      return lvalue_kind (TREE_OPERAND (ref, 0));
+      /* We just return clk_ordinary for NON_DEPENDENT_EXPR in C++98, but
+        in C++11 lvalues don't bind to rvalue references, so we need to
+        work harder to avoid bogus errors (c++/44870).  */
+      if (cxx_dialect < cxx0x)
+       return clk_ordinary;
+      else
+       return lvalue_kind (TREE_OPERAND (ref, 0));
 
     default:
       if (!TREE_TYPE (ref))
@@ -288,6 +291,7 @@ static tree
 build_target_expr (tree decl, tree value, tsubst_flags_t complain)
 {
   tree t;
+  tree type = TREE_TYPE (decl);
 
 #ifdef ENABLE_CHECKING
   gcc_assert (VOID_TYPE_P (TREE_TYPE (value))
@@ -302,12 +306,14 @@ build_target_expr (tree decl, tree value, tsubst_flags_t complain)
   t = cxx_maybe_build_cleanup (decl, complain);
   if (t == error_mark_node)
     return error_mark_node;
-  t = build4 (TARGET_EXPR, TREE_TYPE (decl), decl, value, t, NULL_TREE);
+  t = build4 (TARGET_EXPR, type, decl, value, t, 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
      whatever code is generated anyhow.  */
   TREE_SIDE_EFFECTS (t) = 1;
+  if (literal_type_p (type))
+    TREE_CONSTANT (t) = TREE_CONSTANT (value);
 
   return t;
 }
@@ -511,6 +517,11 @@ build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
                                    complain);
   release_tree_vector (argvec);
 
+  /* For a trivial constructor, build_over_call creates a TARGET_EXPR.  But
+     we don't want one here because we aren't creating a temporary.  */
+  if (TREE_CODE (init) == TARGET_EXPR)
+    init = TARGET_EXPR_INITIAL (init);
+
   return init;
 }
 
@@ -1411,6 +1422,7 @@ build_qualified_name (tree type, tree scope, tree name, bool template_p)
     return error_mark_node;
   t = build2 (SCOPE_REF, type, scope, name);
   QUALIFIED_NAME_IS_TEMPLATE (t) = template_p;
+  PTRMEM_OK_P (t) = true;
   if (type)
     t = convert_from_reference (t);
   return t;
@@ -1441,6 +1453,21 @@ is_overloaded_fn (tree x)
           || TREE_CODE (x) == OVERLOAD);
 }
 
+/* X is the CALL_EXPR_FN of a CALL_EXPR.  If X represents a dependent name
+   (14.6.2), return the IDENTIFIER_NODE for that name.  Otherwise, return
+   NULL_TREE.  */
+
+static tree
+dependent_name (tree x)
+{
+  if (TREE_CODE (x) == IDENTIFIER_NODE)
+    return x;
+  if (TREE_CODE (x) != COMPONENT_REF
+      && is_overloaded_fn (x))
+    return DECL_NAME (get_first_fn (x));
+  return NULL_TREE;
+}
+
 /* Returns true iff X is an expression for an overloaded function
    whose type cannot be known without performing overload
    resolution.  */
@@ -1841,9 +1868,13 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
 
   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.  */
+      /* There can't be any TARGET_EXPRs or their slot variables below this
+        point.  But we must make a copy, in case subsequent processing
+        alters any part of it.  For example, during gimplification a cast
+        of the form (T) &X::f (where "f" is a member function) will lead
+        to replacing the PTRMEM_CST for &X::f with a VAR_DECL.  */
       *walk_subtrees = 0;
+      *tp = unshare_expr (t);
       return NULL_TREE;
     }
   if (TREE_CODE (t) == TARGET_EXPR)
@@ -1851,12 +1882,20 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
       tree u;
 
       if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
-       u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
-                            tf_warning_or_error);
+       {
+         u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
+                              tf_warning_or_error);
+         if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
+           AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
+       }
       else
        u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t),
                                         tf_warning_or_error);
 
+      TARGET_EXPR_IMPLICIT_P (u) = TARGET_EXPR_IMPLICIT_P (t);
+      TARGET_EXPR_LIST_INIT_P (u) = TARGET_EXPR_LIST_INIT_P (t);
+      TARGET_EXPR_DIRECT_INIT_P (u) = TARGET_EXPR_DIRECT_INIT_P (t);
+
       /* Map the old variable to the new one.  */
       splay_tree_insert (target_remap,
                         (splay_tree_key) TREE_OPERAND (t, 0),
@@ -1874,7 +1913,10 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
     }
 
   /* Make a copy of this node.  */
-  return copy_tree_r (tp, walk_subtrees, NULL);
+  t = copy_tree_r (tp, walk_subtrees, NULL);
+  if (TREE_CODE (*tp) == CALL_EXPR)
+    set_flags_from_callee (*tp);
+  return t;
 }
 
 /* Replace all remapped VAR_DECLs in T with their new equivalents.
@@ -1895,14 +1937,21 @@ bot_replace (tree* t,
       if (n)
        *t = (tree) n->value;
     }
+  else if (TREE_CODE (*t) == PARM_DECL
+          && DECL_NAME (*t) == this_identifier)
+    {
+      /* In an NSDMI we need to replace the 'this' parameter we used for
+        parsing with the real one for this function.  */
+      *t = current_class_ptr;
+    }
 
   return NULL_TREE;
 }
 
 /* When we parse a default argument expression, we may create
    temporary variables via TARGET_EXPRs.  When we actually use the
-   default-argument expression, we make a copy of the expression, but
-   we must replace the temporaries with appropriate local versions.  */
+   default-argument expression, we make a copy of the expression
+   and replace the temporaries with appropriate local versions.  */
 
 tree
 break_out_target_exprs (tree t)
@@ -2178,7 +2227,12 @@ cp_tree_equal (tree t1, tree t2)
       {
        tree arg1, arg2;
        call_expr_arg_iterator iter1, iter2;
-       if (!cp_tree_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+       /* Core 1321: dependent names are equivalent even if the
+          overload sets are different.  */
+       tree name1 = dependent_name (CALL_EXPR_FN (t1));
+       tree name2 = dependent_name (CALL_EXPR_FN (t2));
+       if (!(name1 && name2 && name1 == name2)
+           && !cp_tree_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
          return false;
        for (arg1 = first_call_expr_arg (t1, &iter1),
               arg2 = first_call_expr_arg (t2, &iter2);
@@ -2341,6 +2395,7 @@ cp_tree_equal (tree t1, tree t2)
     case REINTERPRET_CAST_EXPR:
     case CONST_CAST_EXPR:
     case DYNAMIC_CAST_EXPR:
+    case IMPLICIT_CONV_EXPR:
     case NEW_EXPR:
       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
        return false;
@@ -2938,11 +2993,13 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
 
     case TYPE_PACK_EXPANSION:
       WALK_SUBTREE (TREE_TYPE (*tp));
+      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
       *walk_subtrees_p = 0;
       break;
       
     case EXPR_PACK_EXPANSION:
       WALK_SUBTREE (TREE_OPERAND (*tp, 0));
+      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
       *walk_subtrees_p = 0;
       break;
 
@@ -2951,6 +3008,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case STATIC_CAST_EXPR:
     case CONST_CAST_EXPR:
     case DYNAMIC_CAST_EXPR:
+    case IMPLICIT_CONV_EXPR:
       if (TREE_TYPE (*tp))
        WALK_SUBTREE (TREE_TYPE (*tp));
 
@@ -3296,11 +3354,20 @@ stabilize_init (tree init, tree *initp)
       /* Aggregate initialization: stabilize each of the field
         initializers.  */
       unsigned i;
-      tree value;
+      constructor_elt *ce;
       bool good = true;
-      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, value)
-       if (!stabilize_init (value, initp))
-         good = false;
+      VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (t);
+      for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
+       {
+         tree type = TREE_TYPE (ce->value);
+         tree subinit;
+         if (TREE_CODE (type) == REFERENCE_TYPE
+             || SCALAR_TYPE_P (type))
+           ce->value = stabilize_expr (ce->value, &subinit);
+         else if (!stabilize_init (ce->value, &subinit))
+           good = false;
+         *initp = add_stmt_to_compound (*initp, subinit);
+       }
       return good;
     }