OSDN Git Service

Restore canonical type comparison for dependent type(def)s
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck.c
index a5f3618..5f8d321 100644 (file)
@@ -1,6 +1,6 @@
 /* Build expressions with type checking for C++ compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
@@ -31,10 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "rtl.h"
-#include "expr.h"
 #include "cp-tree.h"
-#include "tm_p.h"
 #include "flags.h"
 #include "output.h"
 #include "toplev.h"
@@ -42,12 +39,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "target.h"
 #include "convert.h"
-#include "c-common.h"
+#include "c-family/c-common.h"
 #include "params.h"
 
 static tree pfn_from_ptrmemfunc (tree);
 static tree delta_from_ptrmemfunc (tree);
-static tree convert_for_assignment (tree, tree, const char *, tree, int,
+static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
                                    tsubst_flags_t, int);
 static tree cp_pointer_int_sum (enum tree_code, tree, tree);
 static tree rationalize_conditional_expr (enum tree_code, tree, 
@@ -56,21 +53,22 @@ static int comp_ptr_ttypes_real (tree, tree, int);
 static bool comp_except_types (tree, tree, bool);
 static bool comp_array_types (const_tree, const_tree, bool);
 static tree pointer_diff (tree, tree, tree);
-static tree get_delta_difference (tree, tree, bool, bool);
+static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
 static void casts_away_constness_r (tree *, tree *);
 static bool casts_away_constness (tree, tree);
 static void maybe_warn_about_returning_address_of_local (tree);
 static tree lookup_destructor (tree, tree, tree);
-static int convert_arguments (int, tree *, tree, tree, tree, int,
+static void warn_args_num (location_t, tree, bool);
+static int convert_arguments (tree, VEC(tree,gc) **, tree, int,
                               tsubst_flags_t);
 
 /* Do `exp = require_complete_type (exp);' to make sure exp
    does not have an incomplete type.  (That includes void types.)
-   Returns the error_mark_node if the VALUE does not have
+   Returns error_mark_node if the VALUE does not have
    complete type when this function returns.  */
 
 tree
-require_complete_type (tree value)
+require_complete_type_sfinae (tree value, tsubst_flags_t complain)
 {
   tree type;
 
@@ -89,12 +87,18 @@ require_complete_type (tree value)
   if (COMPLETE_TYPE_P (type))
     return value;
 
-  if (complete_type_or_else (type, value))
+  if (complete_type_or_maybe_complain (type, value, complain))
     return value;
   else
     return error_mark_node;
 }
 
+tree
+require_complete_type (tree value)
+{
+  return require_complete_type_sfinae (value, tf_warning_or_error);
+}
+
 /* Try to complete TYPE, if it is incomplete.  For example, if TYPE is
    a template instantiation, do the instantiation.  Returns TYPE,
    whether or not it could be completed, unless something goes
@@ -137,7 +141,7 @@ complete_type (tree type)
    Returns NULL_TREE if the type cannot be made complete.  */
 
 tree
-complete_type_or_else (tree type, tree value)
+complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
 {
   type = complete_type (type);
   if (type == error_mark_node)
@@ -145,13 +149,20 @@ complete_type_or_else (tree type, tree value)
     return NULL_TREE;
   else if (!COMPLETE_TYPE_P (type))
     {
-      cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+      if (complain & tf_error)
+       cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
       return NULL_TREE;
     }
   else
     return type;
 }
 
+tree
+complete_type_or_else (tree type, tree value)
+{
+  return complete_type_or_maybe_complain (type, value, tf_warning_or_error);
+}
+
 /* Return truthvalue of whether type of EXP is instantiated.  */
 
 int
@@ -260,6 +271,20 @@ cp_common_type (tree t1, tree t2)
   enum tree_code code2 = TREE_CODE (t2);
   tree attributes;
 
+
+  /* In what follows, we slightly generalize the rules given in [expr] so
+     as to deal with `long long' and `complex'.  First, merge the
+     attributes.  */
+  attributes = (*targetm.merge_type_attributes) (t1, t2);
+
+  if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
+    {
+      if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+       return build_type_attribute_variant (t1, attributes);
+      else
+       return NULL_TREE;
+    }
+
   /* FIXME: Attributes.  */
   gcc_assert (ARITHMETIC_TYPE_P (t1)
              || TREE_CODE (t1) == VECTOR_TYPE
@@ -268,11 +293,6 @@ cp_common_type (tree t1, tree t2)
              || TREE_CODE (t2) == VECTOR_TYPE
              || UNSCOPED_ENUM_P (t2));
 
-  /* In what follows, we slightly generalize the rules given in [expr] so
-     as to deal with `long long' and `complex'.  First, merge the
-     attributes.  */
-  attributes = (*targetm.merge_type_attributes) (t1, t2);
-
   /* If one type is complex, form the common type of the non-complex
      components, then make that complex.  Use T1 or T2 if it is the
      required type.  */
@@ -344,6 +364,17 @@ cp_common_type (tree t1, tree t2)
                    : long_long_integer_type_node);
          return build_type_attribute_variant (t, attributes);
        }
+      if (int128_integer_type_node != NULL_TREE
+         && (same_type_p (TYPE_MAIN_VARIANT (t1),
+                          int128_integer_type_node)
+             || same_type_p (TYPE_MAIN_VARIANT (t2),
+                             int128_integer_type_node)))
+       {
+         tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+                   ? int128_unsigned_type_node
+                   : int128_integer_type_node);
+         return build_type_attribute_variant (t, attributes);
+       }
 
       /* Go through the same procedure, but for longs.  */
       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
@@ -413,10 +444,11 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
 }
 
 /* Subroutine of composite_pointer_type to implement the recursive
-   case.  See that function for documentation fo the parameters.  */
+   case.  See that function for documentation of the parameters.  */
 
 static tree
-composite_pointer_type_r (tree t1, tree t2, const char* location,
+composite_pointer_type_r (tree t1, tree t2, 
+                         composite_pointer_operation operation,
                          tsubst_flags_t complain)
 {
   tree pointee1;
@@ -449,14 +481,33 @@ composite_pointer_type_r (tree t1, tree t2, const char* location,
            && TREE_CODE (pointee2) == POINTER_TYPE)
           || (TYPE_PTR_TO_MEMBER_P (pointee1)
               && TYPE_PTR_TO_MEMBER_P (pointee2)))
-    result_type = composite_pointer_type_r (pointee1, pointee2, location,
+    result_type = composite_pointer_type_r (pointee1, pointee2, operation,
                                            complain);
   else
     {
       if (complain & tf_error)
-       permerror (input_location, "%s between distinct pointer types %qT and %qT "
-                  "lacks a cast",
-                  location, t1, t2);
+        {
+          switch (operation)
+            {
+            case CPO_COMPARISON:
+              permerror (input_location, "comparison between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            case CPO_CONVERSION:
+              permerror (input_location, "conversion between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            case CPO_CONDITIONAL_EXPR:
+              permerror (input_location, "conditional expression between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            default:
+              gcc_unreachable ();
+            }
+        }
       result_type = void_type_node;
     }
   result_type = cp_build_qualified_type (result_type,
@@ -469,9 +520,28 @@ composite_pointer_type_r (tree t1, tree t2, const char* location,
       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
                        TYPE_PTRMEM_CLASS_TYPE (t2))
          && (complain & tf_error))
-       permerror (input_location, "%s between distinct pointer types %qT and %qT "
-                  "lacks a cast",
-                  location, t1, t2);
+        {
+          switch (operation)
+            {
+            case CPO_COMPARISON:
+              permerror (input_location, "comparison between "
+                         "distinct pointer types %qT and %qT lacks a cast", 
+                         t1, t2);
+              break;
+            case CPO_CONVERSION:
+              permerror (input_location, "conversion between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            case CPO_CONDITIONAL_EXPR:
+              permerror (input_location, "conditional expression between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            default:
+              gcc_unreachable ();
+            }
+        }
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
                                       result_type);
     }
@@ -484,15 +554,17 @@ composite_pointer_type_r (tree t1, tree t2, const char* location,
 }
 
 /* Return the composite pointer type (see [expr.rel]) for T1 and T2.
-   ARG1 and ARG2 are the values with those types.  The LOCATION is a
-   string describing the current location, in case an error occurs.
+   ARG1 and ARG2 are the values with those types.  The OPERATION is to
+   describe the operation between the pointer types,
+   in case an error occurs.
 
    This routine also implements the computation of a common type for
    pointers-to-members as per [expr.eq].  */
 
 tree
 composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
-                       const char* location, tsubst_flags_t complain)
+                       composite_pointer_operation operation, 
+                       tsubst_flags_t complain)
 {
   tree class1;
   tree class2;
@@ -531,9 +603,28 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
       tree result_type;
 
       if (TYPE_PTRFN_P (t2) && (complain & tf_error))
-       pedwarn (input_location, OPT_pedantic, "ISO C++ forbids %s "
-                "between pointer of type %<void *%> and pointer-to-function",
-                location);
+        {
+          switch (operation)
+              {
+              case CPO_COMPARISON:
+                pedwarn (input_location, OPT_pedantic, 
+                         "ISO C++ forbids comparison between "
+                         "pointer of type %<void *%> and pointer-to-function");
+                break;
+              case CPO_CONVERSION:
+                pedwarn (input_location, OPT_pedantic,
+                         "ISO C++ forbids conversion between "
+                         "pointer of type %<void *%> and pointer-to-function");
+                break;
+              case CPO_CONDITIONAL_EXPR:
+                pedwarn (input_location, OPT_pedantic,
+                         "ISO C++ forbids conditional expression between "
+                         "pointer of type %<void *%> and pointer-to-function");
+                break;
+              default:
+                gcc_unreachable ();
+              }
+        }
       result_type
        = cp_build_qualified_type (void_type_node,
                                   (cp_type_quals (TREE_TYPE (t1))
@@ -547,8 +638,8 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
   if (c_dialect_objc () && TREE_CODE (t1) == POINTER_TYPE
       && TREE_CODE (t2) == POINTER_TYPE)
     {
-      if (objc_compare_types (t1, t2, -3, NULL_TREE))
-       return t1;
+      if (objc_have_common_type (t1, t2, -3, NULL_TREE))
+       return objc_common_type (t1, t2);
     }
 
   /* [expr.eq] permits the application of a pointer conversion to
@@ -564,22 +655,37 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
 
       if (DERIVED_FROM_P (class1, class2))
        t2 = (build_pointer_type
-             (cp_build_qualified_type (class1, TYPE_QUALS (class2))));
+             (cp_build_qualified_type (class1, cp_type_quals (class2))));
       else if (DERIVED_FROM_P (class2, class1))
        t1 = (build_pointer_type
-             (cp_build_qualified_type (class2, TYPE_QUALS (class1))));
+             (cp_build_qualified_type (class2, cp_type_quals (class1))));
       else
-       {
-         if (complain & tf_error)
-           error ("%s between distinct pointer types %qT and %qT "
-                  "lacks a cast", location, t1, t2);
-         return error_mark_node;
-       }
+        {
+          if (complain & tf_error)
+            switch (operation)
+              {
+              case CPO_COMPARISON:
+                error ("comparison between distinct "
+                       "pointer types %qT and %qT lacks a cast", t1, t2);
+                break;
+              case CPO_CONVERSION:
+                error ("conversion between distinct "
+                       "pointer types %qT and %qT lacks a cast", t1, t2);
+                break;
+              case CPO_CONDITIONAL_EXPR:
+                error ("conditional expression between distinct "
+                       "pointer types %qT and %qT lacks a cast", t1, t2);
+                break;
+              default:
+                gcc_unreachable ();
+              }
+          return error_mark_node;
+        }
     }
   /* [expr.eq] permits the application of a pointer-to-member
      conversion to change the class type of one of the types.  */
   else if (TYPE_PTR_TO_MEMBER_P (t1)
-          && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
+           && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
                            TYPE_PTRMEM_CLASS_TYPE (t2)))
     {
       class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
@@ -590,15 +696,33 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
       else if (DERIVED_FROM_P (class2, class1))
        t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
       else
-       {
-         if (complain & tf_error)
-           error ("%s between distinct pointer-to-member types %qT and %qT "
-                  "lacks a cast", location, t1, t2);
-         return error_mark_node;
-       }
+        {
+          if (complain & tf_error)
+            switch (operation)
+              {
+              case CPO_COMPARISON:
+                error ("comparison between distinct "
+                       "pointer-to-member types %qT and %qT lacks a cast",
+                       t1, t2);
+                break;
+              case CPO_CONVERSION:
+                error ("conversion between distinct "
+                       "pointer-to-member types %qT and %qT lacks a cast",
+                       t1, t2);
+                break;
+              case CPO_CONDITIONAL_EXPR:
+                error ("conditional expression between distinct "
+                       "pointer-to-member types %qT and %qT lacks a cast",
+                       t1, t2);
+                break;
+              default:
+                gcc_unreachable ();
+              }
+          return error_mark_node;
+        }
     }
 
-  return composite_pointer_type_r (t1, t2, location, complain);
+  return composite_pointer_type_r (t1, t2, operation, complain);
 }
 
 /* Return the merged type of two types.
@@ -708,6 +832,7 @@ merge_types (tree t1, tree t2)
        tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
        tree p1 = TYPE_ARG_TYPES (t1);
        tree p2 = TYPE_ARG_TYPES (t2);
+       tree parms;
        tree rval, raises;
 
        /* Save space: see if the result is identical to one of the args.  */
@@ -718,22 +843,17 @@ merge_types (tree t1, tree t2)
 
        /* Simple way if one arg fails to specify argument types.  */
        if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
-         {
-           rval = build_function_type (valtype, p2);
-           if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
-             rval = build_exception_variant (rval, raises);
-           return cp_build_type_attribute_variant (rval, attributes);
-         }
-       raises = TYPE_RAISES_EXCEPTIONS (t1);
-       if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
-         {
-           rval = build_function_type (valtype, p1);
-           if (raises)
-             rval = build_exception_variant (rval, raises);
-           return cp_build_type_attribute_variant (rval, attributes);
-         }
+         parms = p2;
+       else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
+         parms = p1;
+       else
+         parms = commonparms (p1, p2);
 
-       rval = build_function_type (valtype, commonparms (p1, p2));
+       rval = build_function_type (valtype, parms);
+       gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2));
+       rval = apply_memfn_quals (rval, type_memfn_quals (t1));
+       raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
+                                            TYPE_RAISES_EXCEPTIONS (t2));
        t1 = build_exception_variant (rval, raises);
        break;
       }
@@ -743,7 +863,8 @@ merge_types (tree t1, tree t2)
        /* Get this value the long way, since TYPE_METHOD_BASETYPE
           is just the main variant of this.  */
        tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));
-       tree raises = TYPE_RAISES_EXCEPTIONS (t1);
+       tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1),
+                                                 TYPE_RAISES_EXCEPTIONS (t2));
        tree t3;
 
        /* If this was a member function type, get back to the
@@ -777,6 +898,19 @@ merge_types (tree t1, tree t2)
     return cp_build_type_attribute_variant (t1, attributes);
 }
 
+/* Return the ARRAY_TYPE type without its domain.  */
+
+tree
+strip_array_domain (tree type)
+{
+  tree t2;
+  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+  if (TYPE_DOMAIN (type) == NULL_TREE)
+    return type;
+  t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
+  return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type));
+}
+
 /* Wrapper around cp_common_type that is used by c-common.c and other
    front end optimizations that remove promotions.  
 
@@ -812,7 +946,7 @@ common_pointer_type (tree t1, tree t2)
               || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
 
   return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
-                                 "conversion", tf_warning_or_error);
+                                 CPO_CONVERSION, tf_warning_or_error);
 }
 \f
 /* Compare two exception specifier types for exactness or subsetness, if
@@ -861,13 +995,14 @@ comp_except_types (tree a, tree b, bool exact)
 }
 
 /* Return true if TYPE1 and TYPE2 are equivalent exception specifiers.
-   If EXACT is false, T2 can be stricter than T1 (according to 15.4/7),
-   otherwise it must be exact. Exception lists are unordered, but
-   we've already filtered out duplicates. Most lists will be in order,
-   we should try to make use of that.  */
+   If EXACT is ce_derived, T2 can be stricter than T1 (according to 15.4/5).
+   If EXACT is ce_normal, the compatibility rules in 15.4/3 apply.
+   If EXACT is ce_exact, the specs must be exactly the same. Exception lists
+   are unordered, but we've already filtered out duplicates. Most lists will
+   be in order, we should try to make use of that.  */
 
 bool
-comp_except_specs (const_tree t1, const_tree t2, bool exact)
+comp_except_specs (const_tree t1, const_tree t2, int exact)
 {
   const_tree probe;
   const_tree base;
@@ -876,14 +1011,42 @@ comp_except_specs (const_tree t1, const_tree t2, bool exact)
   if (t1 == t2)
     return true;
 
+  /* First handle noexcept.  */
+  if (exact < ce_exact)
+    {
+      /* noexcept(false) is compatible with any throwing dynamic-exc-spec
+        and stricter than any spec.  */
+      if (t1 == noexcept_false_spec)
+       return !nothrow_spec_p (t2) || exact == ce_derived;
+      /* Even a derived noexcept(false) is compatible with a throwing
+        dynamic spec.  */
+      if (t2 == noexcept_false_spec)
+       return !nothrow_spec_p (t1);
+
+      /* Otherwise, if we aren't looking for an exact match, noexcept is
+        equivalent to throw().  */
+      if (t1 == noexcept_true_spec)
+       t1 = empty_except_spec;
+      if (t2 == noexcept_true_spec)
+       t2 = empty_except_spec;
+    }
+
+  /* If any noexcept is left, it is only comparable to itself;
+     either we're looking for an exact match or we're redeclaring a
+     template with dependent noexcept.  */
+  if ((t1 && TREE_PURPOSE (t1))
+      || (t2 && TREE_PURPOSE (t2)))
+    return (t1 && t2
+           && cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)));
+
   if (t1 == NULL_TREE)                    /* T1 is ...  */
-    return t2 == NULL_TREE || !exact;
+    return t2 == NULL_TREE || exact == ce_derived;
   if (!TREE_VALUE (t1))                           /* t1 is EMPTY */
     return t2 != NULL_TREE && !TREE_VALUE (t2);
   if (t2 == NULL_TREE)                    /* T2 is ...  */
     return false;
   if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */
-    return !exact;
+    return exact == ce_derived;
 
   /* Neither set is ... or EMPTY, make sure each part of T2 is in T1.
      Count how many we find, to determine exactness. For exact matching and
@@ -898,7 +1061,7 @@ comp_except_specs (const_tree t1, const_tree t2, bool exact)
 
          if (comp_except_types (a, b, exact))
            {
-             if (probe == base && exact)
+             if (probe == base && exact > ce_derived)
                base = TREE_CHAIN (probe);
              length++;
              break;
@@ -907,7 +1070,7 @@ comp_except_specs (const_tree t1, const_tree t2, bool exact)
       if (probe == NULL_TREE)
        return false;
     }
-  return !exact || base == NULL_TREE || length == list_length (t1);
+  return exact == ce_derived || base == NULL_TREE || length == list_length (t1);
 }
 
 /* Compare the array types T1 and T2.  ALLOW_REDECLARATION is true if
@@ -972,6 +1135,40 @@ comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration)
   return true;
 }
 
+/* Compare the relative position of T1 and T2 into their respective
+   template parameter list.
+   T1 and T2 must be template parameter types.
+   Return TRUE if T1 and T2 have the same position, FALSE otherwise.  */
+
+static bool
+comp_template_parms_position (tree t1, tree t2)
+{
+  tree index1, index2;
+  gcc_assert (t1 && t2
+             && TREE_CODE (t1) == TREE_CODE (t2)
+             && (TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM
+                 || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM
+                 || TREE_CODE (t1) == TEMPLATE_TYPE_PARM));
+
+  index1 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t1));
+  index2 = TEMPLATE_TYPE_PARM_INDEX (TYPE_MAIN_VARIANT (t2));
+
+  /* If T1 and T2 belong to template parm lists of different size,
+     let's assume they are different.  */
+  if (TEMPLATE_PARM_NUM_SIBLINGS (index1)
+      != TEMPLATE_PARM_NUM_SIBLINGS (index2))
+    return false;
+
+  /* Then compare their relative position.  */
+  if (TEMPLATE_PARM_IDX (index1) != TEMPLATE_PARM_IDX (index2)
+      || TEMPLATE_PARM_LEVEL (index1) != TEMPLATE_PARM_LEVEL (index2)
+      || (TEMPLATE_PARM_PARAMETER_PACK (index1)
+         != TEMPLATE_PARM_PARAMETER_PACK (index2)))
+    return false;
+
+  return true;
+}
+
 /* Subroutine in comptypes.  */
 
 static bool
@@ -1006,7 +1203,10 @@ structural_comptypes (tree t1, tree t2, int strict)
   /* Qualifiers must match.  For array types, we will check when we
      recur on the array element types.  */
   if (TREE_CODE (t1) != ARRAY_TYPE
-      && TYPE_QUALS (t1) != TYPE_QUALS (t2))
+      && cp_type_quals (t1) != cp_type_quals (t2))
+    return false;
+  if (TREE_CODE (t1) == FUNCTION_TYPE
+      && type_memfn_quals (t1) != type_memfn_quals (t2))
     return false;
   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
     return false;
@@ -1019,6 +1219,7 @@ structural_comptypes (tree t1, tree t2, int strict)
       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return true;
 
+
   /* Compare the types.  Break out if they could be the same.  */
   switch (TREE_CODE (t1))
     {
@@ -1048,10 +1249,7 @@ structural_comptypes (tree t1, tree t2, int strict)
 
     case TEMPLATE_TEMPLATE_PARM:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
-      if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
-         || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2)
-          || (TEMPLATE_TYPE_PARAMETER_PACK (t1) 
-              != TEMPLATE_TYPE_PARAMETER_PACK (t2)))
+      if (!comp_template_parms_position (t1, t2))
        return false;
       if (!comp_template_parms
          (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
@@ -1113,10 +1311,9 @@ structural_comptypes (tree t1, tree t2, int strict)
       break;
 
     case TEMPLATE_TYPE_PARM:
-      if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
-         || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2)
-          || (TEMPLATE_TYPE_PARAMETER_PACK (t1) 
-              != TEMPLATE_TYPE_PARAMETER_PACK (t2)))
+      /* If T1 and T2 don't have the same relative position in their
+        template parameters set, they can't be equal.  */
+      if (!comp_template_parms_position (t1, t2))
        return false;
       break;
 
@@ -1153,6 +1350,10 @@ structural_comptypes (tree t1, tree t2, int strict)
     case DECLTYPE_TYPE:
       if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t1)
           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2)
+         || (DECLTYPE_FOR_LAMBDA_CAPTURE (t1)
+             != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
+         || (DECLTYPE_FOR_LAMBDA_RETURN (t1)
+             != DECLTYPE_FOR_LAMBDA_RETURN (t2))
           || !cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), 
                              DECLTYPE_TYPE_EXPR (t2)))
         return false;
@@ -1222,6 +1423,18 @@ comptypes (tree t1, tree t2, int strict)
     return structural_comptypes (t1, t2, strict);
 }
 
+/* Returns nonzero iff TYPE1 and TYPE2 are the same type, ignoring
+   top-level qualifiers.  */
+
+bool
+same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
+{
+  if (type1 == error_mark_node || type2 == error_mark_node)
+    return false;
+
+  return same_type_p (TYPE_MAIN_VARIANT (type1), TYPE_MAIN_VARIANT (type2));
+}
+
 /* Returns 1 if TYPE1 is at least as qualified as TYPE2.  */
 
 bool
@@ -1341,7 +1554,7 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
       return value;
     }
 
-  return c_sizeof_or_alignof_type (complete_type (type),
+  return c_sizeof_or_alignof_type (input_location, complete_type (type),
                                   op == SIZEOF_EXPR,
                                   complain);
 }
@@ -1380,6 +1593,15 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
       return e;
     }
 
+  /* To get the size of a static data member declared as an array of
+     unknown bound, we need to instantiate it.  */
+  if (TREE_CODE (e) == VAR_DECL
+      && VAR_HAD_UNKNOWN_BOUND (e)
+      && DECL_TEMPLATE_INSTANTIATION (e))
+    instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);
+
+  e = mark_type_use (e);
+
   if (TREE_CODE (e) == COMPONENT_REF
       && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
       && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
@@ -1435,6 +1657,8 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain)
       return e;
     }
 
+  e = mark_type_use (e);
+
   if (TREE_CODE (e) == VAR_DECL)
     t = size_int (DECL_ALIGN_UNIT (e));
   else if (TREE_CODE (e) == COMPONENT_REF
@@ -1584,7 +1808,9 @@ unlowered_expr_type (const_tree exp)
    in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
    function-to-pointer conversions.  In addition, manifest constants
    are replaced by their values, and bitfield references are converted
-   to their declared types.
+   to their declared types. Note that this function does not perform the
+   lvalue-to-rvalue conversion for class types. If you need that conversion
+   to for class types, then you probably need to use force_rvalue.
 
    Although the returned value is being used as an rvalue, this
    function does not wrap the returned expression in a
@@ -1601,16 +1827,25 @@ decay_conversion (tree exp)
   if (type == error_mark_node)
     return error_mark_node;
 
+  exp = mark_rvalue_use (exp);
+
+  exp = resolve_nondeduced_context (exp);
   if (type_unknown_p (exp))
     {
       cxx_incomplete_type_error (exp, TREE_TYPE (exp));
       return error_mark_node;
     }
 
+  /* FIXME remove? at least need to remember that this isn't really a
+     constant expression if EXP isn't decl_constant_var_p, like with
+     C_MAYBE_CONST_EXPR.  */
   exp = decl_constant_value (exp);
   if (error_operand_p (exp))
     return error_mark_node;
 
+  if (NULLPTR_TYPE_P (type))
+    return nullptr_node;
+
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */
   code = TREE_CODE (type);
@@ -1622,7 +1857,7 @@ decay_conversion (tree exp)
   if (invalid_nonstatic_memfn_p (exp, tf_warning_or_error))
     return error_mark_node;
   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
-    return cp_build_unary_op (ADDR_EXPR, exp, 0, tf_warning_or_error);
+    return cp_build_addr_expr (exp, tf_warning_or_error);
   if (code == ARRAY_TYPE)
     {
       tree adr;
@@ -1657,7 +1892,7 @@ decay_conversion (tree exp)
        }
       /* This way is better for a COMPONENT_REF since it can
         simplify the offset for a component.  */
-      adr = cp_build_unary_op (ADDR_EXPR, exp, 1, tf_warning_or_error);
+      adr = cp_build_addr_expr (exp, tf_warning_or_error);
       return cp_convert (ptrtype, adr);
     }
 
@@ -1677,8 +1912,8 @@ decay_conversion (tree exp)
 
      Non-class rvalues always have cv-unqualified types.  */
   type = TREE_TYPE (exp);
-  if (!CLASS_TYPE_P (type) && cp_type_quals (type))
-    exp = build_nop (TYPE_MAIN_VARIANT (type), exp);
+  if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
+    exp = build_nop (cv_unqualified (type), exp);
 
   return exp;
 }
@@ -1699,10 +1934,14 @@ decay_conversion (tree exp)
 tree
 default_conversion (tree exp)
 {
+  /* Check for target-specific promotions.  */
+  tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
+  if (promoted_type)
+    exp = cp_convert (promoted_type, exp);
   /* Perform the integral promotions first so that bitfield
      expressions (which may promote to "int", even if the bitfield is
      declared "unsigned") are promoted correctly.  */
-  if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
+  else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
     exp = perform_integral_promotions (exp);
   /* Perform the other conversions.  */
   exp = decay_conversion (exp);
@@ -1720,6 +1959,8 @@ perform_integral_promotions (tree expr)
   tree type;
   tree promoted_type;
 
+  expr = mark_rvalue_use (expr);
+
   /* [conv.prom]
 
      If the bitfield has an enumerated type, it is treated as any
@@ -1761,7 +2002,7 @@ string_conv_p (const_tree totype, const_tree exp, int warn)
   else
     {
       /* Is this a string constant which has decayed to 'const char *'?  */
-      t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
+      t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
       if (!same_type_p (TREE_TYPE (exp), t))
        return 0;
       STRIP_NOPS (exp);
@@ -1833,7 +2074,7 @@ lookup_anon_field (tree t, tree type)
 {
   tree field;
 
-  for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
     {
       if (TREE_STATIC (field))
        continue;
@@ -1891,7 +2132,7 @@ build_class_member_access_expr (tree object, tree member,
      complete type).  */
   object_type = TREE_TYPE (object);
   if (!currently_open_class (object_type)
-      && !complete_type_or_else (object_type, object))
+      && !complete_type_or_maybe_complain (object_type, object, complain))
     return error_mark_node;
   if (!CLASS_TYPE_P (object_type))
     {
@@ -1938,7 +2179,7 @@ build_class_member_access_expr (tree object, tree member,
   {
     tree temp = unary_complex_lvalue (ADDR_EXPR, object);
     if (temp)
-      object = cp_build_indirect_ref (temp, NULL, complain);
+      object = cp_build_indirect_ref (temp, RO_NULL, complain);
   }
 
   /* In [expr.ref], there is an explicit list of the valid choices for
@@ -1947,6 +2188,7 @@ build_class_member_access_expr (tree object, tree member,
     {
       /* A static data member.  */
       result = member;
+      mark_exp_read (object);
       /* If OBJECT has side-effects, they are supposed to occur.  */
       if (TREE_SIDE_EFFECTS (object))
        result = build2 (COMPOUND_EXPR, TREE_TYPE (result), object, result);
@@ -2005,9 +2247,9 @@ build_class_member_access_expr (tree object, tree member,
         in various testsuite cases where a null object is passed where a
         vtable access is required.  */
       if (null_object_p && warn_invalid_offsetof
-         && CLASSTYPE_NON_POD_P (object_type)
+         && CLASSTYPE_NON_STD_LAYOUT (object_type)
          && !DECL_FIELD_IS_BASE (member)
-         && !skip_evaluation
+         && cp_unevaluated_operand == 0
          && (complain & tf_warning))
        {
          warning (OPT_Winvalid_offsetof, 
@@ -2260,13 +2502,17 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
        return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
       object = build_non_dependent_expr (object);
     }
-
+  else if (c_dialect_objc ()
+          && TREE_CODE (name) == IDENTIFIER_NODE
+          && (expr = objc_maybe_build_component_ref (object, name)))
+    return expr;
+    
   /* [expr.ref]
 
      The type of the first expression shall be "class object" (of a
      complete type).  */
   if (!currently_open_class (object_type)
-      && !complete_type_or_else (object_type, object))
+      && !complete_type_or_maybe_complain (object_type, object, complain))
     return error_mark_node;
   if (!CLASS_TYPE_P (object_type))
     {
@@ -2319,6 +2565,14 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
          gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE
                      || TREE_CODE (name) == BIT_NOT_EXPR);
 
+         if (constructor_name_p (name, scope))
+           {
+             if (complain & tf_error)
+               error ("cannot call constructor %<%T::%D%> directly",
+                      scope, name);
+             return error_mark_node;
+           }
+
          /* Find the base of OBJECT_TYPE corresponding to SCOPE.  */
          access_path = lookup_base (object_type, scope, ba_check, NULL);
          if (access_path == error_mark_node)
@@ -2417,7 +2671,8 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
                          /*want_type=*/false);
   member_type = cp_build_qualified_type (TREE_TYPE (member),
                                         cp_type_quals (ptrmem_type));
-  return fold_build3 (COMPONENT_REF, member_type,
+  return fold_build3_loc (input_location,
+                     COMPONENT_REF, member_type,
                      ptrmem, member, NULL_TREE);
 }
 
@@ -2429,7 +2684,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
    Must also handle REFERENCE_TYPEs for C++.  */
 
 tree
-build_x_indirect_ref (tree expr, const char *errorstring, 
+build_x_indirect_ref (tree expr, ref_operator errorstring, 
                       tsubst_flags_t complain)
 {
   tree orig_expr = expr;
@@ -2437,6 +2692,10 @@ build_x_indirect_ref (tree expr, const char *errorstring,
 
   if (processing_template_decl)
     {
+      /* Retain the type if we know the operand is a pointer so that
+        describable_type doesn't make auto deduction break.  */
+      if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr)))
+       return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
       if (type_dependent_expression_p (expr))
        return build_min_nt (INDIRECT_REF, expr);
       expr = build_non_dependent_expr (expr);
@@ -2456,13 +2715,13 @@ build_x_indirect_ref (tree expr, const char *errorstring,
 /* Helper function called from c-common.  */
 tree
 build_indirect_ref (location_t loc __attribute__ ((__unused__)),
-                   tree ptr, const char *errorstring)
+                   tree ptr, ref_operator errorstring)
 {
   return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
 }
 
 tree
-cp_build_indirect_ref (tree ptr, const char *errorstring, 
+cp_build_indirect_ref (tree ptr, ref_operator errorstring, 
                        tsubst_flags_t complain)
 {
   tree pointer, type;
@@ -2482,12 +2741,8 @@ cp_build_indirect_ref (tree ptr, const char *errorstring,
       /* [expr.unary.op]
 
         If the type of the expression is "pointer to T," the type
-        of  the  result  is  "T."
-
-        We must use the canonical variant because certain parts of
-        the back end, like fold, do pointer comparisons between
-        types.  */
-      tree t = canonical_type_variant (TREE_TYPE (type));
+        of  the  result  is  "T."  */
+      tree t = TREE_TYPE (type);
 
       if (CONVERT_EXPR_P (ptr)
           || TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
@@ -2534,14 +2789,38 @@ cp_build_indirect_ref (tree ptr, const char *errorstring,
   /* `pointer' won't be an error_mark_node if we were given a
      pointer to member, so it's cool to check for this here.  */
   else if (TYPE_PTR_TO_MEMBER_P (type))
-    error ("invalid use of %qs on pointer to member", errorstring);
+    switch (errorstring)
+      {
+         case RO_ARRAY_INDEXING:
+           error ("invalid use of array indexing on pointer to member");
+           break;
+         case RO_UNARY_STAR:
+           error ("invalid use of unary %<*%> on pointer to member");
+           break;
+         case RO_IMPLICIT_CONVERSION:
+           error ("invalid use of implicit conversion on pointer to member");
+           break;
+         default:
+           gcc_unreachable ();
+      }
   else if (pointer != error_mark_node)
-    {
-      if (errorstring)
-       error ("invalid type argument of %qs", errorstring);
-      else
-       error ("invalid type argument");
-    }
+    switch (errorstring)
+      {
+         case RO_NULL:
+           error ("invalid type argument");
+           break;
+         case RO_ARRAY_INDEXING:
+           error ("invalid type argument of array indexing");
+           break;
+         case RO_UNARY_STAR:
+           error ("invalid type argument of unary %<*%>");
+           break;
+         case RO_IMPLICIT_CONVERSION:
+           error ("invalid type argument of implicit conversion");
+           break;
+         default:
+           gcc_unreachable ();
+      }
   return error_mark_node;
 }
 
@@ -2561,13 +2840,15 @@ cp_build_indirect_ref (tree ptr, const char *errorstring,
    LOC is the location to use in building the array reference.  */
 
 tree
-build_array_ref (tree array, tree idx, location_t loc)
+cp_build_array_ref (location_t loc, tree array, tree idx,
+                   tsubst_flags_t complain)
 {
   tree ret;
 
   if (idx == 0)
     {
-      error_at (loc, "subscript missing in array reference");
+      if (complain & tf_error)
+       error_at (loc, "subscript missing in array reference");
       return error_mark_node;
     }
 
@@ -2581,7 +2862,8 @@ build_array_ref (tree array, tree idx, location_t loc)
     {
     case COMPOUND_EXPR:
       {
-       tree value = build_array_ref (TREE_OPERAND (array, 1), idx, loc);
+       tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
+                                        complain);
        ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
                      TREE_OPERAND (array, 0), value);
        SET_EXPR_LOCATION (ret, loc);
@@ -2591,9 +2873,11 @@ build_array_ref (tree array, tree idx, location_t loc)
     case COND_EXPR:
       ret = build_conditional_expr
              (TREE_OPERAND (array, 0),
-             build_array_ref (TREE_OPERAND (array, 1), idx, loc),
-             build_array_ref (TREE_OPERAND (array, 2), idx, loc),
-             tf_warning_or_error);
+              cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
+                                  complain),
+              cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
+                                  complain),
+              tf_warning_or_error);
       protected_set_expr_location (ret, loc);
       return ret;
 
@@ -2609,7 +2893,8 @@ build_array_ref (tree array, tree idx, location_t loc)
 
       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
        {
-         error_at (loc, "array subscript is not an integer");
+         if (complain & tf_error)
+           error_at (loc, "array subscript is not an integer");
          return error_mark_node;
        }
 
@@ -2645,7 +2930,7 @@ build_array_ref (tree array, tree idx, location_t loc)
            return error_mark_node;
        }
 
-      if (!lvalue_p (array))
+      if (!lvalue_p (array) && (complain & tf_error))
        pedwarn (loc, OPT_pedantic, 
                 "ISO C++ forbids subscripting non-lvalue array");
 
@@ -2657,7 +2942,8 @@ build_array_ref (tree array, tree idx, location_t loc)
          tree foo = array;
          while (TREE_CODE (foo) == COMPONENT_REF)
            foo = TREE_OPERAND (foo, 0);
-         if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
+         if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)
+             && (complain & tf_warning))
            warning_at (loc, OPT_Wextra,
                        "subscripting array declared %<register%>");
        }
@@ -2672,7 +2958,8 @@ build_array_ref (tree array, tree idx, location_t loc)
        |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
       TREE_THIS_VOLATILE (rval)
        |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
-      ret = require_complete_type (fold_if_not_in_template (rval));
+      ret = require_complete_type_sfinae (fold_if_not_in_template (rval),
+                                         complain);
       protected_set_expr_location (ret, loc);
       return ret;
     }
@@ -2694,12 +2981,14 @@ build_array_ref (tree array, tree idx, location_t loc)
 
     if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE)
       {
-       error_at (loc, "subscripted value is neither array nor pointer");
+       if (complain & tf_error)
+         error_at (loc, "subscripted value is neither array nor pointer");
        return error_mark_node;
       }
     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
       {
-       error_at (loc, "array subscript is not an integer");
+       if (complain & tf_error)
+         error_at (loc, "array subscript is not an integer");
        return error_mark_node;
       }
 
@@ -2707,13 +2996,21 @@ build_array_ref (tree array, tree idx, location_t loc)
 
     ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
                                                     PLUS_EXPR, ar, ind,
-                                                    tf_warning_or_error),
-                                 "array indexing",
-                                 tf_warning_or_error);
+                                                    complain),
+                                 RO_ARRAY_INDEXING,
+                                 complain);
     protected_set_expr_location (ret, loc);
     return ret;
   }
 }
+
+/* Entry point for Obj-C++.  */
+
+tree
+build_array_ref (location_t loc, tree array, tree idx)
+{
+  return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
+}
 \f
 /* Resolve a pointer to member function.  INSTANCE is the object
    instance to use, if the member points to a virtual member.
@@ -2817,24 +3114,24 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
       /* Next extract the vtable pointer from the object.  */
       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
                     instance_ptr);
-      vtbl = cp_build_indirect_ref (vtbl, NULL, tf_warning_or_error);
+      vtbl = cp_build_indirect_ref (vtbl, RO_NULL, tf_warning_or_error);
       /* If the object is not dynamic the access invokes undefined
         behavior.  As it is not executed in this case silence the
         spurious warnings it may provoke.  */
       TREE_NO_WARNING (vtbl) = 1;
 
       /* Finally, extract the function pointer from the vtable.  */
-      e2 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
+      e2 = fold_build2_loc (input_location,
+                       POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
                        fold_convert (sizetype, idx));
-      e2 = cp_build_indirect_ref (e2, NULL, tf_warning_or_error);
+      e2 = cp_build_indirect_ref (e2, RO_NULL, tf_warning_or_error);
       TREE_CONSTANT (e2) = 1;
 
       /* When using function descriptors, the address of the
         vtable entry is treated as a function pointer.  */
       if (TARGET_VTABLE_USES_DESCRIPTORS)
        e2 = build1 (NOP_EXPR, TREE_TYPE (e2),
-                    cp_build_unary_op (ADDR_EXPR, e2, /*noconvert=*/1,
-                                     tf_warning_or_error));
+                    cp_build_addr_expr (e2, tf_warning_or_error));
 
       e2 = fold_convert (TREE_TYPE (e3), e2);
       e1 = build_conditional_expr (e1, e2, e3, tf_warning_or_error);
@@ -2852,48 +3149,87 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
 
 /* Used by the C-common bits.  */
 tree
-build_function_call (tree function, tree params)
+build_function_call (location_t loc ATTRIBUTE_UNUSED, 
+                    tree function, tree params)
 {
   return cp_build_function_call (function, params, tf_warning_or_error);
 }
 
 /* Used by the C-common bits.  */
 tree
-build_function_call_vec (tree function, VEC(tree,gc) *params,
+build_function_call_vec (location_t loc ATTRIBUTE_UNUSED,
+                        tree function, VEC(tree,gc) *params,
                         VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
 {
-  tree p;
-  tree *pp;
-  unsigned int i;
-  tree t;
+  VEC(tree,gc) *orig_params = params;
+  tree ret = cp_build_function_call_vec (function, &params,
+                                        tf_warning_or_error);
 
-  /* FIXME: Should just change cp_build_function_call to use a
-     VEC.  */
-  p = NULL_TREE;
-  pp = &p;
-  for (i = 0; VEC_iterate (tree, params, i, t); ++i)
-    {
-      *pp = build_tree_list (NULL, t);
-      pp = &TREE_CHAIN (*pp);
-    }
-  return cp_build_function_call (function, p, tf_warning_or_error);
+  /* cp_build_function_call_vec can reallocate PARAMS by adding
+     default arguments.  That should never happen here.  Verify
+     that.  */
+  gcc_assert (params == orig_params);
+
+  return ret;
 }
 
+/* Build a function call using a tree list of arguments.  */
+
 tree
 cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
 {
+  VEC(tree,gc) *vec;
+  tree ret;
+
+  vec = make_tree_vector ();
+  for (; params != NULL_TREE; params = TREE_CHAIN (params))
+    VEC_safe_push (tree, gc, vec, TREE_VALUE (params));
+  ret = cp_build_function_call_vec (function, &vec, complain);
+  release_tree_vector (vec);
+  return ret;
+}
+
+/* Build a function call using varargs.  */
+
+tree
+cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
+{
+  VEC(tree,gc) *vec;
+  va_list args;
+  tree ret, t;
+
+  vec = make_tree_vector ();
+  va_start (args, complain);
+  for (t = va_arg (args, tree); t != NULL_TREE; t = va_arg (args, tree))
+    VEC_safe_push (tree, gc, vec, t);
+  va_end (args);
+  ret = cp_build_function_call_vec (function, &vec, complain);
+  release_tree_vector (vec);
+  return ret;
+}
+
+/* Build a function call using a vector of arguments.  PARAMS may be
+   NULL if there are no parameters.  This changes the contents of
+   PARAMS.  */
+
+tree
+cp_build_function_call_vec (tree function, VEC(tree,gc) **params,
+                           tsubst_flags_t complain)
+{
   tree fntype, fndecl;
-  tree name = NULL_TREE;
   int is_method;
   tree original = function;
-  int nargs, parm_types_len;
+  int nargs;
   tree *argarray;
   tree parm_types;
+  VEC(tree,gc) *allocated = NULL;
+  tree ret;
 
   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
      expressions, like those used for ObjC messenger dispatches.  */
-  if (params != NULL_TREE)
-    function = objc_rewrite_function_call (function, TREE_VALUE (params));
+  if (params != NULL && !VEC_empty (tree, *params))
+    function = objc_rewrite_function_call (function,
+                                          VEC_index (tree, *params, 0));
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context.  */
@@ -2903,8 +3239,6 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
 
   if (TREE_CODE (function) == FUNCTION_DECL)
     {
-      name = DECL_NAME (function);
-
       mark_used (function);
       fndecl = function;
 
@@ -2953,81 +3287,111 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
   fntype = TREE_TYPE (fntype);
   parm_types = TYPE_ARG_TYPES (fntype);
 
-  /* Allocate storage for converted arguments.  */
-  parm_types_len = list_length (parm_types);
-  nargs = list_length (params);
-  if (parm_types_len > nargs)
-    nargs = parm_types_len;
-  argarray = (tree *) alloca (nargs * sizeof (tree));
-
-  /* Convert the parameters to the types declared in the
-     function prototype, or apply default promotions.  */
-  nargs = convert_arguments (nargs, argarray, parm_types,
-                            params, fndecl, LOOKUP_NORMAL,
-                             complain);
+  if (params == NULL)
+    {
+      allocated = make_tree_vector ();
+      params = &allocated;
+    }
+
+  nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
+                            complain);
   if (nargs < 0)
     return error_mark_node;
 
+  argarray = VEC_address (tree, *params);
+
   /* Check for errors in format strings and inappropriately
      null parameters.  */
   check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
                            parm_types);
 
-  return build_cxx_call (function, nargs, argarray);
+  ret = build_cxx_call (function, nargs, argarray);
+
+  if (allocated != NULL)
+    release_tree_vector (allocated);
+
+  return ret;
 }
 \f
-/* Convert the actual parameter expressions in the list VALUES
-   to the types in the list TYPELIST.
+/* Subroutine of convert_arguments.
+   Warn about wrong number of args are genereted. */
+
+static void
+warn_args_num (location_t loc, tree fndecl, bool too_many_p)
+{
+  if (fndecl)
+    {
+      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
+       {
+         if (DECL_NAME (fndecl) == NULL_TREE
+             || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
+           error_at (loc,
+                     too_many_p
+                     ? G_("too many arguments to constructor %q#D")
+                     : G_("too few arguments to constructor %q#D"),
+                     fndecl);
+         else
+           error_at (loc,
+                     too_many_p
+                     ? G_("too many arguments to member function %q#D")
+                     : G_("too few arguments to member function %q#D"),
+                     fndecl);
+       }
+      else
+       error_at (loc,
+                 too_many_p
+                 ? G_("too many arguments to function %q#D")
+                 : G_("too few arguments to function %q#D"),
+                 fndecl);
+      inform (DECL_SOURCE_LOCATION (fndecl),
+             "declared here");
+    }
+  else
+    {
+      if (c_dialect_objc ()  &&  objc_message_selector ())
+       error_at (loc,
+                 too_many_p 
+                 ? G_("too many arguments to method %q#D")
+                 : G_("too few arguments to method %q#D"),
+                 objc_message_selector ());
+      else
+       error_at (loc, too_many_p ? G_("too many arguments to function")
+                                 : G_("too few arguments to function"));
+    }
+}
+
+/* Convert the actual parameter expressions in the list VALUES to the
+   types in the list TYPELIST.  The converted expressions are stored
+   back in the VALUES vector.
    If parmdecls is exhausted, or when an element has NULL as its type,
    perform the default conversions.
 
-   Store the converted arguments in ARGARRAY.  NARGS is the size of this array.
-
    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
 
    This is also where warnings about wrong number of args are generated.
 
    Returns the actual number of arguments processed (which might be less
-   than NARGS), or -1 on error.
-
-   VALUES is a chain of TREE_LIST nodes with the elements of the list
-   in the TREE_VALUE slots of those nodes.
+   than the length of the vector), or -1 on error.
 
    In C++, unspecified trailing parameters can be filled in with their
    default arguments, if such were specified.  Do so here.  */
 
 static int
-convert_arguments (int nargs, tree *argarray,
-                  tree typelist, tree values, tree fndecl, int flags,
-                   tsubst_flags_t complain)
+convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
+                  int flags, tsubst_flags_t complain)
 {
-  tree typetail, valtail;
-  const char *called_thing = 0;
-  int i = 0;
+  tree typetail;
+  unsigned int i;
 
   /* Argument passing is always copy-initialization.  */
   flags |= LOOKUP_ONLYCONVERTING;
 
-  if (fndecl)
-    {
-      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
-       {
-         if (DECL_NAME (fndecl) == NULL_TREE
-             || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
-           called_thing = "constructor";
-         else
-           called_thing = "member function";
-       }
-      else
-       called_thing = "function";
-    }
-
-  for (valtail = values, typetail = typelist;
-       valtail;
-       valtail = TREE_CHAIN (valtail), i++)
+  for (i = 0, typetail = typelist;
+       i < VEC_length (tree, *values);
+       i++)
     {
       tree type = typetail ? TREE_VALUE (typetail) : 0;
-      tree val = TREE_VALUE (valtail);
+      tree val = VEC_index (tree, *values, i);
 
       if (val == error_mark_node || type == error_mark_node)
        return -1;
@@ -3036,14 +3400,7 @@ convert_arguments (int nargs, tree *argarray,
        {
           if (complain & tf_error)
             {
-              if (fndecl)
-                {
-                  error ("too many arguments to %s %q+#D", 
-                         called_thing, fndecl);
-                  error ("at this point in file");
-                }
-              else
-                error ("too many arguments to function");
+             warn_args_num (input_location, fndecl, /*too_many_p=*/true);
               return i;
             }
           else
@@ -3089,27 +3446,27 @@ convert_arguments (int nargs, tree *argarray,
            {
              parmval = convert_for_initialization
                (NULL_TREE, type, val, flags,
-                "argument passing", fndecl, i, complain);
+                ICR_ARGPASS, fndecl, i, complain);
              parmval = convert_for_arg_passing (type, parmval);
            }
 
          if (parmval == error_mark_node)
            return -1;
 
-         argarray[i] = parmval;
+         VEC_replace (tree, *values, i, parmval);
        }
       else
        {
          if (fndecl && DECL_BUILT_IN (fndecl)
              && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
            /* Don't do ellipsis conversion for __built_in_constant_p
-              as this will result in spurious warnings for non-POD
+              as this will result in spurious errors for non-trivial
               types.  */
-           val = require_complete_type (val);
+           val = require_complete_type_sfinae (val, complain);
          else
            val = convert_arg_to_ellipsis (val);
 
-         argarray[i] = val;
+         VEC_replace (tree, *values, i, val);
        }
 
       if (typetail)
@@ -3138,7 +3495,7 @@ convert_arguments (int nargs, tree *argarray,
              if (parmval == error_mark_node)
                return -1;
 
-             argarray[i] = parmval;
+             VEC_safe_push (tree, gc, *values, parmval);
              typetail = TREE_CHAIN (typetail);
              /* ends with `...'.  */
              if (typetail == NULL_TREE)
@@ -3148,22 +3505,12 @@ convert_arguments (int nargs, tree *argarray,
       else
        {
           if (complain & tf_error)
-            {
-              if (fndecl)
-                {
-                  error ("too few arguments to %s %q+#D", 
-                         called_thing, fndecl);
-                  error ("at this point in file");
-                }
-              else
-                error ("too few arguments to function");
-            }
+           warn_args_num (input_location, fndecl, /*too_many_p=*/false);
          return -1;
        }
     }
 
-  gcc_assert (i <= nargs);
-  return i;
+  return (int) i;
 }
 \f
 /* Build a binary-operation expression, after performing default
@@ -3208,6 +3555,7 @@ build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
      misinterpret.  But don't warn about obj << x + y, since that is a
      common idiom for I/O.  */
   if (warn_parentheses
+      && (complain & tf_warning)
       && !processing_template_decl
       && !error_operand_p (arg1)
       && !error_operand_p (arg2)
@@ -3389,7 +3737,6 @@ cp_build_binary_op (location_t location,
 
   /* If an error was already reported for one of the arguments,
      avoid reporting another error.  */
-
   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
     return error_mark_node;
 
@@ -3400,6 +3747,25 @@ cp_build_binary_op (location_t location,
       return error_mark_node;
     }
 
+  /* Issue warnings about peculiar, but valid, uses of NULL.  */
+  if ((orig_op0 == null_node || orig_op1 == null_node)
+      /* It's reasonable to use pointer values as operands of &&
+        and ||, so NULL is no exception.  */
+      && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR 
+      && ( /* Both are NULL (or 0) and the operation was not a
+             comparison or a pointer subtraction.  */
+         (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1) 
+          && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR) 
+         /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
+         || (!null_ptr_cst_p (orig_op0)
+             && !TYPE_PTR_P (type0) && !TYPE_PTR_TO_MEMBER_P (type0))
+         || (!null_ptr_cst_p (orig_op1) 
+             && !TYPE_PTR_P (type1) && !TYPE_PTR_TO_MEMBER_P (type1)))
+      && (complain & tf_warning))
+    /* Some sort of arithmetic operation involving NULL was
+       performed.  */
+    warning (OPT_Wpointer_arith, "NULL used in arithmetic");
+
   switch (code)
     {
     case MINUS_EXPR:
@@ -3529,13 +3895,15 @@ cp_build_binary_op (location_t location,
            {
              if (tree_int_cst_lt (op1, integer_zero_node))
                {
-                 if (complain & tf_warning)
+                 if ((complain & tf_warning)
+                     && c_inhibit_evaluation_warnings == 0)
                    warning (0, "right shift count is negative");
                }
              else
                {
                  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0
-                     && (complain & tf_warning))
+                     && (complain & tf_warning)
+                     && c_inhibit_evaluation_warnings == 0)
                    warning (0, "right shift count >= width of type");
                }
            }
@@ -3556,12 +3924,14 @@ cp_build_binary_op (location_t location,
            {
              if (tree_int_cst_lt (op1, integer_zero_node))
                {
-                 if (complain & tf_warning)
+                 if ((complain & tf_warning)
+                     && c_inhibit_evaluation_warnings == 0)
                    warning (0, "left shift count is negative");
                }
              else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
                {
-                 if (complain & tf_warning)
+                 if ((complain & tf_warning)
+                     && c_inhibit_evaluation_warnings == 0)
                    warning (0, "left shift count >= width of type");
                }
            }
@@ -3616,14 +3986,14 @@ cp_build_binary_op (location_t location,
 
       build_type = boolean_type_node;
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
-          || code0 == COMPLEX_TYPE)
+          || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-             || code1 == COMPLEX_TYPE))
+             || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
        short_compare = 1;
       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
               || (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1)))
        result_type = composite_pointer_type (type0, type1, op0, op1,
-                                             "comparison", complain);
+                                             CPO_COMPARISON, complain);
       else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
               && null_ptr_cst_p (op1))
        {
@@ -3648,6 +4018,9 @@ cp_build_binary_op (location_t location,
            }
          result_type = type1;
        }
+      else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
+       /* One of the operands must be of nullptr_t type.  */
+        result_type = TREE_TYPE (nullptr_node);
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
@@ -3712,8 +4085,8 @@ cp_build_binary_op (location_t location,
          tree delta0;
          tree delta1;
 
-         type = composite_pointer_type (type0, type1, op0, op1, "comparison",
-                                        complain);
+         type = composite_pointer_type (type0, type1, op0, op1, 
+                                        CPO_COMPARISON, complain);
 
          if (!same_type_p (TREE_TYPE (op0), type))
            op0 = cp_convert_and_check (type, op0);
@@ -3824,7 +4197,7 @@ cp_build_binary_op (location_t location,
        shorten = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        result_type = composite_pointer_type (type0, type1, op0, op1,
-                                             "comparison", complain);
+                                             CPO_COMPARISON, complain);
       break;
 
     case LE_EXPR:
@@ -3839,18 +4212,21 @@ cp_build_binary_op (location_t location,
        }
 
       build_type = boolean_type_node;
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
-          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+          || code0 == ENUMERAL_TYPE)
+          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+              || code1 == ENUMERAL_TYPE))
        short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        result_type = composite_pointer_type (type0, type1, op0, op1,
-                                             "comparison", complain);
-      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
-              && integer_zerop (op1))
+                                             CPO_COMPARISON, complain);
+      else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
        result_type = type0;
-      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
-              && integer_zerop (op0))
+      else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
        result_type = type1;
+      else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
+       /* One of the operands must be of nullptr_t type.  */
+        result_type = TREE_TYPE (nullptr_node);
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
@@ -3890,9 +4266,10 @@ cp_build_binary_op (location_t location,
       break;
     }
 
-  if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+  if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
+       || code0 == ENUMERAL_TYPE)
        && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-          || code1 == COMPLEX_TYPE)))
+          || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
     arithmetic_types_p = 1;
   else
     {
@@ -3914,7 +4291,14 @@ cp_build_binary_op (location_t location,
   if (!result_type
       && arithmetic_types_p
       && (shorten || common || short_compare))
-    result_type = cp_common_type (type0, type1);
+    {
+      result_type = cp_common_type (type0, type1);
+      do_warn_double_promotion (result_type, type0, type1,
+                               "implicit conversion from %qT to %qT "
+                               "to match other operand of binary "
+                               "expression",
+                               location);
+    }
 
   if (!result_type)
     {
@@ -3941,7 +4325,83 @@ cp_build_binary_op (location_t location,
 
   if (arithmetic_types_p)
     {
-      int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
+      bool first_complex = (code0 == COMPLEX_TYPE);
+      bool second_complex = (code1 == COMPLEX_TYPE);
+      int none_complex = (!first_complex && !second_complex);
+
+      /* Adapted from patch for c/24581.  */
+      if (first_complex != second_complex
+         && (code == PLUS_EXPR
+             || code == MINUS_EXPR
+             || code == MULT_EXPR
+             || (code == TRUNC_DIV_EXPR && first_complex))
+         && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
+         && flag_signed_zeros)
+       {
+         /* An operation on mixed real/complex operands must be
+            handled specially, but the language-independent code can
+            more easily optimize the plain complex arithmetic if
+            -fno-signed-zeros.  */
+         tree real_type = TREE_TYPE (result_type);
+         tree real, imag;
+         if (first_complex)
+           {
+             if (TREE_TYPE (op0) != result_type)
+               op0 = cp_convert_and_check (result_type, op0);
+             if (TREE_TYPE (op1) != real_type)
+               op1 = cp_convert_and_check (real_type, op1);
+           }
+         else
+           {
+             if (TREE_TYPE (op0) != real_type)
+               op0 = cp_convert_and_check (real_type, op0);
+             if (TREE_TYPE (op1) != result_type)
+               op1 = cp_convert_and_check (result_type, op1);
+           }
+         if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
+           return error_mark_node;
+         if (first_complex)
+           {
+             op0 = save_expr (op0);
+             real = cp_build_unary_op (REALPART_EXPR, op0, 1, complain);
+             imag = cp_build_unary_op (IMAGPART_EXPR, op0, 1, complain);
+             switch (code)
+               {
+               case MULT_EXPR:
+               case TRUNC_DIV_EXPR:
+                 imag = build2 (resultcode, real_type, imag, op1);
+                 /* Fall through.  */
+               case PLUS_EXPR:
+               case MINUS_EXPR:
+                 real = build2 (resultcode, real_type, real, op1);
+                 break;
+               default:
+                 gcc_unreachable();
+               }
+           }
+         else
+           {
+             op1 = save_expr (op1);
+             real = cp_build_unary_op (REALPART_EXPR, op1, 1, complain);
+             imag = cp_build_unary_op (IMAGPART_EXPR, op1, 1, complain);
+             switch (code)
+               {
+               case MULT_EXPR:
+                 imag = build2 (resultcode, real_type, op0, imag);
+                 /* Fall through.  */
+               case PLUS_EXPR:
+                 real = build2 (resultcode, real_type, op0, real);
+                 break;
+               case MINUS_EXPR:
+                 real = build2 (resultcode, real_type, op0, real);
+                 imag = build1 (NEGATE_EXPR, real_type, imag);
+                 break;
+               default:
+                 gcc_unreachable();
+               }
+           }
+         return build2 (COMPLEX_EXPR, result_type, real, imag);
+       }
 
       /* For certain operations (which identify themselves by shorten != 0)
         if both args were extended from the same smaller type,
@@ -3983,35 +4443,19 @@ cp_build_binary_op (location_t location,
 
       if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
          && warn_sign_compare
+         && !TREE_NO_WARNING (orig_op0)
+         && !TREE_NO_WARNING (orig_op1)
          /* Do not warn until the template is instantiated; we cannot
             bound the ranges of the arguments until that point.  */
          && !processing_template_decl
-          && (complain & tf_warning))
+          && (complain & tf_warning)
+         && c_inhibit_evaluation_warnings == 0)
        {
          warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1, 
                                 result_type, resultcode);
        }
     }
 
-  /* Issue warnings about peculiar, but valid, uses of NULL.  */
-  if ((orig_op0 == null_node || orig_op1 == null_node)
-      /* It's reasonable to use pointer values as operands of &&
-        and ||, so NULL is no exception.  */
-      && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR 
-      && ( /* Both are NULL (or 0) and the operation was not a comparison.  */
-         (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1) 
-          && code != EQ_EXPR && code != NE_EXPR) 
-         /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
-         || (!null_ptr_cst_p (orig_op0) && TREE_CODE (TREE_TYPE (op0)) != POINTER_TYPE)
-         || (!null_ptr_cst_p (orig_op1) && TREE_CODE (TREE_TYPE (op1)) != POINTER_TYPE))
-      && (complain & tf_warning))
-    /* Some sort of arithmetic operation involving NULL was
-       performed.  Note that pointer-difference and pointer-addition
-       have already been handled above, and so we don't end up here in
-       that case.  */
-    warning (OPT_Wpointer_arith, "NULL used in arithmetic");
-  
-
   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
      Then the expression will be built.
      It will be given type FINAL_TYPE if that is nonzero;
@@ -4038,7 +4482,7 @@ cp_build_binary_op (location_t location,
   if (TREE_OVERFLOW_P (result) 
       && !TREE_OVERFLOW_P (op0) 
       && !TREE_OVERFLOW_P (op1))
-    overflow_warning (result);
+    overflow_warning (location, result);
 
   return result;
 }
@@ -4058,7 +4502,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
      pointer_int_sum() anyway.  */
   complete_type (TREE_TYPE (res_type));
 
-  return pointer_int_sum (resultcode, ptrop,
+  return pointer_int_sum (input_location, resultcode, ptrop,
                          fold_if_not_in_template (intop));
 }
 
@@ -4150,9 +4594,10 @@ build_x_unary_op (enum tree_code code, tree xarg, tsubst_flags_t complain)
          tree fn = get_first_fn (xarg);
          if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
            {
-             const char *type =
-               (DECL_CONSTRUCTOR_P (fn) ? "constructor" : "destructor");
-             error ("taking address of %s %qE", type, xarg);
+             error (DECL_CONSTRUCTOR_P (fn)
+                     ? G_("taking address of constructor %qE")
+                     : G_("taking address of destructor %qE"),
+                     xarg);
              return error_mark_node;
            }
        }
@@ -4195,9 +4640,8 @@ build_x_unary_op (enum tree_code code, tree xarg, tsubst_flags_t complain)
              PTRMEM_OK_P (xarg) = ptrmem;
            }
        }
-      else if (TREE_CODE (xarg) == TARGET_EXPR && (complain & tf_warning))
-       warning (0, "taking address of temporary");
-      exp = cp_build_unary_op (ADDR_EXPR, xarg, 0, complain);
+
+      exp = cp_build_addr_expr_strict (xarg, complain);
     }
 
   if (processing_template_decl && exp != error_mark_node)
@@ -4231,39 +4675,330 @@ condition_conversion (tree expr)
   tree t;
   if (processing_template_decl)
     return expr;
-  t = perform_implicit_conversion (boolean_type_node, expr, 
-                                  tf_warning_or_error);
+  t = perform_implicit_conversion_flags (boolean_type_node, expr,
+                                        tf_warning_or_error, LOOKUP_NORMAL);
   t = fold_build_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.  */
+/* Returns the address of T.  This function will fold away
+   ADDR_EXPR of INDIRECT_REF.  */
 
 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);
-
-  return addr;
+  t = build_fold_addr_expr (t);
+  if (TREE_CODE (t) != ADDR_EXPR)
+    t = rvalue (t);
+  return t;
 }
 
-/* Return a NOP_EXPR converting EXPR to TYPE.  */
+/* Returns the address of T with type TYPE.  */
 
 tree
-build_nop (tree type, tree expr)
+build_typed_address (tree t, tree type)
 {
-  if (type == error_mark_node || error_operand_p (expr))
+  if (error_operand_p (t) || !cxx_mark_addressable (t))
+    return error_mark_node;
+  t = build_fold_addr_expr_with_type (t, type);
+  if (TREE_CODE (t) != ADDR_EXPR)
+    t = rvalue (t);
+  return t;
+}
+
+/* Return a NOP_EXPR converting EXPR to TYPE.  */
+
+tree
+build_nop (tree type, tree expr)
+{
+  if (type == error_mark_node || error_operand_p (expr))
     return expr;
   return build1 (NOP_EXPR, type, expr);
 }
 
+/* Take the address of ARG, whatever that means under C++ semantics.
+   If STRICT_LVALUE is true, require an lvalue; otherwise, allow xvalues
+   and class rvalues as well.
+
+   Nothing should call this function directly; instead, callers should use
+   cp_build_addr_expr or cp_build_addr_expr_strict.  */
+
+static tree
+cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
+{
+  tree argtype;
+  tree val;
+
+  if (!arg || error_operand_p (arg))
+    return error_mark_node;
+
+  arg = mark_lvalue_use (arg);
+  argtype = lvalue_type (arg);
+
+  gcc_assert (TREE_CODE (arg) != IDENTIFIER_NODE
+             || !IDENTIFIER_OPNAME_P (arg));
+
+  if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
+      && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
+    {
+      /* They're trying to take the address of a unique non-static
+        member function.  This is ill-formed (except in MS-land),
+        but let's try to DTRT.
+        Note: We only handle unique functions here because we don't
+        want to complain if there's a static overload; non-unique
+        cases will be handled by instantiate_type.  But we need to
+        handle this case here to allow casts on the resulting PMF.
+        We could defer this in non-MS mode, but it's easier to give
+        a useful error here.  */
+
+      /* 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 fn = get_first_fn (TREE_OPERAND (arg, 1));
+      mark_used (fn);
+
+      if (! flag_ms_extensions)
+       {
+         tree name = DECL_NAME (fn);
+         if (!(complain & tf_error))
+           return error_mark_node;
+         else if (current_class_type
+                  && TREE_OPERAND (arg, 0) == current_class_ref)
+           /* An expression like &memfn.  */
+           permerror (input_location, "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
+           permerror (input_location, "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, fn, /*address_p=*/true);
+    }
+
+  /* Uninstantiated types are all functions.  Taking the
+     address of a function is a no-op, so just return the
+     argument.  */
+  if (type_unknown_p (arg))
+    return build1 (ADDR_EXPR, unknown_type_node, arg);
+
+  if (TREE_CODE (arg) == OFFSET_REF)
+    /* We want a pointer to member; bypass all the code for actually taking
+       the address of something.  */
+    goto offset_ref;
+
+  /* Anything not already handled and not a true memory reference
+     is an error.  */
+  if (TREE_CODE (argtype) != FUNCTION_TYPE
+      && TREE_CODE (argtype) != METHOD_TYPE)
+    {
+      cp_lvalue_kind kind = lvalue_kind (arg);
+      if (kind == clk_none)
+       {
+         if (complain & tf_error)
+           lvalue_error (lv_addressof);
+         return error_mark_node;
+       }
+      if (strict_lvalue && (kind & (clk_rvalueref|clk_class)))
+       {
+         if (!(complain & tf_error))
+           return error_mark_node;
+         if (kind & clk_class)
+           /* Make this a permerror because we used to accept it.  */
+           permerror (input_location, "taking address of temporary");
+         else
+           error ("taking address of xvalue (rvalue reference)");
+       }
+    }
+
+  if (TREE_CODE (argtype) == REFERENCE_TYPE)
+    {
+      tree type = build_pointer_type (TREE_TYPE (argtype));
+      arg = build1 (CONVERT_EXPR, type, arg);
+      return arg;
+    }
+  else if (pedantic && DECL_MAIN_P (arg))
+    {
+      /* ARM $3.4 */
+      /* Apparently a lot of autoconf scripts for C++ packages do this,
+        so only complain if -pedantic.  */
+      if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
+       pedwarn (input_location, OPT_pedantic,
+                "ISO C++ forbids taking address of function %<::main%>");
+      else if (flag_pedantic_errors)
+       return error_mark_node;
+    }
+
+  /* Let &* cancel out to simplify resulting code.  */
+  if (TREE_CODE (arg) == INDIRECT_REF)
+    {
+      /* We don't need to have `current_class_ptr' wrapped in a
+        NON_LVALUE_EXPR node.  */
+      if (arg == current_class_ref)
+       return current_class_ptr;
+
+      arg = TREE_OPERAND (arg, 0);
+      if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
+       {
+         tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
+         arg = build1 (CONVERT_EXPR, type, arg);
+       }
+      else
+       /* Don't let this be an lvalue.  */
+       arg = rvalue (arg);
+      return arg;
+    }
+
+  /* ??? Cope with user tricks that amount to offsetof.  */
+  if (TREE_CODE (argtype) != FUNCTION_TYPE
+      && TREE_CODE (argtype) != METHOD_TYPE
+      && argtype != unknown_type_node
+      && (val = get_base_address (arg))
+      && COMPLETE_TYPE_P (TREE_TYPE (val))
+      && TREE_CODE (val) == INDIRECT_REF
+      && TREE_CONSTANT (TREE_OPERAND (val, 0)))
+    {
+      tree type = build_pointer_type (argtype);
+      tree op0 = fold_convert (type, TREE_OPERAND (val, 0));
+      tree op1 = fold_convert (sizetype, fold_offsetof (arg, val));
+      return fold_build2 (POINTER_PLUS_EXPR, type, op0, op1);
+    }
+
+  /* Handle complex lvalues (when permitted)
+     by reduction to simpler cases.  */
+  val = unary_complex_lvalue (ADDR_EXPR, arg);
+  if (val != 0)
+    return val;
+
+  switch (TREE_CODE (arg))
+    {
+    CASE_CONVERT:
+    case FLOAT_EXPR:
+    case FIX_TRUNC_EXPR:
+      /* Even if we're not being pedantic, we cannot allow this
+        extension when we're instantiating in a SFINAE
+        context.  */
+      if (! lvalue_p (arg) && complain == tf_none)
+       {
+         if (complain & tf_error)
+           permerror (input_location, "ISO C++ forbids taking the address of a cast to a non-lvalue expression");
+         else
+           return error_mark_node;
+       }
+      break;
+
+    case BASELINK:
+      arg = BASELINK_FUNCTIONS (arg);
+      /* Fall through.  */
+
+    case OVERLOAD:
+      arg = OVL_CURRENT (arg);
+      break;
+
+    case OFFSET_REF:
+    offset_ref:
+      /* Turn a reference to a non-static data member into a
+        pointer-to-member.  */
+      {
+       tree type;
+       tree t;
+
+       gcc_assert (PTRMEM_OK_P (arg));
+
+       t = TREE_OPERAND (arg, 1);
+       if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
+         {
+           if (complain & tf_error)
+             error ("cannot create pointer to reference member %qD", t);
+           return error_mark_node;
+         }
+
+       type = build_ptrmem_type (context_for_name_lookup (t),
+                                 TREE_TYPE (t));
+       t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
+       return t;
+      }
+
+    default:
+      break;
+    }
+
+  if (argtype != error_mark_node)
+    argtype = build_pointer_type (argtype);
+
+  /* In a template, we are processing a non-dependent expression
+     so we can just form an ADDR_EXPR with the correct type.  */
+  if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
+    {
+      val = build_address (arg);
+      if (TREE_CODE (arg) == OFFSET_REF)
+       PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
+    }
+  else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
+    {
+      tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
+
+      /* We can only get here with a single static member
+        function.  */
+      gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+                 && DECL_STATIC_FUNCTION_P (fn));
+      mark_used (fn);
+      val = build_address (fn);
+      if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
+       /* Do not lose object's side effects.  */
+       val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
+                     TREE_OPERAND (arg, 0), val);
+    }
+  else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+    {
+      if (complain & tf_error)
+       error ("attempt to take address of bit-field structure member %qD",
+              TREE_OPERAND (arg, 1));
+      return error_mark_node;
+    }
+  else
+    {
+      tree object = TREE_OPERAND (arg, 0);
+      tree field = TREE_OPERAND (arg, 1);
+      gcc_assert (same_type_ignoring_top_level_qualifiers_p
+                 (TREE_TYPE (object), decl_type_context (field)));
+      val = build_address (arg);
+    }
+
+  if (TREE_CODE (argtype) == POINTER_TYPE
+      && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
+    {
+      build_ptrmemfunc_type (argtype);
+      val = build_ptrmemfunc (argtype, val, 0,
+                             /*c_cast_p=*/false,
+                             tf_warning_or_error);
+    }
+
+  return val;
+}
+
+/* Take the address of ARG if it has one, even if it's an rvalue.  */
+
+tree
+cp_build_addr_expr (tree arg, tsubst_flags_t complain)
+{
+  return cp_build_addr_expr_1 (arg, 0, complain);
+}
+
+/* Take the address of ARG, but only if it's an lvalue.  */
+
+tree
+cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
+{
+  return cp_build_addr_expr_1 (arg, 1, complain);
+}
+
 /* C++: Must handle pointers to members.
 
    Perhaps type instantiation should be extended to handle conversion
@@ -4284,7 +5019,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
   tree val;
   const char *invalid_op_diag;
 
-  if (error_operand_p (arg))
+  if (!arg || error_operand_p (arg))
     return error_mark_node;
 
   if ((invalid_op_diag
@@ -4309,8 +5044,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
        arg = build_expr_type_conversion (flags, arg, true);
        if (!arg)
          errstring = (code == NEGATE_EXPR
-                      ? "wrong type argument to unary minus"
-                      : "wrong type argument to unary plus");
+                      ? _("wrong type argument to unary minus")
+                      : _("wrong type argument to unary plus"));
        else
          {
            if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
@@ -4331,16 +5066,16 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
            arg = default_conversion (arg);
        }
       else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM
-                                                  | WANT_VECTOR,
+                                                  | WANT_VECTOR_OR_COMPLEX,
                                                   arg, true)))
-       errstring = "wrong type argument to bit-complement";
+       errstring = _("wrong type argument to bit-complement");
       else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
        arg = perform_integral_promotions (arg);
       break;
 
     case ABS_EXPR:
       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
-       errstring = "wrong type argument to abs";
+       errstring = _("wrong type argument to abs");
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -4348,7 +5083,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
     case CONJ_EXPR:
       /* Conjugating a real value is a no-op, but allow it anyway.  */
       if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
-       errstring = "wrong type argument to conjugation";
+       errstring = _("wrong type argument to conjugation");
       else if (!noconvert)
        arg = default_conversion (arg);
       break;
@@ -4356,10 +5091,10 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
     case TRUTH_NOT_EXPR:
       arg = perform_implicit_conversion (boolean_type_node, arg,
                                         complain);
-      val = invert_truthvalue (arg);
+      val = invert_truthvalue_loc (input_location, arg);
       if (arg != error_mark_node)
        return val;
-      errstring = "in argument to unary !";
+      errstring = _("in argument to unary !");
       break;
 
     case NOP_EXPR:
@@ -4398,6 +5133,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
       if (val != 0)
        return val;
 
+      arg = mark_lvalue_use (arg);
+
       /* Increment or decrement the real part of the value,
         and don't change the imaginary part.  */
       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
@@ -4420,13 +5157,13 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
                                              arg, true)))
        {
          if (code == PREINCREMENT_EXPR)
-           errstring ="no pre-increment operator for type";
+           errstring = _("no pre-increment operator for type");
          else if (code == POSTINCREMENT_EXPR)
-           errstring ="no post-increment operator for type";
+           errstring = _("no post-increment operator for type");
          else if (code == PREDECREMENT_EXPR)
-           errstring ="no pre-decrement operator for type";
+           errstring = _("no pre-decrement operator for type");
          else
-           errstring ="no post-decrement operator for type";
+           errstring = _("no post-decrement operator for type");
          break;
        }
       else if (arg == error_mark_node)
@@ -4440,7 +5177,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
           if (complain & tf_error)
             readonly_error (arg, ((code == PREINCREMENT_EXPR
                                    || code == POSTINCREMENT_EXPR)
-                                  ? "increment" : "decrement"));
+                                  ? REK_INCREMENT : REK_DECREMENT));
           else
             return error_mark_node;
         }
@@ -4507,7 +5244,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
          return error_mark_node;
 
        /* Forbid using -- on `bool'.  */
-       if (same_type_p (declared_type, boolean_type_node))
+       if (TREE_CODE (declared_type) == BOOLEAN_TYPE)
          {
            if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR)
              {
@@ -4528,221 +5265,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
     case ADDR_EXPR:
       /* Note that this operation never does default_conversion
         regardless of NOCONVERT.  */
-
-      argtype = lvalue_type (arg);
-
-      if (TREE_CODE (arg) == OFFSET_REF)
-       goto offset_ref;
-
-      if (TREE_CODE (argtype) == REFERENCE_TYPE)
-       {
-         tree type = build_pointer_type (TREE_TYPE (argtype));
-         arg = build1 (CONVERT_EXPR, type, arg);
-         return arg;
-       }
-      else if (pedantic && DECL_MAIN_P (arg))
-        {
-          /* ARM $3.4 */
-         /* Apparently a lot of autoconf scripts for C++ packages do this,
-            so only complain if -pedantic.  */
-          if (complain & (flag_pedantic_errors ? tf_error : tf_warning))
-            pedwarn (input_location, OPT_pedantic,
-                    "ISO C++ forbids taking address of function %<::main%>");
-          else if (flag_pedantic_errors)
-            return error_mark_node;
-        }
-
-      /* Let &* cancel out to simplify resulting code.  */
-      if (TREE_CODE (arg) == INDIRECT_REF)
-       {
-         /* We don't need to have `current_class_ptr' wrapped in a
-            NON_LVALUE_EXPR node.  */
-         if (arg == current_class_ref)
-           return current_class_ptr;
-
-         arg = TREE_OPERAND (arg, 0);
-         if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
-           {
-             tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
-             arg = build1 (CONVERT_EXPR, type, arg);
-           }
-         else
-           /* Don't let this be an lvalue.  */
-           arg = rvalue (arg);
-         return arg;
-       }
-
-      /* Uninstantiated types are all functions.  Taking the
-        address of a function is a no-op, so just return the
-        argument.  */
-
-      gcc_assert (TREE_CODE (arg) != IDENTIFIER_NODE
-                 || !IDENTIFIER_OPNAME_P (arg));
-
-      if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
-         && !really_overloaded_fn (TREE_OPERAND (arg, 1)))
-       {
-         /* They're trying to take the address of a unique non-static
-            member function.  This is ill-formed (except in MS-land),
-            but let's try to DTRT.
-            Note: We only handle unique functions here because we don't
-            want to complain if there's a static overload; non-unique
-            cases will be handled by instantiate_type.  But we need to
-            handle this case here to allow casts on the resulting PMF.
-            We could defer this in non-MS mode, but it's easier to give
-            a useful error here.  */
-
-         /* 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 fn = get_first_fn (TREE_OPERAND (arg, 1));
-         mark_used (fn);
-
-         if (! flag_ms_extensions)
-           {
-             tree name = DECL_NAME (fn);
-              if (!(complain & tf_error))
-                return error_mark_node;
-             else if (current_class_type
-                       && TREE_OPERAND (arg, 0) == current_class_ref)
-                  /* An expression like &memfn.  */
-                permerror (input_location, "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
-               permerror (input_location, "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, fn, /*address_p=*/true);
-       }
-
-    offset_ref:
-      if (type_unknown_p (arg))
-       return build1 (ADDR_EXPR, unknown_type_node, arg);
-
-      /* Handle complex lvalues (when permitted)
-        by reduction to simpler cases.  */
-      val = unary_complex_lvalue (code, arg);
-      if (val != 0)
-       return val;
-
-      switch (TREE_CODE (arg))
-       {
-       CASE_CONVERT:
-       case FLOAT_EXPR:
-       case FIX_TRUNC_EXPR:
-          /* Even if we're not being pedantic, we cannot allow this
-             extension when we're instantiating in a SFINAE
-             context.  */
-         if (! lvalue_p (arg) && complain == tf_none)
-            {
-              if (complain & tf_error)
-                permerror (input_location, "ISO C++ forbids taking the address of a cast to a non-lvalue expression");
-              else
-                return error_mark_node;
-            }
-         break;
-
-       case BASELINK:
-         arg = BASELINK_FUNCTIONS (arg);
-         /* Fall through.  */
-
-       case OVERLOAD:
-         arg = OVL_CURRENT (arg);
-         break;
-
-       case OFFSET_REF:
-         /* Turn a reference to a non-static data member into a
-            pointer-to-member.  */
-         {
-           tree type;
-           tree t;
-
-           if (!PTRMEM_OK_P (arg))
-             return cp_build_unary_op (code, arg, 0, complain);
-
-           t = TREE_OPERAND (arg, 1);
-           if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
-             {
-                if (complain & tf_error)
-                  error ("cannot create pointer to reference member %qD", t);
-               return error_mark_node;
-             }
-
-           type = build_ptrmem_type (context_for_name_lookup (t),
-                                     TREE_TYPE (t));
-           t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
-           return t;
-         }
-
-       default:
-         break;
-       }
-
-      /* Anything not already handled and not a true memory reference
-        is an error.  */
-      if (TREE_CODE (argtype) != FUNCTION_TYPE
-         && TREE_CODE (argtype) != METHOD_TYPE
-         && TREE_CODE (arg) != OFFSET_REF
-         && !lvalue_or_else (arg, lv_addressof, complain))
-       return error_mark_node;
-
-      if (argtype != error_mark_node)
-       argtype = build_pointer_type (argtype);
-
-      /* In a template, we are processing a non-dependent expression
-        so we can just form an ADDR_EXPR with the correct type.  */
-      if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
-       {
-         val = build_address (arg);
-         if (TREE_CODE (arg) == OFFSET_REF)
-           PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
-       }
-      else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
-       {
-         tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
-
-         /* We can only get here with a single static member
-            function.  */
-         gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
-                     && DECL_STATIC_FUNCTION_P (fn));
-         mark_used (fn);
-         val = build_address (fn);
-         if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
-           /* Do not lose object's side effects.  */
-           val = build2 (COMPOUND_EXPR, TREE_TYPE (val),
-                         TREE_OPERAND (arg, 0), val);
-       }
-      else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
-       {
-          if (complain & tf_error)
-            error ("attempt to take address of bit-field structure member %qD",
-                   TREE_OPERAND (arg, 1));
-         return error_mark_node;
-       }
-      else
-       {
-         tree object = TREE_OPERAND (arg, 0);
-         tree field = TREE_OPERAND (arg, 1);
-         gcc_assert (same_type_ignoring_top_level_qualifiers_p
-                     (TREE_TYPE (object), decl_type_context (field)));
-         val = build_address (arg);
-       }
-
-      if (TREE_CODE (argtype) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE)
-       {
-         build_ptrmemfunc_type (argtype);
-         val = build_ptrmemfunc (argtype, val, 0,
-                                 /*c_cast_p=*/false);
-       }
-
-      return val;
+      return cp_build_addr_expr (arg, complain);
 
     default:
       break;
@@ -4973,23 +5496,69 @@ build_x_conditional_expr (tree ifexp, tree op1, tree op2,
 /* Given a list of expressions, return a compound expression
    that performs them all and returns the value of the last of them.  */
 
-tree build_x_compound_expr_from_list (tree list, const char *msg)
+tree
+build_x_compound_expr_from_list (tree list, expr_list_kind exp,
+                                tsubst_flags_t complain)
 {
   tree expr = TREE_VALUE (list);
 
   if (TREE_CHAIN (list))
     {
-      if (msg)
-       permerror (input_location, "%s expression list treated as compound expression", msg);
+      if (complain & tf_error)
+       switch (exp)
+         {
+         case ELK_INIT:
+           permerror (input_location, "expression list treated as compound "
+                                      "expression in initializer");
+           break;
+         case ELK_MEM_INIT:
+           permerror (input_location, "expression list treated as compound "
+                                      "expression in mem-initializer");
+           break;
+         case ELK_FUNC_CAST:
+           permerror (input_location, "expression list treated as compound "
+                                      "expression in functional cast");
+           break;
+         default:
+           gcc_unreachable ();
+         }
 
       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
        expr = build_x_compound_expr (expr, TREE_VALUE (list), 
-                                      tf_warning_or_error);
+                                      complain);
     }
 
   return expr;
 }
 
+/* Like build_x_compound_expr_from_list, but using a VEC.  */
+
+tree
+build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg)
+{
+  if (VEC_empty (tree, vec))
+    return NULL_TREE;
+  else if (VEC_length (tree, vec) == 1)
+    return VEC_index (tree, vec, 0);
+  else
+    {
+      tree expr;
+      unsigned int ix;
+      tree t;
+
+      if (msg != NULL)
+       permerror (input_location,
+                  "%s expression list treated as compound expression",
+                  msg);
+
+      expr = VEC_index (tree, vec, 0);
+      for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
+       expr = build_x_compound_expr (expr, t, tf_warning_or_error);
+
+      return expr;
+    }
+}
+
 /* Handle overloading of the ',' operator when needed.  */
 
 tree
@@ -5022,7 +5591,7 @@ build_x_compound_expr (tree op1, tree op2, tsubst_flags_t complain)
 /* Like cp_build_compound_expr, but for the c-common bits.  */
 
 tree
-build_compound_expr (tree lhs, tree rhs)
+build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs)
 {
   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
 }
@@ -5032,7 +5601,7 @@ build_compound_expr (tree lhs, tree rhs)
 tree
 cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
 {
-  lhs = convert_to_void (lhs, "left-hand operand of comma", complain);
+  lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
 
   if (lhs == error_mark_node || rhs == error_mark_node)
     return error_mark_node;
@@ -5110,7 +5679,7 @@ check_for_casting_away_constness (tree src_type, tree dest_type,
 
 tree
 convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
-               bool c_cast_p)
+               bool c_cast_p, tsubst_flags_t complain)
 {
   if (TYPE_PTRMEM_P (type))
     {
@@ -5121,7 +5690,10 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
       delta = get_delta_difference (TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (expr)),
                                    TYPE_PTRMEM_CLASS_TYPE (type),
                                    allow_inverse_p,
-                                   c_cast_p);
+                                   c_cast_p, complain);
+      if (delta == error_mark_node)
+       return error_mark_node;
+
       if (!integer_zerop (delta))
        {
          tree cond, op1, op2;
@@ -5136,7 +5708,8 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
                                    PLUS_EXPR, op1, delta,
                                    tf_warning_or_error);
 
-         expr = fold_build3 (COND_EXPR, ptrdiff_type_node, cond, op1, op2);
+         expr = fold_build3_loc (input_location,
+                             COND_EXPR, ptrdiff_type_node, cond, op1, op2);
                         
        }
 
@@ -5144,7 +5717,7 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
     }
   else
     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr,
-                            allow_inverse_p, c_cast_p);
+                            allow_inverse_p, c_cast_p, complain);
 }
 
 /* If EXPR is an INTEGER_CST and ORIG is an arithmetic constant, return
@@ -5219,7 +5792,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
   if (TREE_CODE (type) == REFERENCE_TYPE
       && CLASS_TYPE_P (TREE_TYPE (type))
       && CLASS_TYPE_P (intype)
-      && real_lvalue_p (expr)
+      && (TYPE_REF_IS_RVALUE (type) || real_lvalue_p (expr))
       && DERIVED_FROM_P (intype, TREE_TYPE (type))
       && can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
                      build_pointer_type (TYPE_MAIN_VARIANT
@@ -5245,11 +5818,31 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
                              base, /*nonnull=*/false);
       /* Convert the pointer to a reference -- but then remember that
         there are no expressions with reference type in C++.  */
-      return convert_from_reference (build_nop (type, expr));
+      return convert_from_reference (cp_fold_convert (type, expr));
+    }
+
+  /* "An lvalue of type cv1 T1 can be cast to type rvalue reference to
+     cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
+  if (TREE_CODE (type) == REFERENCE_TYPE
+      && TYPE_REF_IS_RVALUE (type)
+      && real_lvalue_p (expr)
+      && reference_related_p (TREE_TYPE (type), intype)
+      && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
+    {
+      expr = build_typed_address (expr, type);
+      return convert_from_reference (expr);
     }
 
   orig = expr;
 
+  /* Resolve overloaded address here rather than once in
+     implicit_conversion and again in the inverse code below.  */
+  if (TYPE_PTRMEMFUNC_P (type) && type_unknown_p (expr))
+    {
+      expr = instantiate_type (type, expr, complain);
+      intype = TREE_TYPE (expr);
+    }
+
   /* [expr.static.cast]
 
      An expression e can be explicitly converted to a type T using a
@@ -5278,7 +5871,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 
      Any expression can be explicitly converted to type cv void.  */
   if (TREE_CODE (type) == VOID_TYPE)
-    return convert_to_void (expr, /*implicit=*/NULL, complain);
+    return convert_to_void (expr, ICV_CAST, complain);
 
   /* [expr.static.cast]
 
@@ -5300,8 +5893,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
   /* The effect of all that is that any conversion between any two
      types which are integral, floating, or enumeration types can be
      performed.  */
-  if ((INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type))
-      && (INTEGRAL_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype)))
+  if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+       || SCALAR_FLOAT_TYPE_P (type))
+      && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
+         || SCALAR_FLOAT_TYPE_P (intype)))
     {
       expr = ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL);
 
@@ -5358,7 +5953,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
          if (!c_cast_p)
            check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR);
          return convert_ptrmem (type, expr, /*allow_inverse_p=*/1,
-                                c_cast_p);
+                                c_cast_p, tf_warning_or_error);
        }
     }
 
@@ -5501,13 +6096,18 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
        warning (0, "casting %qT to %qT does not dereference pointer",
                 intype, type);
 
-      expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
+      expr = cp_build_addr_expr (expr, complain);
+
+      if (warn_strict_aliasing > 2)
+       strict_aliasing_warning (TREE_TYPE (expr), type, expr);
+
       if (expr != error_mark_node)
        expr = build_reinterpret_cast_1
          (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
           valid_p, complain);
       if (expr != error_mark_node)
-       expr = cp_build_indirect_ref (expr, 0, complain);
+       /* cp_build_indirect_ref isn't right for rvalue refs.  */
+       expr = convert_from_reference (fold_convert (type, expr));
       return expr;
     }
 
@@ -5541,8 +6141,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
 
   /* [expr.reinterpret.cast]
      A pointer can be converted to any integral type large enough to
-     hold it.  */
-  if (CP_INTEGRAL_TYPE_P (type) && TYPE_PTR_P (intype))
+     hold it. ... A value of type std::nullptr_t can be converted to
+     an integral type; the conversion has the same meaning and
+     validity as a conversion of (void*)0 to the integral type.  */
+  if (CP_INTEGRAL_TYPE_P (type)
+      && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
     {
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
@@ -5552,6 +6155,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
           else
             return error_mark_node;
         }
+      if (NULLPTR_TYPE_P (intype))
+        return build_int_cst (type, 0);
     }
   /* [expr.reinterpret.cast]
      A value of integral or enumeration type can be explicitly
@@ -5601,7 +6206,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
     }
   else if (TREE_CODE (type) == VECTOR_TYPE)
     return fold_if_not_in_template (convert_to_vector (type, expr));
-  else if (TREE_CODE (intype) == VECTOR_TYPE && INTEGRAL_TYPE_P (type))
+  else if (TREE_CODE (intype) == VECTOR_TYPE
+          && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
     return fold_if_not_in_template (convert_to_integer (type, expr));
   else
     {
@@ -5728,8 +6334,8 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
        }
       if (reference_type)
        {
-         expr = cp_build_unary_op (ADDR_EXPR, expr, 0, 
-                                    complain? tf_warning_or_error : tf_none);
+         expr = cp_build_addr_expr (expr,
+                                    complain ? tf_warning_or_error : tf_none);
          expr = build_nop (reference_type, expr);
          return convert_from_reference (expr);
        }
@@ -5776,7 +6382,7 @@ build_const_cast (tree type, tree expr, tsubst_flags_t complain)
 /* Like cp_build_c_cast, but for the c-common bits.  */
 
 tree
-build_c_cast (tree type, tree expr)
+build_c_cast (location_t loc ATTRIBUTE_UNUSED, tree type, tree expr)
 {
   return cp_build_c_cast (type, expr, tf_warning_or_error);
 }
@@ -5845,6 +6451,15 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
       return error_mark_node;
     }
 
+  if (TREE_CODE (type) == POINTER_TYPE
+      && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
+      /* Casting to an integer of smaller size is an error detected elsewhere.  */
+      && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
+      /* Don't warn about converting any constant.  */
+      && !TREE_CONSTANT (value))
+    warning_at (input_location, OPT_Wint_to_pointer_cast, 
+               "cast to pointer from integer of different size");
+
   /* A C-style cast can be a const_cast.  */
   result = build_const_cast_1 (type, value, /*complain=*/false,
                               &valid_p);
@@ -5893,7 +6508,8 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
 tree
 build_modify_expr (location_t location ATTRIBUTE_UNUSED,
                   tree lhs, tree lhs_origtype ATTRIBUTE_UNUSED,
-                  enum tree_code modifycode, tree rhs,
+                  enum tree_code modifycode, 
+                  location_t rhs_location ATTRIBUTE_UNUSED, tree rhs,
                   tree rhs_origtype ATTRIBUTE_UNUSED)
 {
   return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
@@ -6021,8 +6637,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
   if (modifycode == INIT_EXPR)
     {
-      if (TREE_CODE (rhs) == CONSTRUCTOR)
+      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+       /* Do the default thing.  */;
+      else if (TREE_CODE (rhs) == CONSTRUCTOR)
        {
+         /* Compound literal.  */
          if (! same_type_p (TREE_TYPE (rhs), lhstype))
            /* Call convert to generate an error; see PR 11063.  */
            rhs = convert (lhstype, rhs);
@@ -6034,10 +6653,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
        /* Do the default thing.  */;
       else
        {
+         VEC(tree,gc) *rhs_vec = make_tree_vector_single (rhs);
          result = build_special_member_call (lhs, complete_ctor_identifier,
-                                             build_tree_list (NULL_TREE, rhs),
-                                             lhstype, LOOKUP_NORMAL,
+                                             &rhs_vec, lhstype, LOOKUP_NORMAL,
                                               complain);
+         release_tree_vector (rhs_vec);
          if (result == NULL_TREE)
            return error_mark_node;
          return result;
@@ -6045,12 +6665,19 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
     }
   else
     {
-      lhs = require_complete_type (lhs);
+      lhs = require_complete_type_sfinae (lhs, complain);
       if (lhs == error_mark_node)
        return error_mark_node;
 
       if (modifycode == NOP_EXPR)
        {
+         if (c_dialect_objc ())
+           {
+             result = objc_maybe_build_modify_expr (lhs, rhs);
+             if (result)
+               return result;
+           }
+
          /* `operator=' is not an inheritable operator.  */
          if (! MAYBE_CLASS_TYPE_P (lhstype))
            /* Do the default thing.  */;
@@ -6089,6 +6716,12 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
          /* Now it looks like a plain assignment.  */
          modifycode = NOP_EXPR;
+         if (c_dialect_objc ())
+           {
+             result = objc_maybe_build_modify_expr (lhs, newrhs);
+             if (result)
+               return result;
+           }
        }
       gcc_assert (TREE_CODE (lhstype) != REFERENCE_TYPE);
       gcc_assert (TREE_CODE (TREE_TYPE (newrhs)) != REFERENCE_TYPE);
@@ -6112,7 +6745,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
              && C_TYPE_FIELDS_READONLY (lhstype))))
     {
       if (complain & tf_error)
-       readonly_error (lhs, "assignment");
+       readonly_error (lhs, REK_ASSIGNMENT);
       else
        return error_mark_node;
     }
@@ -6129,8 +6762,21 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
     {
       int from_array;
 
-      if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
-                               TYPE_MAIN_VARIANT (TREE_TYPE (rhs))))
+      if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
+       {
+         if (modifycode != INIT_EXPR)
+           {
+             if (complain & tf_error)
+               error ("assigning to an array from an initializer list");
+             return error_mark_node;
+           }
+         if (check_array_initializer (lhs, lhstype, newrhs))
+           return error_mark_node;
+         newrhs = digest_init (lhstype, newrhs);
+       }
+
+      else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
+                                    TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))))
        {
          if (complain & tf_error)
            error ("incompatible types in assignment of %qT to %qT",
@@ -6139,7 +6785,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
        }
 
       /* Allow array assignment in compiler-generated code.  */
-      if (!current_function_decl || !DECL_ARTIFICIAL (current_function_decl))
+      else if (!current_function_decl
+              || !DECL_ARTIFICIAL (current_function_decl))
        {
           /* This routine is used for both initialization and assignment.
              Make sure the diagnostic message differentiates the context.  */
@@ -6164,10 +6811,10 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
     /* Calls with INIT_EXPR are all direct-initialization, so don't set
        LOOKUP_ONLYCONVERTING.  */
     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
-                                        "initialization", NULL_TREE, 0,
+                                        ICR_INIT, NULL_TREE, 0,
                                          complain);
   else
-    newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
+    newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
                                     NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
 
   if (!same_type_p (lhstype, olhstype))
@@ -6234,20 +6881,32 @@ build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
 /* Helper function for get_delta_difference which assumes FROM is a base
    class of TO.  Returns a delta for the conversion of pointer-to-member
-   of FROM to pointer-to-member of TO.  If the conversion is invalid,
+   of FROM to pointer-to-member of TO.  If the conversion is invalid and 
+   tf_error is not set in COMPLAIN returns error_mark_node, otherwise
    returns zero.  If FROM is not a base class of TO, returns NULL_TREE.
-   If C_CAST_P is true, this conversion is taking place as part of a C-style
-   cast.  */
+   If C_CAST_P is true, this conversion is taking place as part of a 
+   C-style cast.  */
 
 static tree
-get_delta_difference_1 (tree from, tree to, bool c_cast_p)
+get_delta_difference_1 (tree from, tree to, bool c_cast_p,
+                       tsubst_flags_t complain)
 {
   tree binfo;
   base_kind kind;
+  base_access access = c_cast_p ? ba_unique : ba_check;
+
+  /* Note: ba_quiet does not distinguish between access control and
+     ambiguity.  */
+  if (!(complain & tf_error))
+    access |= ba_quiet;
+
+  binfo = lookup_base (to, from, access, &kind);
 
-  binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind);
   if (kind == bk_inaccessible || kind == bk_ambig)
     {
+      if (!(complain & tf_error))
+       return error_mark_node;
+
       error ("   in pointer to member function conversion");
       return size_zero_node;
     }
@@ -6259,22 +6918,26 @@ get_delta_difference_1 (tree from, tree to, bool c_cast_p)
        /* FROM is a virtual base class of TO.  Issue an error or warning
           depending on whether or not this is a reinterpret cast.  */
        {
+         if (!(complain & tf_error))
+           return error_mark_node;
+
          error ("pointer to member conversion via virtual base %qT",
                 BINFO_TYPE (binfo_from_vbase (binfo)));
 
          return size_zero_node;
        }
       }
-    else
-      return NULL_TREE;
+  else
+    return NULL_TREE;
 }
 
 /* Get difference in deltas for different pointer to member function
-   types.  Returns an integer constant of type PTRDIFF_TYPE_NODE.  If
-   the conversion is invalid, the constant is zero.  If
-   ALLOW_INVERSE_P is true, then allow reverse conversions as well.
-   If C_CAST_P is true this conversion is taking place as part of a
-   C-style cast.
+   types.  If the conversion is invalid and tf_error is not set in
+   COMPLAIN, returns error_mark_node, otherwise returns an integer
+   constant of type PTRDIFF_TYPE_NODE and its value is zero if the
+   conversion is invalid.  If ALLOW_INVERSE_P is true, then allow reverse
+   conversions as well.  If C_CAST_P is true this conversion is taking
+   place as part of a C-style cast.
 
    Note that the naming of FROM and TO is kind of backwards; the return
    value is what we add to a TO in order to get a FROM.  They are named
@@ -6284,7 +6947,7 @@ get_delta_difference_1 (tree from, tree to, bool c_cast_p)
 static tree
 get_delta_difference (tree from, tree to,
                      bool allow_inverse_p,
-                     bool c_cast_p)
+                     bool c_cast_p, tsubst_flags_t complain)
 {
   tree result;
 
@@ -6292,24 +6955,37 @@ get_delta_difference (tree from, tree to,
     /* Pointer to member of incomplete class is permitted*/
     result = size_zero_node;
   else
-    result = get_delta_difference_1 (from, to, c_cast_p);
+    result = get_delta_difference_1 (from, to, c_cast_p, complain);
+
+  if (result == error_mark_node)
+    return error_mark_node;
 
   if (!result)
   {
     if (!allow_inverse_p)
       {
+       if (!(complain & tf_error))
+         return error_mark_node;
+
        error_not_base_type (from, to);
        error ("   in pointer to member conversion");
-       result = size_zero_node;
+       result = size_zero_node;
       }
     else
       {
-       result = get_delta_difference_1 (to, from, c_cast_p);
+       result = get_delta_difference_1 (to, from, c_cast_p, complain);
+
+       if (result == error_mark_node)
+         return error_mark_node;
 
        if (result)
-         result = size_diffop (size_zero_node, result);
+         result = size_diffop_loc (input_location,
+                                   size_zero_node, result);
        else
          {
+           if (!(complain & tf_error))
+             return error_mark_node;
+
            error_not_base_type (from, to);
            error ("   in pointer to member conversion");
            result = size_zero_node;
@@ -6334,7 +7010,7 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn)
 
   /* Pull the FIELD_DECLs out of the type.  */
   pfn_field = TYPE_FIELDS (type);
-  delta_field = TREE_CHAIN (pfn_field);
+  delta_field = DECL_CHAIN (pfn_field);
 
   /* Make sure DELTA has the type we want.  */
   delta = convert_and_check (delta_type_node, delta);
@@ -6368,7 +7044,8 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn)
    Return error_mark_node, if something goes wrong.  */
 
 tree
-build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
+build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
+                 tsubst_flags_t complain)
 {
   tree fn;
   tree pfn_type;
@@ -6395,7 +7072,9 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
                                TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
                                force,
-                               c_cast_p);
+                               c_cast_p, complain);
+      if (n == error_mark_node)
+       return error_mark_node;
 
       /* We don't have to do any conversion to convert a
         pointer-to-member to its own type.  But, we don't want to
@@ -6435,9 +7114,9 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
     }
 
   /* Handle null pointer to member function conversions.  */
-  if (integer_zerop (pfn))
+  if (null_ptr_cst_p (pfn))
     {
-      pfn = build_c_cast (type, integer_zero_node);
+      pfn = build_c_cast (input_location, type, integer_zero_node);
       return build_ptrmemfunc1 (to_type,
                                integer_zero_node,
                                pfn);
@@ -6478,7 +7157,7 @@ expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
 
   /* First, calculate the adjustment to the function's class.  */
   *delta = get_delta_difference (fn_class, ptr_class, /*force=*/0,
-                                /*c_cast_p=*/0);
+                                /*c_cast_p=*/0, tf_warning_or_error);
 
   if (!DECL_VIRTUAL_P (fn))
     *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
@@ -6566,14 +7245,15 @@ delta_from_ptrmemfunc (tree t)
 }
 
 /* Convert value RHS to type TYPE as preparation for an assignment to
-   an lvalue of type TYPE.  ERRTYPE is a string to use in error
-   messages: "assignment", "return", etc.  If FNDECL is non-NULL, we
-   are doing the conversion in order to pass the PARMNUMth argument of
-   FNDECL.  */
+   an lvalue of type TYPE.  ERRTYPE indicates what kind of error the
+   implicit conversion is.  If FNDECL is non-NULL, we are doing the
+   conversion in order to pass the PARMNUMth argument of FNDECL.
+   If FNDECL is NULL, we are doing the conversion in function pointer
+   argument passing, conversion in initialization, etc. */
 
 static tree
 convert_for_assignment (tree type, tree rhs,
-                       const char *errtype, tree fndecl, int parmnum,
+                       impl_conv_rhs errtype, tree fndecl, int parmnum,
                        tsubst_flags_t complain, int flags)
 {
   tree rhstype;
@@ -6588,7 +7268,10 @@ convert_for_assignment (tree type, tree rhs,
 
   if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
       && vector_types_convertible_p (type, rhstype, true))
-    return convert (type, rhs);
+    {
+      rhs = mark_rvalue_use (rhs);
+      return convert (type, rhs);
+    }
 
   if (rhs == error_mark_node || rhstype == error_mark_node)
     return error_mark_node;
@@ -6610,27 +7293,32 @@ convert_for_assignment (tree type, tree rhs,
   if (c_dialect_objc ())
     {
       int parmno;
+      tree selector;
       tree rname = fndecl;
 
-      if (!strcmp (errtype, "assignment"))
-       parmno = -1;
-      else if (!strcmp (errtype, "initialization"))
-       parmno = -2;
-      else
-       {
-         tree selector = objc_message_selector ();
-
-         parmno = parmnum;
-
-         if (selector && parmno > 1)
-           {
-             rname = selector;
-             parmno -= 1;
-           }
+      switch (errtype)
+        {
+         case ICR_ASSIGN:
+           parmno = -1;
+           break;
+         case ICR_INIT:
+           parmno = -2;
+           break;
+         default:
+           selector = objc_message_selector ();
+           parmno = parmnum;
+           if (selector && parmno > 1)
+             {
+               rname = selector;
+               parmno -= 1;
+             }
        }
 
       if (objc_compare_types (type, rhstype, parmno, rname))
-       return convert (type, rhs);
+       {
+         rhs = mark_rvalue_use (rhs);
+         return convert (type, rhs);
+       }
     }
 
   /* [expr.ass]
@@ -6641,7 +7329,7 @@ convert_for_assignment (tree type, tree rhs,
      We allow bad conversions here because by the time we get to this point
      we are committed to doing the conversion.  If we end up doing a bad
      conversion, convert_like will complain.  */
-  if (!can_convert_arg_bad (type, rhstype, rhs))
+  if (!can_convert_arg_bad (type, rhstype, rhs, flags))
     {
       /* When -Wno-pmf-conversions is use, we just silently allow
         conversions from pointers-to-members to plain pointers.  If
@@ -6663,8 +7351,35 @@ convert_for_assignment (tree type, tree rhs,
                error ("cannot convert %qT to %qT for argument %qP to %qD",
                       rhstype, type, parmnum, fndecl);
              else
-               error ("cannot convert %qT to %qT in %s", rhstype, type,
-                      errtype);
+               switch (errtype)
+                 {
+                   case ICR_DEFAULT_ARGUMENT:
+                     error ("cannot convert %qT to %qT in default argument",
+                            rhstype, type);
+                     break;
+                   case ICR_ARGPASS:
+                     error ("cannot convert %qT to %qT in argument passing",
+                            rhstype, type);
+                     break;
+                   case ICR_CONVERTING:
+                     error ("cannot convert %qT to %qT",
+                            rhstype, type);
+                     break;
+                   case ICR_INIT:
+                     error ("cannot convert %qT to %qT in initialization",
+                            rhstype, type);
+                     break;
+                   case ICR_RETURN:
+                     error ("cannot convert %qT to %qT in return",
+                            rhstype, type);
+                     break;
+                   case ICR_ASSIGN:
+                     error ("cannot convert %qT to %qT in assignment",
+                            rhstype, type);
+                     break;
+                   default:
+                     gcc_unreachable();
+                 }
            }
          return error_mark_node;
        }
@@ -6676,22 +7391,57 @@ convert_for_assignment (tree type, tree rhs,
          && coder == codel
          && check_missing_format_attribute (type, rhstype)
          && (complain & tf_warning))
-       warning (OPT_Wmissing_format_attribute,
-                "%s might be a candidate for a format attribute",
-                errtype);
+       switch (errtype)
+         {
+           case ICR_ARGPASS:
+           case ICR_DEFAULT_ARGUMENT:
+             if (fndecl)
+               warning (OPT_Wmissing_format_attribute,
+                        "parameter %qP of %qD might be a candidate "
+                        "for a format attribute", parmnum, fndecl);
+             else
+               warning (OPT_Wmissing_format_attribute,
+                        "parameter might be a candidate "
+                        "for a format attribute");
+             break;
+           case ICR_CONVERTING:
+             warning (OPT_Wmissing_format_attribute,
+                      "target of conversion might be might be a candidate "
+                      "for a format attribute");
+             break;
+           case ICR_INIT:
+             warning (OPT_Wmissing_format_attribute,
+                      "target of initialization might be a candidate "
+                      "for a format attribute");
+             break;
+           case ICR_RETURN:
+             warning (OPT_Wmissing_format_attribute,
+                      "return type might be a candidate "
+                      "for a format attribute");
+             break;
+           case ICR_ASSIGN:
+             warning (OPT_Wmissing_format_attribute,
+                      "left-hand side of assignment might be a candidate "
+                      "for a format attribute");
+             break;
+           default:
+             gcc_unreachable();
+         }
     }
 
   /* If -Wparentheses, warn about a = b = c when a has type bool and b
      does not.  */
   if (warn_parentheses
-      && type == boolean_type_node
+      && TREE_CODE (type) == BOOLEAN_TYPE
       && TREE_CODE (rhs) == MODIFY_EXPR
       && !TREE_NO_WARNING (rhs)
-      && TREE_TYPE (rhs) != boolean_type_node
+      && TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
       && (complain & tf_warning))
     {
-      warning (OPT_Wparentheses,
-              "suggest parentheses around assignment used as truth value");
+      location_t loc = EXPR_LOC_OR_HERE (rhs);
+
+      warning_at (loc, OPT_Wparentheses,
+                 "suggest parentheses around assignment used as truth value");
       TREE_NO_WARNING (rhs) = 1;
     }
 
@@ -6701,7 +7451,7 @@ convert_for_assignment (tree type, tree rhs,
 
 /* Convert RHS to be of type TYPE.
    If EXP is nonzero, it is the target of the initialization.
-   ERRTYPE is a string to use in error messages.
+   ERRTYPE indicates what kind of error the implicit conversion is.
 
    Two major differences between the behavior of
    `convert_for_assignment' and `convert_for_initialization'
@@ -6717,7 +7467,7 @@ convert_for_assignment (tree type, tree rhs,
 
 tree
 convert_for_initialization (tree exp, tree type, tree rhs, int flags,
-                           const char *errtype, tree fndecl, int parmnum,
+                           impl_conv_rhs errtype, tree fndecl, int parmnum,
                             tsubst_flags_t complain)
 {
   enum tree_code codel = TREE_CODE (type);
@@ -6763,7 +7513,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
       if (fndecl)
        savew = warningcount, savee = errorcount;
       rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE,
-                                 /*cleanup=*/NULL);
+                                 /*cleanup=*/NULL, complain);
       if (fndecl)
        {
          if (warningcount > savew)
@@ -6775,7 +7525,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
     }
 
   if (exp != 0)
-    exp = require_complete_type (exp);
+    exp = require_complete_type_sfinae (exp, complain);
   if (exp == error_mark_node)
     return error_mark_node;
 
@@ -6783,6 +7533,11 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
 
   type = complete_type (type);
 
+  if (DIRECT_INIT_EXPR_P (type, rhs))
+    /* Don't try to do copy-initialization if we already have
+       direct-initialization.  */
+    return rhs;
+
   if (MAYBE_CLASS_TYPE_P (type))
     return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
 
@@ -6895,6 +7650,31 @@ check_return_expr (tree retval, bool *no_warning)
       return NULL_TREE;
     }
 
+  /* As an extension, deduce lambda return type from a return statement
+     anywhere in the body.  */
+  if (retval && LAMBDA_FUNCTION_P (current_function_decl))
+    {
+      tree lambda = CLASSTYPE_LAMBDA_EXPR (current_class_type);
+      if (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda))
+       {
+         tree type = lambda_return_type (retval);
+         tree oldtype = LAMBDA_EXPR_RETURN_TYPE (lambda);
+
+         if (VOID_TYPE_P (type))
+           { /* Nothing.  */ }
+         else if (oldtype == NULL_TREE)
+           {
+             pedwarn (input_location, OPT_pedantic, "lambda return type "
+                      "can only be deduced when the return statement is "
+                      "the only statement in the function body");
+             apply_lambda_return_type (lambda, type);
+           }
+         else if (!same_type_p (type, oldtype))
+           error ("inconsistent types %qT and %qT deduced for "
+                  "lambda return type", type, oldtype);
+       }
+    }
+
   if (processing_template_decl)
     {
       current_function_returns_value = 1;
@@ -7069,7 +7849,7 @@ check_return_expr (tree retval, bool *no_warning)
       if ((cxx_dialect != cxx98) 
           && named_return_value_okay_p
           /* The variable must not have the `volatile' qualifier.  */
-         && !(cp_type_quals (TREE_TYPE (retval)) & TYPE_QUAL_VOLATILE)
+         && !CP_TYPE_VOLATILE_P (TREE_TYPE (retval))
          /* The return type must be a class type.  */
          && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
        flags = flags | LOOKUP_PREFER_RVALUE;
@@ -7078,7 +7858,7 @@ check_return_expr (tree retval, bool *no_warning)
         to the type of return value's location to handle the
         case that functype is smaller than the valtype.  */
       retval = convert_for_initialization
-       (NULL_TREE, functype, retval, flags, "return", NULL_TREE, 0,
+       (NULL_TREE, functype, retval, flags, ICR_RETURN, NULL_TREE, 0,
          tf_warning_or_error);
       retval = convert (valtype, retval);
 
@@ -7134,12 +7914,13 @@ comp_ptr_ttypes_real (tree to, tree from, int constp)
          /* In Objective-C++, some types may have been 'volatilized' by
             the compiler for EH; when comparing them here, the volatile
             qualification must be ignored.  */
-         bool objc_quals_match = objc_type_quals_match (to, from);
+         tree nv_to = objc_non_volatilized_type (to);
+         tree nv_from = objc_non_volatilized_type (from);
 
-         if (!at_least_as_qualified_p (to, from) && !objc_quals_match)
+         if (!at_least_as_qualified_p (nv_to, nv_from))
            return 0;
 
-         if (!at_least_as_qualified_p (from, to) && !objc_quals_match)
+         if (!at_least_as_qualified_p (nv_from, nv_to))
            {
              if (constp == 0)
                return 0;
@@ -7147,7 +7928,7 @@ comp_ptr_ttypes_real (tree to, tree from, int constp)
            }
 
          if (constp > 0)
-           constp &= TYPE_READONLY (to);
+           constp &= TYPE_READONLY (nv_to);
        }
 
       if (TREE_CODE (to) == VECTOR_TYPE)
@@ -7170,6 +7951,44 @@ comp_ptr_ttypes (tree to, tree from)
   return comp_ptr_ttypes_real (to, from, 1);
 }
 
+/* Returns true iff FNTYPE is a non-class type that involves
+   error_mark_node.  We can get FUNCTION_TYPE with buried error_mark_node
+   if a parameter type is ill-formed.  */
+
+bool
+error_type_p (const_tree type)
+{
+  tree t;
+
+  switch (TREE_CODE (type))
+    {
+    case ERROR_MARK:
+      return true;
+
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+    case OFFSET_TYPE:
+      return error_type_p (TREE_TYPE (type));
+
+    case FUNCTION_TYPE:
+    case METHOD_TYPE:
+      if (error_type_p (TREE_TYPE (type)))
+       return true;
+      for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+       if (error_type_p (TREE_VALUE (t)))
+         return true;
+      return false;
+
+    case RECORD_TYPE:
+      if (TYPE_PTRMEMFUNC_P (type))
+       return error_type_p (TYPE_PTRMEMFUNC_FN_TYPE (type));
+      return false;
+
+    default:
+      return false;
+    }
+}
+
 /* Returns 1 if to and from are (possibly multi-level) pointers to the same
    type or inheritance-related types, regardless of cv-quals.  */
 
@@ -7179,9 +7998,10 @@ ptr_reasonably_similar (const_tree to, const_tree from)
   for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
     {
       /* Any target type is similar enough to void.  */
-      if (TREE_CODE (to) == VOID_TYPE
-         || TREE_CODE (from) == VOID_TYPE)
-       return 1;
+      if (TREE_CODE (to) == VOID_TYPE)
+       return !error_type_p (from);
+      if (TREE_CODE (from) == VOID_TYPE)
+       return !error_type_p (to);
 
       if (TREE_CODE (to) != TREE_CODE (from))
        return 0;
@@ -7201,7 +8021,7 @@ ptr_reasonably_similar (const_tree to, const_tree from)
        return 1;
 
       if (TREE_CODE (to) == FUNCTION_TYPE)
-       return 1;
+       return !error_type_p (to) && !error_type_p (from);
 
       if (TREE_CODE (to) != POINTER_TYPE)
        return comptypes
@@ -7244,24 +8064,59 @@ comp_ptr_ttypes_const (tree to, tree from)
 int
 cp_type_quals (const_tree type)
 {
+  int quals;
   /* This CONST_CAST is okay because strip_array_types returns its
      argument unmodified and we assign it to a const_tree.  */
-  type = strip_array_types (CONST_CAST_TREE(type));
-  if (type == error_mark_node)
+  type = strip_array_types (CONST_CAST_TREE (type));
+  if (type == error_mark_node
+      /* Quals on a FUNCTION_TYPE are memfn quals.  */
+      || TREE_CODE (type) == FUNCTION_TYPE)
     return TYPE_UNQUALIFIED;
-  return TYPE_QUALS (type);
+  quals = TYPE_QUALS (type);
+  /* METHOD and REFERENCE_TYPEs should never have quals.  */
+  gcc_assert ((TREE_CODE (type) != METHOD_TYPE
+              && TREE_CODE (type) != REFERENCE_TYPE)
+             || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
+                 == TYPE_UNQUALIFIED));
+  return quals;
+}
+
+/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
+   METHOD_TYPE.  */
+
+int
+type_memfn_quals (const_tree type)
+{
+  if (TREE_CODE (type) == FUNCTION_TYPE)
+    return TYPE_QUALS (type);
+  else if (TREE_CODE (type) == METHOD_TYPE)
+    return cp_type_quals (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))));
+  else
+    gcc_unreachable ();
+}
+
+/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
+   MEMFN_QUALS.  */
+
+tree
+apply_memfn_quals (tree type, cp_cv_quals memfn_quals)
+{
+  /* Could handle METHOD_TYPE here if necessary.  */
+  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
+  if (TYPE_QUALS (type) == memfn_quals)
+    return type;
+  /* This should really have a different TYPE_MAIN_VARIANT, but that gets
+     complex.  */
+  return build_qualified_type (type, memfn_quals);
 }
 
-/* Returns nonzero if the TYPE is const from a C++ perspective: look inside
-   arrays.  */
+/* Returns nonzero if TYPE is const or volatile.  */
 
 bool
-cp_type_readonly (const_tree type)
+cv_qualified_p (const_tree type)
 {
-  /* This CONST_CAST is okay because strip_array_types returns its
-     argument unmodified and we assign it to a const_tree.  */
-  type = strip_array_types (CONST_CAST_TREE(type));
-  return TYPE_READONLY (type);
+  int quals = cp_type_quals (type);
+  return (quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)) != 0;
 }
 
 /* Returns nonzero if the TYPE contains a mutable member.  */
@@ -7299,23 +8154,8 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
   if (TREE_CODE (decl) == TYPE_DECL)
     return;
 
-  if (TREE_CODE (type) == FUNCTION_TYPE
-      && type_quals != TYPE_UNQUALIFIED)
-    {
-      /* This was an error in C++98 (cv-qualifiers cannot be added to
-        a function type), but DR 295 makes the code well-formed by
-        dropping the extra qualifiers. */
-      if (pedantic)
-       {
-         tree bad_type = build_qualified_type (type, type_quals);
-         pedwarn (input_location, OPT_pedantic, 
-                  "ignoring %qV qualifiers added to function type %qT",
-                  bad_type, type);
-       }
-
-      TREE_TYPE (decl) = TYPE_MAIN_VARIANT (type);
-      return;
-    }
+  gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
+               && type_quals != TYPE_UNQUALIFIED));
 
   /* Avoid setting TREE_READONLY incorrectly.  */
   if (/* If the object has a constructor, the constructor may modify
@@ -7465,10 +8305,24 @@ non_reference (tree t)
 int
 lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
 {
-  int win = lvalue_p (ref);
-
-  if (!win && (complain & tf_error))
-    lvalue_error (use);
+  cp_lvalue_kind kind = lvalue_kind (ref);
 
-  return win;
+  if (kind == clk_none)
+    {
+      if (complain & tf_error)
+       lvalue_error (use);
+      return 0;
+    }
+  else if (kind & (clk_rvalueref|clk_class))
+    {
+      if (!(complain & tf_error))
+       return 0;
+      if (kind & clk_class)
+       /* Make this a permerror because we used to accept it.  */
+       permerror (input_location, "using temporary as lvalue");
+      else
+       error ("using xvalue (rvalue reference) as lvalue");
+    }
+  return 1;
 }
+