OSDN Git Service

PR c++/29632
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index c982645..3418703 100644 (file)
@@ -39,6 +39,7 @@ Boston, MA 02110-1301, USA.  */
 #include "intl.h"
 #include "target.h"
 #include "convert.h"
+#include "langhooks.h"
 
 /* The various kinds of conversion.  */
 
@@ -426,11 +427,14 @@ null_ptr_cst_p (tree t)
      A null pointer constant is an integral constant expression
      (_expr.const_) rvalue of integer type that evaluates to zero.  */
   t = integral_constant_value (t);
-  if (t == null_node
-      || (CP_INTEGRAL_TYPE_P (TREE_TYPE (t))
-         && integer_zerop (t)
-         && !TREE_CONSTANT_OVERFLOW (t)))
+  if (t == null_node)
     return true;
+  if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))
+    {
+      STRIP_NOPS (t);
+      if (!TREE_CONSTANT_OVERFLOW (t))
+       return true;
+    }
   return false;
 }
 
@@ -623,7 +627,16 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
       conv = build_conv (ck_lvalue, from, conv);
     }
   else if (fromref || (expr && lvalue_p (expr)))
-    conv = build_conv (ck_rvalue, from, conv);
+    {
+      if (expr)
+       {
+         tree bitfield_type;
+         bitfield_type = is_bitfield_expr_with_lowered_type (expr);
+         if (bitfield_type)
+           from = strip_top_quals (bitfield_type);
+       }
+      conv = build_conv (ck_rvalue, from, conv);
+    }
 
    /* Allow conversion between `__complex__' data types.  */
   if (tcode == COMPLEX_TYPE && fcode == COMPLEX_TYPE)
@@ -715,7 +728,19 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
                  that necessitates this conversion is ill-formed.
                  Therefore, we use DERIVED_FROM_P, and do not check
                  access or uniqueness.  */
-              && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
+              && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))
+              /* If FROM is not yet complete, then we must be parsing
+                 the body of a class.  We know what's derived from
+                 what, but we can't actually perform a
+                 derived-to-base conversion.  For example, in:
+
+                    struct D : public B { 
+                       static const int i = sizeof((B*)(D*)0);
+                     };
+
+                  the D*-to-B* conversion is a reinterpret_cast, not a
+                 static_cast.  */
+              && COMPLETE_TYPE_P (TREE_TYPE (from)))
        {
          from =
            cp_build_qualified_type (TREE_TYPE (to),
@@ -1786,14 +1811,19 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
        break;
       if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
        break;
-      if (TREE_CODE (type1) == ENUMERAL_TYPE && TREE_CODE (type2) == ENUMERAL_TYPE)
+      if (TREE_CODE (type1) == ENUMERAL_TYPE 
+         && TREE_CODE (type2) == ENUMERAL_TYPE)
        break;
-      if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1]))
+      if (TYPE_PTR_P (type1) 
+         && null_ptr_cst_p (args[1])
+         && !uses_template_parms (type1))
        {
          type2 = type1;
          break;
        }
-      if (null_ptr_cst_p (args[0]) && TYPE_PTR_P (type2))
+      if (null_ptr_cst_p (args[0]) 
+         && TYPE_PTR_P (type2)
+         && !uses_template_parms (type2))
        {
          type1 = type2;
          break;
@@ -2692,6 +2722,8 @@ resolve_args (tree args)
          error ("invalid use of void expression");
          return error_mark_node;
        }
+      else if (invalid_nonstatic_memfn_p (arg))
+       return error_mark_node;
     }
   return args;
 }
@@ -2821,7 +2853,7 @@ build_new_function_call (tree fn, tree args, bool koenig_p)
    set, upon return, to the allocation function called.  */
 
 tree
-build_operator_new_call (tree fnname, tree args, 
+build_operator_new_call (tree fnname, tree args,
                         tree *size, tree *cookie_size,
                         tree *fn)
 {
@@ -3196,8 +3228,12 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
      array-to-pointer (_conv.array_), and function-to-pointer
      (_conv.func_) standard conversions are performed on the second
      and third operands.  */
-  arg2_type = TREE_TYPE (arg2);
-  arg3_type = TREE_TYPE (arg3);
+  arg2_type = is_bitfield_expr_with_lowered_type (arg2);
+  if (!arg2_type)
+    arg2_type = TREE_TYPE (arg2);
+  arg3_type = is_bitfield_expr_with_lowered_type (arg3);
+  if (!arg3_type)
+    arg3_type = TREE_TYPE (arg3);
   if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
     {
       /* Do the conversions.  We don't these for `void' type arguments
@@ -3284,7 +3320,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
          || (conv3 && conv3->kind == ck_ambig))
        {
          error ("operands to ?: have different types %qT and %qT",
-             arg2_type, arg3_type);
+                arg2_type, arg3_type);
          result = error_mark_node;
        }
       else if (conv2 && (!conv2->bad_p || !conv3))
@@ -3292,12 +3328,21 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
          arg2 = convert_like (conv2, arg2);
          arg2 = convert_from_reference (arg2);
          arg2_type = TREE_TYPE (arg2);
+         /* Even if CONV2 is a valid conversion, the result of the
+            conversion may be invalid.  For example, if ARG3 has type
+            "volatile X", and X does not have a copy constructor
+            accepting a "volatile X&", then even if ARG2 can be
+            converted to X, the conversion will fail.  */
+         if (error_operand_p (arg2))
+           result = error_mark_node;
        }
       else if (conv3 && (!conv3->bad_p || !conv2))
        {
          arg3 = convert_like (conv3, arg3);
          arg3 = convert_from_reference (arg3);
          arg3_type = TREE_TYPE (arg3);
+         if (error_operand_p (arg3))
+           result = error_mark_node;
        }
 
       /* Free all the conversions we allocated.  */
@@ -3494,8 +3539,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
 
   if (!result_type)
     {
-         error ("operands to ?: have different types %qT and %qT",
-             arg2_type, arg3_type);
+      error ("operands to ?: have different types %qT and %qT",
+            arg2_type, arg3_type);
       return error_mark_node;
     }
 
@@ -3505,16 +3550,18 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
-  /* Expand both sides into the same slot, hopefully the target of the
-     ?: expression.  We used to check for TARGET_EXPRs here, but now we
-     sometimes wrap them in NOP_EXPRs so the test would fail.  */
-  if (!lvalue_p && CLASS_TYPE_P (TREE_TYPE (result)))
-    result = get_target_expr (result);
-
-  /* If this expression is an rvalue, but might be mistaken for an
-     lvalue, we must add a NON_LVALUE_EXPR.  */
-  if (!lvalue_p && real_lvalue_p (result))
-    result = rvalue (result);
+  if (!lvalue_p)
+    {
+      /* Expand both sides into the same slot, hopefully the target of
+        the ?: expression.  We used to check for TARGET_EXPRs here,
+        but now we sometimes wrap them in NOP_EXPRs so the test would
+        fail.  */
+      if (CLASS_TYPE_P (TREE_TYPE (result)))
+       result = get_target_expr (result);
+      /* If this expression is an rvalue, but might be mistaken for an
+        lvalue, we must add a NON_LVALUE_EXPR.  */
+      result = rvalue (result);
+    }
 
   return result;
 }
@@ -4035,7 +4082,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
          /* On the second pass, the second argument must be
             "size_t".  */
          else if (pass == 1
-                  && same_type_p (TREE_VALUE (t), sizetype)
+                  && same_type_p (TREE_VALUE (t), size_type_node)
                   && TREE_CHAIN (t) == void_list_node)
            break;
        }
@@ -4055,7 +4102,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
       /* If the FN is a member function, make sure that it is
         accessible.  */
       if (DECL_CLASS_SCOPE_P (fn))
-       perform_or_defer_access_check (TYPE_BINFO (type), fn);
+       perform_or_defer_access_check (TYPE_BINFO (type), fn, fn);
 
       if (pass == 0)
        args = tree_cons (NULL_TREE, addr, args);
@@ -4086,21 +4133,22 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
 
 /* If the current scope isn't allowed to access DECL along
    BASETYPE_PATH, give an error.  The most derived class in
-   BASETYPE_PATH is the one used to qualify DECL.  */
+   BASETYPE_PATH is the one used to qualify DECL. DIAG_DECL is
+   the declaration to use in the error diagnostic.  */
 
 bool
-enforce_access (tree basetype_path, tree decl)
+enforce_access (tree basetype_path, tree decl, tree diag_decl)
 {
   gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
 
   if (!accessible_p (basetype_path, decl, true))
     {
       if (TREE_PRIVATE (decl))
-       error ("%q+#D is private", decl);
+       error ("%q+#D is private", diag_decl);
       else if (TREE_PROTECTED (decl))
-       error ("%q+#D is protected", decl);
+       error ("%q+#D is protected", diag_decl);
       else
-       error ("%q+#D is inaccessible", decl);
+       error ("%q+#D is inaccessible", diag_decl);
       error ("within this context");
       return false;
     }
@@ -4315,6 +4363,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   switch (convs->kind)
     {
     case ck_rvalue:
+      expr = convert_bitfield_to_declared_type (expr);
       if (! IS_AGGR_TYPE (totype))
        return expr;
       /* Else fall through.  */
@@ -4502,10 +4551,12 @@ build_x_va_arg (tree expr, tree type)
 
   if (! pod_type_p (type))
     {
+      /* Remove reference types so we don't ICE later on.  */
+      tree type1 = non_reference (type);
       /* Undefined behavior [expr.call] 5.2.2/7.  */
       warning (0, "cannot receive objects of non-POD type %q#T through %<...%>; "
               "call will abort at runtime", type);
-      expr = convert (build_pointer_type (type), null_node);
+      expr = convert (build_pointer_type (type1), null_node);
       expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr),
                     call_builtin_trap (), expr);
       expr = build_indirect_ref (expr, NULL);
@@ -4726,9 +4777,9 @@ build_over_call (struct z_candidate *cand, int flags)
       if (DECL_TEMPLATE_INFO (fn)
          && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
        perform_or_defer_access_check (cand->access_path,
-                                      DECL_TI_TEMPLATE (fn));
+                                      DECL_TI_TEMPLATE (fn), fn);
       else
-       perform_or_defer_access_check (cand->access_path, fn);
+       perform_or_defer_access_check (cand->access_path, fn, fn);
     }
 
   if (args && TREE_CODE (args) != TREE_LIST)
@@ -4805,6 +4856,12 @@ build_over_call (struct z_candidate *cand, int flags)
       tree type = TREE_VALUE (parm);
 
       conv = convs[i];
+
+      /* Don't make a copy here if build_call is going to.  */
+      if (conv->kind == ck_rvalue
+         && !TREE_ADDRESSABLE (complete_type (type)))
+       conv = conv->u.next;
+
       val = convert_like_with_context
        (conv, TREE_VALUE (arg), fn, i - is_method);
 
@@ -5015,9 +5072,9 @@ build_java_interface_fn_ref (tree fn, tree instance)
                                     tree_cons (NULL_TREE, java_int_type_node,
                                                endlink)));
       java_iface_lookup_fn
-       = builtin_function ("_Jv_LookupInterfaceMethodIdx",
-                           build_function_type (ptr_type_node, t),
-                           0, NOT_BUILT_IN, NULL, NULL_TREE);
+       = add_builtin_function ("_Jv_LookupInterfaceMethodIdx",
+                               build_function_type (ptr_type_node, t),
+                               0, NOT_BUILT_IN, NULL, NULL_TREE);
     }
 
   /* Look up the pointer to the runtime java.lang.Class object for `instance'.
@@ -5459,9 +5516,9 @@ build_new_method_call (tree instance, tree fns, tree args,
                 none-the-less evaluated.  */
              if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
                  && !is_dummy_object (instance_ptr)
-                 && TREE_SIDE_EFFECTS (instance))
+                 && TREE_SIDE_EFFECTS (instance_ptr))
                call = build2 (COMPOUND_EXPR, TREE_TYPE (call),
-                              instance, call);
+                              instance_ptr, call);
            }
        }
     }
@@ -6047,7 +6104,7 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
              if (warn)
                {
                  warning (OPT_Wsign_promo, "passing %qT chooses %qT over %qT",
-                           type, type1, type2);
+                          type, type1, type2);
                  warning (OPT_Wsign_promo, "  in call to %qD", w->fn);
                }
              else
@@ -6369,6 +6426,14 @@ perform_implicit_conversion (tree type, tree expr)
       error ("could not convert %qE to %qT", expr, type);
       expr = error_mark_node;
     }
+  else if (processing_template_decl)
+    {
+      /* In a template, we are only concerned about determining the
+        type of non-dependent expressions, so we do not have to
+        perform the actual conversion.  */
+      if (TREE_TYPE (expr) != type)
+       expr = build_nop (type, expr);
+    }
   else
     expr = convert_like (conv, expr);