Index: c-family/c-objc.h
===================================================================
--- c-family/c-objc.h   (revision 168020)
+++ c-family/c-objc.h   (working copy)
@@ -106,6 +106,7 @@ extern bool objc_is_property_ref (tree);
 extern bool objc_string_ref_type_p (tree);
 extern void objc_check_format_arg (tree, tree);
 extern void objc_finish_function (void);
+extern void objc_maybe_warn_exceptions (location_t);
 
 /* The following are provided by the C and C++ front-ends, and called by
    ObjC/ObjC++.  */
Index: c-family/ChangeLog
===================================================================
--- c-family/ChangeLog  (revision 168020)
+++ c-family/ChangeLog  (working copy)
@@ -1,3 +1,8 @@
+2010-12-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * c-objc.h (objc_maybe_warn_exceptions): New.
+       * stub-objc.c (objc_maybe_warn_exceptions): New.        
+
 2010-12-10  Nathan Froyd  <froydnj@codesourcery.com>
 
        * c-common.h (readonly_error): Declare.
Index: c-family/stub-objc.c
===================================================================
--- c-family/stub-objc.c        (revision 168020)
+++ c-family/stub-objc.c        (working copy)
@@ -455,3 +455,8 @@ void
 objc_finish_function (void)
 {
 }
+
+void
+objc_maybe_warn_exceptions (location_t ARG_UNUSED (loc))
+{
+}
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c     (revision 168020)
+++ objc/objc-act.c     (working copy)
@@ -626,6 +626,11 @@ objc_init (void)
   if (print_struct_values && !flag_compare_debug)
     generate_struct_by_value_array ();
 
+#ifndef OBJCPLUS
+  if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
+    using_eh_for_cleanups ();
+#endif
+
   return true;
 }
 
@@ -5036,32 +5041,26 @@ objc_eh_personality (void)
 }
 #endif
 
-static void
-objc_init_exceptions (location_t loc)
+void
+objc_maybe_warn_exceptions (location_t loc)
 {
-  static bool done = false;
-
   /* -fobjc-exceptions is required to enable Objective-C exceptions.
      For example, on Darwin, ObjC exceptions require a sufficiently
      recent version of the runtime, so the user must ask for them
      explicitly.  On other platforms, at the moment -fobjc-exceptions
      triggers -fexceptions which again is required for exceptions to
-     work.
-  */
-  /* TODO: we only really need one error message when the flag is missing.  */
+     work.  */
   if (!flag_objc_exceptions)
     {
-      error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
-    }
+      /* Warn only once per compilation unit.  */
+      static bool warned = false;
 
-  if (done)
-    return;
-  done = true;
-
-#ifndef OBJCPLUS
-  if (!flag_objc_sjlj_exceptions)
-    using_eh_for_cleanups ();
-#endif
+      if (!warned)
+       {
+         error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
+         warned = true;
+       }
+    }
 }
 
 /* Build __builtin_eh_pointer, or the moral equivalent.  In the case
@@ -5365,8 +5364,6 @@ objc_begin_try_stmt (location_t try_locus, tree bo
   c->end_try_locus = input_location;
   cur_try_context = c;
 
-  objc_init_exceptions (try_locus);
-
   /* Collect the list of local variables.  We'll mark them as volatile
      at the end of compilation of this function to prevent them being
      clobbered by setjmp/longjmp.  */
@@ -5573,7 +5570,7 @@ objc_build_throw_stmt (location_t loc, tree throw_
 {
   tree args;
 
-  objc_init_exceptions (loc); 
+  objc_maybe_warn_exceptions (loc);
 
   if (throw_expr == NULL)
     {
Index: objc/ChangeLog
===================================================================
--- objc/ChangeLog      (revision 168020)
+++ objc/ChangeLog      (working copy)
@@ -1,3 +1,12 @@
+2010-12-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc-act.c (objc_init): Call using_eh_for_cleanups.
+       (objc_init_exceptions): Renamed to objc_maybe_warn_exceptions.  Do
+       not call using_eh_for_cleanups.
+       (objc_begin_try_stmt): Do not call objc_init_exceptions.
+       (objc_build_throw_stmt): Updated call to
+       objc_maybe_warn_exceptions.
+
 2010-12-18  Iain Sandoe  <iains@gcc.gnu.org>
 
        * objc/objc-act.c (objc_eh_personality): Select personality name on
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 168020)
+++ ChangeLog   (working copy)
@@ -1,3 +1,10 @@
+2010-12-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * c-parser.c (c_parser_objc_try_catch_finally_statement): Call
+       objc_maybe_warn_exceptions.
+       (c_parser_objc_synchronized_statement): Call
+       objc_maybe_warn_exceptions.
+       
 2010-12-18  Kai Tietz  <kai.tietz@onevision.com>
 
        PR target/36834
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog (revision 168020)
+++ testsuite/ChangeLog (working copy)
@@ -1,6 +1,15 @@
+2010-12-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * objc.dg/fobjc-exceptions-1.m: Updated.
+       * objc.dg/fobjc-exceptions-2.m: New.
+       * objc.dg/fobjc-exceptions-3.m: New.
+       * obj-c++.dg/fobjc-exceptions-1.mm: New.
+       * obj-c++.dg/fobjc-exceptions-2.mm: New.
+       * obj-c++.dg/fobjc-exceptions-3.mm: New.
+       
 2010-12-18  Iain Sandoe  <iains@gcc.gnu.org>
 
-       * fobjc-exceptions.m: Update dg-error syntax.
+       * objc.dg/fobjc-exceptions.m: Update dg-error syntax.
 
 2010-12-18  Kai Tietz  <kai.tietz@onevision.com>
 
Index: testsuite/objc.dg/fobjc-exceptions-2.m
===================================================================
--- testsuite/objc.dg/fobjc-exceptions-2.m      (revision 0)
+++ testsuite/objc.dg/fobjc-exceptions-2.m      (revision 0)
@@ -0,0 +1,29 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions.  */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+  @synchronized (o) /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+    {
+      number++;
+    }
+
+  @try {            /* Nothing, error has already been produced.  */
+    number++;
+    @throw o;       /* Nothing, error has already been produced.  */
+  }
+  @catch (id object)
+    {
+      number++;
+      @throw;       /* Nothing, error has already been produced.  */
+    }
+  @finally
+    {
+      number++;
+    }
+  
+  
+  return number;
+}
Index: testsuite/objc.dg/fobjc-exceptions-3.m
===================================================================
--- testsuite/objc.dg/fobjc-exceptions-3.m      (revision 0)
+++ testsuite/objc.dg/fobjc-exceptions-3.m      (revision 0)
@@ -0,0 +1,30 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions.  */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+  @throw o;           /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+
+  @try {              /* Nothing, error has already been produced.  */
+    number++;
+    @throw o;         /* Nothing, error has already been produced.  */
+  }
+  @catch (id object)
+    {
+      number++;
+      @throw;        /* Nothing, error has already been produced.  */
+    }
+  @finally
+    {
+      number++;
+    }
+  
+  @synchronized (o)   /* Nothing, error has already been produced.  */
+    {
+      number++;
+    }
+  
+  return number;
+}
Index: testsuite/objc.dg/fobjc-exceptions.m
===================================================================
--- testsuite/objc.dg/fobjc-exceptions.m        (revision 168020)
+++ testsuite/objc.dg/fobjc-exceptions.m        (working copy)
@@ -1,28 +0,0 @@
-/* Test that Objective-C exceptions cause an error with -fobjc-exceptions.  */
-/* { dg-do compile } */
-
-@class Object;
-
-int dummy (int number, Object *o)
-{
-  @try {            /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
-    number++;
-    @throw o;     /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
-  }
-  @catch (id object)
-    {
-      number++;
-      @throw;       /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
-    }
-  @finally
-    {
-      number++;
-    }
-  
-  @synchronized (o) /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
-    {
-      number++;
-    }
-  
-  return number;
-}
Index: testsuite/objc.dg/fobjc-exceptions-1.m
===================================================================
--- testsuite/objc.dg/fobjc-exceptions-1.m      (revision 168020)
+++ testsuite/objc.dg/fobjc-exceptions-1.m      (working copy)
@@ -7,19 +7,19 @@ int dummy (int number, Object *o)
 {
   @try {            /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
     number++;
-    @throw o;     /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+    @throw o;       /* Nothing, error has already been produced.  */
   }
   @catch (id object)
     {
       number++;
-      @throw;       /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+      @throw;       /* Nothing, error has already been produced.  */
     }
   @finally
     {
       number++;
     }
   
-  @synchronized (o) /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+  @synchronized (o) /* Nothing, error has already been produced.  */
     {
       number++;
     }
Index: testsuite/obj-c++.dg/fobjc-exceptions-2.mm
===================================================================
--- testsuite/obj-c++.dg/fobjc-exceptions-2.mm  (revision 0)
+++ testsuite/obj-c++.dg/fobjc-exceptions-2.mm  (revision 0)
@@ -0,0 +1,29 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions.  */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+  @synchronized (o) /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+    {
+      number++;
+    }
+
+  @try {            /* Nothing, error has already been produced.  */
+    number++;
+    @throw o;       /* Nothing, error has already been produced.  */
+  }
+  @catch (id object)
+    {
+      number++;
+      @throw;       /* Nothing, error has already been produced.  */
+    }
+  @finally
+    {
+      number++;
+    }
+  
+  
+  return number;
+}
Index: testsuite/obj-c++.dg/fobjc-exceptions-3.mm
===================================================================
--- testsuite/obj-c++.dg/fobjc-exceptions-3.mm  (revision 0)
+++ testsuite/obj-c++.dg/fobjc-exceptions-3.mm  (revision 0)
@@ -0,0 +1,30 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions.  */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+  @throw o;           /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+
+  @try {              /* Nothing, error has already been produced.  */
+    number++;
+    @throw o;         /* Nothing, error has already been produced.  */
+  }
+  @catch (id object)
+    {
+      number++;
+      @throw;        /* Nothing, error has already been produced.  */
+    }
+  @finally
+    {
+      number++;
+    }
+  
+  @synchronized (o)   /* Nothing, error has already been produced.  */
+    {
+      number++;
+    }
+  
+  return number;
+}
Index: testsuite/obj-c++.dg/fobjc-exceptions-1.mm
===================================================================
--- testsuite/obj-c++.dg/fobjc-exceptions-1.mm  (revision 0)
+++ testsuite/obj-c++.dg/fobjc-exceptions-1.mm  (revision 0)
@@ -0,0 +1,28 @@
+/* Test that Objective-C exceptions cause an error with -fobjc-exceptions.  */
+/* { dg-do compile } */
+
+@class Object;
+
+int dummy (int number, Object *o)
+{
+  @try {            /* { dg-error ".-fobjc-exceptions. is required to enable Objective-C exception syntax" } */
+    number++;
+    @throw o;       /* Nothing, error has already been produced.  */
+  }
+  @catch (id object)
+    {
+      number++;
+      @throw;       /* Nothing, error has already been produced.  */
+    }
+  @finally
+    {
+      number++;
+    }
+  
+  @synchronized (o) /* Nothing, error has already been produced.  */
+    {
+      number++;
+    }
+  
+  return number;
+}
Index: cp/ChangeLog
===================================================================
--- cp/ChangeLog        (revision 168020)
+++ cp/ChangeLog        (working copy)
@@ -1,3 +1,9 @@
+2010-12-18  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       * parser.c (cp_parser_objc_try_catch_finally_statement): Call
+       objc_maybe_warn_exceptions.
+       (cp_parser_objc_synchronized_statement): Same change.
+       
 2010-12-17  Jason Merrill  <jason@redhat.com>
 
        PR c++/46670
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 168020)
+++ cp/parser.c (working copy)
@@ -22692,6 +22692,7 @@ cp_parser_objc_try_catch_finally_statement (cp_par
 
   cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY);
   location = cp_lexer_peek_token (parser->lexer)->location;
+  objc_maybe_warn_exceptions (location);
   /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
      node, lest it get absorbed into the surrounding block.  */
   stmt = push_stmt_list ();
@@ -22784,6 +22785,7 @@ cp_parser_objc_synchronized_statement (cp_parser *
   cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED);
 
   location = cp_lexer_peek_token (parser->lexer)->location;
+  objc_maybe_warn_exceptions (location);
   cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   lock = cp_parser_expression (parser, false, NULL);
   cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
Index: c-parser.c
===================================================================
--- c-parser.c  (revision 168020)
+++ c-parser.c  (working copy)
@@ -7547,6 +7547,7 @@ c_parser_objc_try_catch_finally_statement (c_parse
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
   c_parser_consume_token (parser);
   location = c_parser_peek_token (parser)->location;
+  objc_maybe_warn_exceptions (location);
   stmt = c_parser_compound_statement (parser);
   objc_begin_try_stmt (location, stmt);
 
@@ -7628,6 +7629,7 @@ c_parser_objc_synchronized_statement (c_parser *pa
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
   c_parser_consume_token (parser);
   loc = c_parser_peek_token (parser)->location;
+  objc_maybe_warn_exceptions (loc);
   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     {
       expr = c_parser_expression (parser).value;
