Index: call.c
===================================================================
--- call.c	(revision 197804)
+++ call.c	(working copy)
@@ -4577,8 +4577,9 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr
 	  || (conv2 && conv2->kind == ck_ambig)
 	  || (conv3 && conv3->kind == ck_ambig))
 	{
-	  error ("operands to ?: have different types %qT and %qT",
-		 arg2_type, arg3_type);
+	  if (complain & tf_error)
+	    error ("operands to ?: have different types %qT and %qT",
+		   arg2_type, arg3_type);
 	  result = error_mark_node;
 	}
       else if (conv2 && (!conv2->bad_p || !conv3))
@@ -4760,10 +4761,11 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr
       /* In this case, there is always a common type.  */
       result_type = type_after_usual_arithmetic_conversions (arg2_type,
 							     arg3_type);
-      do_warn_double_promotion (result_type, arg2_type, arg3_type,
-				"implicit conversion from %qT to %qT to "
-				"match other result of conditional",
-				input_location);
+      if (complain & tf_warning)
+	do_warn_double_promotion (result_type, arg2_type, arg3_type,
+				  "implicit conversion from %qT to %qT to "
+				  "match other result of conditional",
+				  input_location);
 
       if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
 	  && TREE_CODE (arg3_type) == ENUMERAL_TYPE)
@@ -6790,9 +6792,14 @@ build_over_call (struct z_candidate *cand, int fla
       /* Check that the base class is accessible.  */
       if (!accessible_base_p (TREE_TYPE (argtype),
 			      BINFO_TYPE (cand->conversion_path), true))
-	error ("%qT is not an accessible base of %qT",
-	       BINFO_TYPE (cand->conversion_path),
-	       TREE_TYPE (argtype));
+	{
+	  if (complain & tf_error)
+	    error ("%qT is not an accessible base of %qT",
+		   BINFO_TYPE (cand->conversion_path),
+		   TREE_TYPE (argtype));
+	  else
+	    return error_mark_node;
+	}
       /* If fn was found by a using declaration, the conversion path
 	 will be to the derived class, not the base declaring fn. We
 	 must convert from derived to base.  */
Index: cvt.c
===================================================================
--- cvt.c	(revision 197804)
+++ cvt.c	(working copy)
@@ -40,7 +40,7 @@ static tree cp_convert_to_pointer (tree, tree, tsu
 static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
 static tree build_type_conversion (tree, tree);
 static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
-static void warn_ref_binding (location_t, tree, tree, tree);
+static void diagnose_ref_binding (location_t, tree, tree, tree);
 
 /* Change of width--truncation and extension of integers or reals--
    is represented with NOP_EXPR.  Proper functioning of many things
@@ -371,7 +371,7 @@ build_up_reference (tree type, tree arg, int flags
    non-volatile const type.  */
 
 static void
-warn_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
+diagnose_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
 {
   tree ttl = TREE_TYPE (reftype);
 
@@ -456,9 +456,9 @@ convert_to_reference (tree reftype, tree expr, int
 	tree ttl = TREE_TYPE (reftype);
 	tree ttr = lvalue_type (expr);
 
-	if ((complain & tf_warning)
+	if ((complain & tf_error)
 	    && ! real_lvalue_p (expr))
-	  warn_ref_binding (loc, reftype, intype, decl);
+	  diagnose_ref_binding (loc, reftype, intype, decl);
 
 	if (! (convtype & CONV_CONST)
 	    && !at_least_as_qualified_p (ttl, ttr))
@@ -502,8 +502,8 @@ convert_to_reference (tree reftype, tree expr, int
 					 ICR_CONVERTING, 0, 0, complain);
       if (rval == NULL_TREE || rval == error_mark_node)
 	return rval;
-      if (complain & tf_warning)
-	warn_ref_binding (loc, reftype, intype, decl);
+      if (complain & tf_error)
+	diagnose_ref_binding (loc, reftype, intype, decl);
       rval = build_up_reference (reftype, rval, flags, decl, complain);
     }
 
Index: typeck.c
===================================================================
--- typeck.c	(revision 197804)
+++ typeck.c	(working copy)
@@ -54,7 +54,7 @@ static tree get_delta_difference (tree, tree, bool
 static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
 static bool casts_away_constness (tree, tree, tsubst_flags_t);
 static void maybe_warn_about_returning_address_of_local (tree);
-static tree lookup_destructor (tree, tree, tree);
+static tree lookup_destructor (tree, tree, tree, tsubst_flags_t);
 static void warn_args_num (location_t, tree, bool);
 static int convert_arguments (tree, vec<tree, va_gc> **, tree, int,
                               tsubst_flags_t);
@@ -2469,7 +2469,8 @@ build_class_member_access_expr (tree object, tree
    SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type.  */
 
 static tree
-lookup_destructor (tree object, tree scope, tree dtor_name)
+lookup_destructor (tree object, tree scope, tree dtor_name,
+		   tsubst_flags_t complain)
 {
   tree object_type = TREE_TYPE (object);
   tree dtor_type = TREE_OPERAND (dtor_name, 0);
@@ -2477,8 +2478,9 @@ static tree
 
   if (scope && !check_dtor_name (scope, dtor_type))
     {
-      error ("qualified type %qT does not match destructor name ~%qT",
-	     scope, dtor_type);
+      if (complain & tf_error)
+	error ("qualified type %qT does not match destructor name ~%qT",
+	       scope, dtor_type);
       return error_mark_node;
     }
   if (identifier_p (dtor_type))
@@ -2489,16 +2491,18 @@ static tree
 	dtor_type = object_type;
       else
 	{
-	  error ("object type %qT does not match destructor name ~%qT",
-		 object_type, dtor_type);
+	  if (complain & tf_error)
+	    error ("object type %qT does not match destructor name ~%qT",
+		   object_type, dtor_type);
 	  return error_mark_node;
 	}
       
     }
   else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
     {
-      error ("the type being destroyed is %qT, but the destructor refers to %qT",
-	     TYPE_MAIN_VARIANT (object_type), dtor_type);
+      if (complain & tf_error)
+	error ("the type being destroyed is %qT, but the destructor "
+	       "refers to %qT", TYPE_MAIN_VARIANT (object_type), dtor_type);
       return error_mark_node;
     }
   expr = lookup_member (dtor_type, complete_dtor_identifier,
@@ -2731,7 +2735,7 @@ finish_class_member_access_expr (tree object, tree
 	}
 
       if (TREE_CODE (name) == BIT_NOT_EXPR)
-	member = lookup_destructor (object, scope, name);
+	member = lookup_destructor (object, scope, name, complain);
       else
 	{
 	  /* Look up the member.  */
@@ -3933,7 +3937,8 @@ cp_build_binary_op (location_t location,
   if ((invalid_op_diag
        = targetm.invalid_binary_op (code, type0, type1)))
     {
-      error (invalid_op_diag);
+      if (complain & tf_error)
+	error (invalid_op_diag);
       return error_mark_node;
     }
 
@@ -4600,7 +4605,8 @@ cp_build_binary_op (location_t location,
 	      || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
 							TREE_TYPE (type1)))
 	    {
-	      binary_op_error (location, code, type0, type1);
+	      if (complain & tf_error)
+		binary_op_error (location, code, type0, type1);
 	      return error_mark_node;
 	    }
 	  arithmetic_types_p = 1;
@@ -4612,11 +4618,12 @@ cp_build_binary_op (location_t location,
       && (shorten || common || short_compare))
     {
       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 (complain & tf_warning)
+	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)
@@ -4954,10 +4961,11 @@ build_x_unary_op (location_t loc, enum tree_code c
 	  tree fn = get_first_fn (xarg);
 	  if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
 	    {
-	      error (DECL_CONSTRUCTOR_P (fn)
-                     ? G_("taking address of constructor %qE")
-                     : G_("taking address of destructor %qE"),
-                     xarg);
+	      if (complain & tf_error)
+		error (DECL_CONSTRUCTOR_P (fn)
+		       ? G_("taking address of constructor %qE")
+		       : G_("taking address of destructor %qE"),
+		       xarg);
 	      return error_mark_node;
 	    }
 	}
@@ -4970,17 +4978,23 @@ build_x_unary_op (location_t loc, enum tree_code c
 	  if (TREE_CODE (xarg) != OFFSET_REF
 	      || !TYPE_P (TREE_OPERAND (xarg, 0)))
 	    {
-              error ("invalid use of %qE to form a pointer-to-member-function",
-                     xarg);
-              if (TREE_CODE (xarg) != OFFSET_REF)
-                inform (input_location, "  a qualified-id is required");
+	      if (complain & tf_error)
+		{
+		  error ("invalid use of %qE to form a "
+			 "pointer-to-member-function", xarg);
+		  if (TREE_CODE (xarg) != OFFSET_REF)
+		    inform (input_location, "  a qualified-id is required");
+		}
 	      return error_mark_node;
 	    }
 	  else
 	    {
-	      error ("parentheses around %qE cannot be used to form a"
-		     " pointer-to-member-function",
-		     xarg);
+	      if (complain & tf_error)
+		error ("parentheses around %qE cannot be used to form a"
+		       " pointer-to-member-function",
+		       xarg);
+	      else
+		return error_mark_node;
 	      PTRMEM_OK_P (xarg) = 1;
 	    }
 	}
@@ -5395,7 +5409,8 @@ cp_build_unary_op (enum tree_code code, tree xarg,
 				    : code),
 				   TREE_TYPE (xarg))))
     {
-      error (invalid_op_diag);
+      if (complain & tf_error)
+	error (invalid_op_diag);
       return error_mark_node;
     }
 
@@ -6028,7 +6043,8 @@ cp_build_compound_expr (tree lhs, tree rhs, tsubst
 
   if (type_unknown_p (rhs))
     {
-      error ("no context to resolve type of %qE", rhs);
+      if (complain & tf_error)
+	error ("no context to resolve type of %qE", rhs);
       return error_mark_node;
     }
   
@@ -7577,8 +7593,13 @@ build_ptrmemfunc (tree type, tree pfn, int force,
       if (!force
 	  && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
 			       LOOKUP_NORMAL, complain))
-	error ("invalid conversion to type %qT from type %qT",
-	       to_type, pfn_type);
+	{
+	  if (complain & tf_error)
+	    error ("invalid conversion to type %qT from type %qT",
+		   to_type, pfn_type);
+	  else
+	    return error_mark_node;
+	}
 
       n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
 				TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
