diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 57d01106da320fe79f4be2fa2090e64719efc984..eaa96a5a7722c6e764101a6dfb4a473f3df0b253 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2006-05-31  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/27801
+	* call.c (perform_implicit_conversion): Do not actually perform
+	conversions in templates.
+
+	PR c++/26496
+	* call.c (resolve_args): Check for invalid uses of bound
+	non-static member functions.
+	* init.c (build_offset_ref): Return error_mark_node for errors.
+
+	PR c++/27385
+	* decl.c (reshape_init): Robustify.
+	(reshape_init_array_1): Likewise.
+
 2006-05-30  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/27808
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9e69772954c804572d3c28b1163a59f3c8c7b779..2167101e2f94d12af9fcd28944cad1401f5c01f5 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2704,6 +2704,8 @@ resolve_args (tree args)
 	  error ("invalid use of void expression");
 	  return error_mark_node;
 	}
+      else if (invalid_nonstatic_memfn_p (arg))
+	return error_mark_node;
     }
   return args;
 }
@@ -6388,6 +6390,14 @@ perform_implicit_conversion (tree type, tree expr)
       error ("could not convert %qE to %qT", expr, type);
       expr = error_mark_node;
     }
+  else if (processing_template_decl)
+    {
+      /* In a template, we are only concerned about determining the
+	 type of non-dependent expressions, so we do not have to
+	 perform the actual conversion.  */
+      if (TREE_TYPE (expr) != type)
+	expr = build_nop (type, expr);
+    }
   else
     expr = convert_like (conv, expr);
 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5178bdfd91d327db0627e11b214731de98167d3a..bccb438a29bd60cbe7ec57d26ac4d6421c8d99dd 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4352,6 +4352,8 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
 	}
 
       elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
+      if (elt_init == error_mark_node)
+	return error_mark_node;
       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
     }
 
@@ -4630,6 +4632,8 @@ reshape_init (tree type, tree init)
   d.end = d.cur + VEC_length (constructor_elt, v);
 
   new_init = reshape_init_r (type, &d, true);
+  if (new_init == error_mark_node)
+    return error_mark_node;
 
   /* Make sure all the element of the constructor were used. Otherwise,
      issue an error about exceeding initializers.  */
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 533f9fb0a28d49e05a17dc20dfb0b37320f616b0..99d5d99080502d736f73e6505d7b3af4b0d5dc27 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1426,7 +1426,7 @@ build_offset_ref (tree type, tree member, bool address_p)
 	    }
 	  error ("invalid use of non-static member function %qD",
 		 TREE_OPERAND (member, 1));
-	  return member;
+	  return error_mark_node;
 	}
       else if (TREE_CODE (member) == FIELD_DECL)
 	{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c0b7c04597d6f827999297d21144405d9c377ef9..7277f60936cf9e9ddba2a97a46d30653a622fecf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2006-05-31  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/27801
+	* g++.dg/template/cond6.C: New test.
+
+	PR c++/26496
+	* g++.dg/template/crash51.C: New test.
+	* g++.old-deja/g++.mike/net36.C: Tweak error markers.
+
+	PR c++/27385
+	* g++.dg/init/array20.C: New test.
+
 2006-05-31  Roger Sayle  <roger@eyesopen.com>
 
 	* gcc.dg/builtins-54.c: New test case.
diff --git a/gcc/testsuite/g++.dg/init/array20.C b/gcc/testsuite/g++.dg/init/array20.C
new file mode 100644
index 0000000000000000000000000000000000000000..06a167596e68ef05c820ac41a1acfc07c04691e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array20.C
@@ -0,0 +1,5 @@
+// PR c++/27385
+
+struct A {};
+A a[] = { 0 };  // { dg-error "initializer" }
+
diff --git a/gcc/testsuite/g++.dg/template/cond6.C b/gcc/testsuite/g++.dg/template/cond6.C
new file mode 100644
index 0000000000000000000000000000000000000000..e4cede35b176cc89b15a80e2a4e3e078f43a8bfe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/cond6.C
@@ -0,0 +1,6 @@
+// PR c++/27801
+
+template<int> int foo(int i)
+{
+  return !( (1 && i) ? 0 : 1 );
+}
diff --git a/gcc/testsuite/g++.dg/template/crash51.C b/gcc/testsuite/g++.dg/template/crash51.C
new file mode 100644
index 0000000000000000000000000000000000000000..8c2553d1034d0cd9b65ebcf3fbc0ad05895e3e9d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash51.C
@@ -0,0 +1,11 @@
+// PR c++/26496
+
+template< typename _Generator> int generate_n(_Generator __gen);
+struct Distribution { };
+typedef double (Distribution::* Pstd_mem)();
+int main(void)
+{
+  Distribution* rng;
+  Pstd_mem ptr;
+  generate_n(rng->*ptr); // { dg-error "non-static member" } 
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net36.C b/gcc/testsuite/g++.old-deja/g++.mike/net36.C
index 98b38eedb48bebe21b5286e68fd1d879e46552f6..3ffa60e37a28dc3da61059678208399af8fa0779 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net36.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net36.C
@@ -11,7 +11,7 @@ typedef void (A::*handler) (X*);
 
 class B {
 public:
-  void setHandler(handler); // { dg-error "candidate" }
+  void setHandler(handler);
 };
 
 void f(B* b) {