--- cp/parser.c.orig	2011-03-03 02:49:28.000000000 +0000
+++ cp/parser.c	2011-03-17 19:33:57.558598884 +0000
@@ -1871,6 +1871,8 @@ static tree cp_parser_c_for
   (cp_parser *, tree, tree);
 static tree cp_parser_range_for
   (cp_parser *, tree, tree, tree);
+static tree cp_parser_perform_range_for_lookup
+  (const char *, tree, int*);
 static tree cp_parser_jump_statement
   (cp_parser *);
 static void cp_parser_declaration_statement
@@ -8870,25 +8872,15 @@ cp_convert_range_for (tree statement, tr
       else
 	{
 	  /* If it is not an array, we must call begin(__range)/end__range() */
-	  VEC(tree,gc) *vec;
-
-	  begin_expr = get_identifier ("begin");
-	  vec = make_tree_vector ();
-	  VEC_safe_push (tree, gc, vec, range_temp);
-	  begin_expr = perform_koenig_lookup (begin_expr, vec,
-					      /*include_std=*/true);
-	  begin_expr = finish_call_expr (begin_expr, &vec, false, true,
-					 tf_warning_or_error);
-	  release_tree_vector (vec);
-
-	  end_expr = get_identifier ("end");
-	  vec = make_tree_vector ();
-	  VEC_safe_push (tree, gc, vec, range_temp);
-	  end_expr = perform_koenig_lookup (end_expr, vec,
-					    /*include_std=*/true);
-	  end_expr = finish_call_expr (end_expr, &vec, false, true,
-				       tf_warning_or_error);
-	  release_tree_vector (vec);
+	  int begin_is_member = 0;
+	  begin_expr = cp_parser_perform_range_for_lookup("begin", range_temp, &begin_is_member);
+	  int end_is_member = 0;
+	  end_expr = cp_parser_perform_range_for_lookup("end", range_temp, &end_is_member);
+
+	  if (begin_is_member != end_is_member)
+	    error ("range-based for found %s %<begin%> and %s %<end%>",
+		   (begin_is_member ? "member" : "non-member"),
+		   (end_is_member ? "member" : "non-member"));
 
 	  /* The unqualified type of the __begin and __end temporaries should
 	   * be the same as required by the multiple auto declaration */
@@ -8940,6 +8932,44 @@ cp_convert_range_for (tree statement, tr
   return statement;
 }
 
+static tree
+cp_parser_perform_range_for_lookup (const char *name, tree range, int* is_member)
+{
+  tree ident, expr;
+
+  ident = get_identifier (name);
+  expr = build_qualified_name (/*type=*/NULL_TREE,
+			       TREE_TYPE (range),
+			       ident,
+			       /*template_p=*/false);
+  expr = finish_class_member_access_expr(range, expr, false, tf_none);
+
+  if (expr != error_mark_node)
+    {
+      tree instance, fn;
+      instance = TREE_OPERAND (expr, 0);
+      fn = TREE_OPERAND (expr, 1);
+
+      expr = build_new_method_call (instance, fn, NULL, NULL, LOOKUP_NORMAL,
+				    NULL, tf_warning_or_error);
+      *is_member = 1;
+    }
+  else
+    {
+      VEC(tree,gc) *vec;
+      vec = make_tree_vector ();
+      VEC_safe_push (tree, gc, vec, range);
+      expr = get_identifier (name);
+      expr = perform_koenig_lookup (expr, vec,
+				    /*include_std=*/true);
+      expr = finish_call_expr (expr, &vec, false, true,
+			       tf_warning_or_error);
+      release_tree_vector (vec);
+      *is_member = 0;
+    }
+  return expr;
+}
+
 
 /* Parse an iteration-statement.
 
