OSDN Git Service

* g++.dg/abi/vague1.C: Use xfail, rather than embedded Tcl code.
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck.c
index 06a0b42..21068b3 100644 (file)
@@ -971,11 +971,9 @@ comptypes (t1, t2, strict)
   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return 1;
 
-  if (strict & COMPARE_NO_ATTRIBUTES)
-    attrval = 1;
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
-  else if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
-     return 0;
+  if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
+    return 0;
 
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
   val = 0;
@@ -1941,7 +1939,8 @@ build_class_member_access_expr (tree object, tree member,
                       && integer_zerop (TREE_OPERAND (object, 0)));
 
       /* Convert OBJECT to the type of MEMBER.  */
-      if (!same_type_p (object_type, member_scope))
+      if (!same_type_p (TYPE_MAIN_VARIANT (object_type),
+                       TYPE_MAIN_VARIANT (member_scope)))
        {
          tree binfo;
          base_kind kind;
@@ -1951,7 +1950,7 @@ build_class_member_access_expr (tree object, tree member,
          if (binfo == error_mark_node)
            return error_mark_node;
 
-         /* It is invalid to use to try to get to a virtual base of a
+         /* It is invalid to try to get to a virtual base of a
             NULL object.  The most common cause is invalid use of
             offsetof macro.  */
          if (null_object_p && kind == bk_via_virtual)
@@ -1975,7 +1974,8 @@ build_class_member_access_expr (tree object, tree member,
         give the right answer.  Note that we complain whether or not they
         actually used the offsetof macro, since there's no way to know at this
         point.  So we just give a warning, instead of a pedwarn.  */
-      if (null_object_p && CLASSTYPE_NON_POD_P (object_type))
+      if (null_object_p && warn_invalid_offsetof
+         && CLASSTYPE_NON_POD_P (object_type))
        {
          warning ("invalid access to non-static data member `%D' of NULL object", 
                   member);
@@ -2655,12 +2655,10 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
 }
 
 tree
-build_function_call_real (function, params, require_complete, flags)
+build_function_call (function, params)
      tree function, params;
-     int require_complete, flags;
 {
   register tree fntype, fndecl;
-  register tree value_type;
   register tree coerced_params;
   tree result;
   tree name = NULL_TREE, assembler_name = NULL_TREE;
@@ -2731,20 +2729,10 @@ build_function_call_real (function, params, require_complete, flags)
   /* Convert the parameters to the types declared in the
      function prototype, or apply default promotions.  */
 
-  if (flags & LOOKUP_COMPLAIN)
-    coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
-                                       params, fndecl, LOOKUP_NORMAL);
-  else
-    coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
-                                       params, fndecl, 0);
-
+  coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
+                                     params, fndecl, LOOKUP_NORMAL);
   if (coerced_params == error_mark_node)
-    {
-      if (flags & LOOKUP_SPECULATIVELY)
-       return NULL_TREE;
-      else
-       return error_mark_node;
-    }
+    return error_mark_node;
 
   /* Check for errors in format strings.  */
 
@@ -2765,27 +2753,7 @@ build_function_call_real (function, params, require_complete, flags)
        return result;
     }
 
-  /* Some built-in function calls will be evaluated at
-     compile-time in fold ().  */
-  result = fold (build_call (function, coerced_params));
-  value_type = TREE_TYPE (result);
-
-  if (require_complete)
-    {
-      if (TREE_CODE (value_type) == VOID_TYPE)
-       return result;
-      result = require_complete_type (result);
-    }
-  if (IS_AGGR_TYPE (value_type))
-    result = build_cplus_new (value_type, result);
-  return convert_from_reference (result);
-}
-
-tree
-build_function_call (function, params)
-     tree function, params;
-{
-  return build_function_call_real (function, params, 1, LOOKUP_NORMAL);
+  return build_cxx_call (function, params, coerced_params);
 }
 \f
 /* Convert the actual parameter expressions in the list VALUES
@@ -4089,7 +4057,45 @@ condition_conversion (expr)
   t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
   return t;
 }
-                              
+               
+/* Return an ADDR_EXPR giving the address of T.  This function
+   attempts no optimizations or simplifications; it is a low-level
+   primitive.  */
+
+tree
+build_address (tree t)
+{
+  tree addr;
+
+  if (error_operand_p (t) || !cxx_mark_addressable (t))
+    return error_mark_node;
+
+  addr = build1 (ADDR_EXPR, 
+                build_pointer_type (TREE_TYPE (t)),
+                t);
+  if (staticp (t))
+    TREE_CONSTANT (addr) = 1;
+
+  return addr;
+}
+
+/* Return a NOP_EXPR converting EXPR to TYPE.  */
+
+tree
+build_nop (tree type, tree expr)
+{
+  tree nop;
+
+  if (type == error_mark_node || error_operand_p (expr))
+    return expr;
+    
+  nop = build1 (NOP_EXPR, type, expr);
+  if (TREE_CONSTANT (expr))
+    TREE_CONSTANT (nop) = 1;
+  
+  return nop;
+}
+
 /* C++: Must handle pointers to members.
 
    Perhaps type instantiation should be extended to handle conversion
@@ -4423,7 +4429,11 @@ build_unary_op (code, xarg, noconvert)
             We could defer this in non-MS mode, but it's easier to give
             a useful error here.  */
 
-         tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
+         /* Inside constant member functions, the `this' pointer
+            contains an extra const qualifier.  TYPE_MAIN_VARIANT
+            is used here to remove this const from the diagnostics
+            and the created OFFSET_REF.  */
+         tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
          tree name = DECL_NAME (get_first_fn (TREE_OPERAND (arg, 1)));
 
          if (! flag_ms_extensions)
@@ -4431,9 +4441,15 @@ build_unary_op (code, xarg, noconvert)
              if (current_class_type
                  && TREE_OPERAND (arg, 0) == current_class_ref)
                /* An expression like &memfn.  */
-               pedwarn ("ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say `&%T::%D'", base, name);
+               pedwarn ("ISO C++ forbids taking the address of an unqualified"
+                        " or parenthesized non-static member function to form"
+                        " a pointer to member function.  Say `&%T::%D'",
+                        base, name);
              else
-               pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say `&%T::%D'", base, name);
+               pedwarn ("ISO C++ forbids taking the address of a bound member"
+                        " function to form a pointer to member function."
+                        "  Say `&%T::%D'",
+                        base, name);
            }
          arg = build_offset_ref (base, name);
         }
@@ -4479,9 +4495,6 @@ build_unary_op (code, xarg, noconvert)
       if (argtype != error_mark_node)
        argtype = build_pointer_type (argtype);
 
-      if (!cxx_mark_addressable (arg))
-       return error_mark_node;
-
       {
        tree addr;
 
@@ -4489,19 +4502,19 @@ build_unary_op (code, xarg, noconvert)
            && TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
          arg = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
 
-       if (TREE_CODE (arg) == COMPONENT_REF
-           && DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+       if (TREE_CODE (arg) != COMPONENT_REF)
+         addr = build_address (arg);
+       else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
          {
            error ("attempt to take address of bit-field structure member `%D'",
                   TREE_OPERAND (arg, 1));
            return error_mark_node;
          }
-       else if (TREE_CODE (arg) == COMPONENT_REF
-                && TREE_CODE (TREE_OPERAND (arg, 0)) == INDIRECT_REF
-                && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg, 0), 0))
-                    == INTEGER_CST))
+       else
          {
-           /* offsetof idiom, fold it.  */
+           /* Unfortunately we cannot just build an address
+              expression here, because we would not handle
+              address-constant-expressions or offsetof correctly.  */
            tree field = TREE_OPERAND (arg, 1);
            tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
            tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (rval)),
@@ -4514,13 +4527,6 @@ build_unary_op (code, xarg, noconvert)
            addr = fold (build (PLUS_EXPR, argtype, rval,
                                cp_convert (argtype, byte_position (field))));
          }
-       else
-         addr = build1 (ADDR_EXPR, argtype, arg);
-
-       /* Address of a static or external variable or
-          function counts as a constant */
-       if (staticp (arg))
-         TREE_CONSTANT (addr) = 1;
 
        if (TREE_CODE (argtype) == POINTER_TYPE
            && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
@@ -4734,7 +4740,7 @@ cxx_mark_addressable (exp)
          warning ("address requested for `%D', which is declared `register'",
                      x);
        TREE_ADDRESSABLE (x) = 1;
-       put_var_into_stack (x);
+       put_var_into_stack (x, /*rescan=*/true);
        return true;
 
       case FUNCTION_DECL:
@@ -4796,7 +4802,7 @@ build_x_compound_expr (list)
       /* the left-hand operand of a comma expression is like an expression
          statement: we should warn if it doesn't have any side-effects,
          unless it was explicitly cast to (void).  */
-      if ((extra_warnings || warn_unused_value)
+      if (warn_unused_value
            && !(TREE_CODE (TREE_VALUE(list)) == CONVERT_EXPR
                 && VOID_TYPE_P (TREE_TYPE (TREE_VALUE(list)))))
         warning("left-hand operand of comma expression has no effect");
@@ -5329,6 +5335,10 @@ build_modify_expr (lhs, modifycode, rhs)
                    TREE_OPERAND (lhs, 0), newrhs);
 
     case MODIFY_EXPR:
+      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
+       lhs = build (TREE_CODE (lhs), TREE_TYPE (lhs),
+                    stabilize_reference (TREE_OPERAND (lhs, 0)),
+                    TREE_OPERAND (lhs, 1));
       newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
       if (newrhs == error_mark_node)
        return error_mark_node;
@@ -5534,14 +5544,6 @@ build_modify_expr (lhs, modifycode, rhs)
        }
     }
 
-  if (TREE_CODE (lhstype) != REFERENCE_TYPE)
-    {
-      if (TREE_SIDE_EFFECTS (lhs))
-       lhs = stabilize_reference (lhs);
-      if (TREE_SIDE_EFFECTS (newrhs))
-       newrhs = stabilize_reference (newrhs);
-    }
-
   /* Convert new value to destination type.  */
 
   if (TREE_CODE (lhstype) == ARRAY_TYPE)
@@ -5771,7 +5773,7 @@ build_ptrmemfunc1 (type, delta, pfn)
   /* Finish creating the initializer.  */
   u = tree_cons (pfn_field, pfn,
                 build_tree_list (delta_field, delta));
-  u = build (CONSTRUCTOR, type, NULL_TREE, u);
+  u = build_constructor (type, u);
   TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
   TREE_STATIC (u) = (TREE_CONSTANT (u)
                     && (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
@@ -5798,11 +5800,17 @@ build_ptrmemfunc (type, pfn, force)
      int force;
 {
   tree fn;
-  tree pfn_type = TREE_TYPE (pfn);
-  tree to_type = build_ptrmemfunc_type (type);
+  tree pfn_type;
+  tree to_type;
+
+  if (error_operand_p (pfn))
+    return error_mark_node;
+
+  pfn_type = TREE_TYPE (pfn);
+  to_type = build_ptrmemfunc_type (type);
 
   /* Handle multiple conversions of pointer to member functions.  */
-  if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
+  if (TYPE_PTRMEMFUNC_P (pfn_type))
     {
       tree delta = NULL_TREE;
       tree npfn = NULL_TREE;
@@ -6183,7 +6191,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
 
       if (fndecl)
        savew = warningcount, savee = errorcount;
-      rhs = initialize_reference (type, rhs);
+      rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE);
       if (fndecl)
        {
          if (warningcount > savew)
@@ -6562,15 +6570,14 @@ comp_ptr_ttypes_real (to, from, constp)
        }
 
       if (TREE_CODE (to) != POINTER_TYPE)
-       return 
-         same_type_ignoring_top_level_qualifiers_p (to, from)
-         && (constp >= 0 || to_more_cv_qualified);
+       return ((constp >= 0 || to_more_cv_qualified)
+               && same_type_ignoring_top_level_qualifiers_p (to, from));
     }
 }
 
-/* When comparing, say, char ** to char const **, this function takes the
-   'char *' and 'char const *'.  Do not pass non-pointer types to this
-   function.  */
+/* When comparing, say, char ** to char const **, this function takes
+   the 'char *' and 'char const *'.  Do not pass non-pointer/reference
+   types to this function.  */
 
 int
 comp_ptr_ttypes (to, from)