diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 506d83c7ffb07eb3606e59d5d11e233d7dfd5e78..71fed72eb921f14bdacd90d20ae012541afe9062 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2009-08-04  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+	PR c++/16696
+	* call.c (build_new_op): Only try prefix operator if -fpermissive,
+	otherwise just error.
+
 2009-08-04  Dodji Seketeli  <dodji@redhat.com>
 
 	PR debug/39706
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index a667434f7a6d27c450b411dcc1b11e9267d84415..f6a083bd6776aeeedf462b7e5adc1583c6e08e46 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4255,13 +4255,23 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
 	  if (!(complain & tf_error))
 	    return error_mark_node;
 
-	  /* Look for an `operator++ (int)'.  If they didn't have
-	     one, then we fall back to the old way of doing things.  */
+	  /* Look for an `operator++ (int)'. Pre-1985 C++ didn't
+	     distinguish between prefix and postfix ++ and
+	     operator++() was used for both, so we allow this with
+	     -fpermissive.  */
 	  if (flags & LOOKUP_COMPLAIN)
-	    permerror (input_location, "no %<%D(int)%> declared for postfix %qs, "
-		       "trying prefix operator instead",
-		       fnname,
-		       operator_name_info[code].name);
+	    {
+	      const char *msg = (flag_permissive) 
+		? G_("no %<%D(int)%> declared for postfix %qs,"
+		     " trying prefix operator instead")
+		: G_("no %<%D(int)%> declared for postfix %qs");
+	      permerror (input_location, msg, fnname,
+			 operator_name_info[code].name);
+	    }
+
+	  if (!flag_permissive)
+	    return error_mark_node;
+
 	  if (code == POSTINCREMENT_EXPR)
 	    code = PREINCREMENT_EXPR;
 	  else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3ee1adce14500f12b12bceaddffd4509305e51b9..cecd2a13ba0b1a744d3dff595e6c580fba986296 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2009-08-04  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+	PR c++/16696
+	* g++.dg/parse/pr16696.C: New.
+	* g++.dg/parse/pr16696-permissive.C: New.
+
 2009-08-04  Paul Thomas  <pault@gcc.gnu.org>
 
 	PR fortran/40875
diff --git a/gcc/testsuite/g++.dg/parse/pr16696-permissive.C b/gcc/testsuite/g++.dg/parse/pr16696-permissive.C
new file mode 100644
index 0000000000000000000000000000000000000000..1d8a920ad25e544f41c766d4da7e01878e7af1c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr16696-permissive.C
@@ -0,0 +1,17 @@
+// PR 16696 Strange message when operator++ not found
+// { dg-do compile } 
+// { dg-options "-fdiagnostics-show-option -fpermissive" } 
+
+
+struct X { void operator++(); }; 
+struct Y { };
+
+int main () { 
+  X x; 
+  Y y;
+  x++; // { dg-warning "trying prefix operator" } 
+
+  y++; // { dg-warning "trying prefix operator" } 
+  // { dg-error "no match" "" { target *-*-* } 14 }
+} 
+
diff --git a/gcc/testsuite/g++.dg/parse/pr16696.C b/gcc/testsuite/g++.dg/parse/pr16696.C
new file mode 100644
index 0000000000000000000000000000000000000000..902e2a1a90b5a9404db2438fa19044345e9c520a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr16696.C
@@ -0,0 +1,17 @@
+// PR 16696 Strange message when operator++ not found
+// { dg-do compile } 
+// { dg-options "-fdiagnostics-show-option" } 
+
+
+struct X { void operator++(); }; 
+struct Y { };
+
+int main () { 
+  X x; 
+  Y y;
+  x++; // { dg-bogus "trying prefix operator" } 
+  // { dg-error "fpermissive" "" { target *-*-* } 12 }
+  y++; // { dg-bogus "trying prefix operator" } 
+  // { dg-error "fpermissive" "" { target *-*-* } 14 }
+} 
+