This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[c/c++/fortran] PR35058: -Werror= works only with some warnin


The following patch implements pedwarn (OPT_*, ...) and pedwarn0() as
discussed here:
http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00972.html

It also fixes PR 35058.

Bootstrapped with --enable-languages=all and regression tested on
x86_64-unknown-linux-gnu.

OK for 4.4?

Cheers,

Manuel.

(Writing this Changelog entry was a horrible horrible experience! And
I find it totally uninformative. I think there is something wrong with
our approach.)



2008-06-13  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

        PR 35058
	* diagnostic.c (pedwarn): Add opt parameter.
	(pedwarn0): New. Equivalent to pedwarn(0,...).
	* c-tree.h (pedwarn_init): Add opt parameter.
	(pedwarn_c90): Likewise.
	(pedwarn_c99): Likewise.
	* c-errors.c (pedwarn_c99): Likewise.
	(pedwarn_c90): Likewise.
	* toplev.h (pedwarn): Update declaration.
	(pedwarn0): Declare.
	* toplev.c (check_global_declaration_1): Use OPT_pedantic for
	pedwarn conditional on -pedantic. Use pedwarn0 for unconditional
	pedwarn.
	* c-lex.c (interpret_integer): Likewise.
	(interpret_float): Likewise.
	* c-decl.c (pop_scope): Likewise.
	(diagnose_mismatched_decls): Likewise.
	(implicit_decl_warning): Use OPT_Wimplicit_function_declaration.
	(shadow_tag_warned): Use OPT_pedantic for pedwarn conditional on
	-pedantic. Use pedwarn0 for unconditional pedwarn.
	(build_array_declarator): Likewise.
	(start_decl): Likewise.
	(mark_forward_parm_decls): Likewise.
	(check_bitfield_type_and_width): Likewise. Use OPT_Wvla.
	(grokdeclarator): Use either 0 or OPT_Wimplicit_int.
	Use OPT_pedantic for pedwarn conditional on -pedantic. Use
	pedwarn0 for unconditional pedwarn.
	(grokparms): Likewise.
	(grokfield): Likewise.
	(finish_struct): Likewise.
	(build_enumerator): Likewise.
	(start_function): Use either 0, OPT_Wreturn_type or
	OPT_Wimplicit_int.
	Use OPT_Wmain.
	(store_parm_decls_oldstyle): Use OPT_pedantic for pedwarn
	conditional on -pedantic. Use pedwarn0 for unconditional pedwarn.
	(finish_function): Likewise.
	(declspecs_add_qual): Likewise.
	(declspecs_add_type): Use OPT_Wlong_long. Use OPT_pedantic for pedwarn
	conditional on -pedantic. Use pedwarn0 for unconditional pedwarn.
	(finish_declspecs): Likewise.
	(c_write_global_declarations_1): Likewise.
	* c-typeck.c (composite_type): Likewise.
	(function_types_compatible_p): Likewise.
	(build_array_ref): Likewise.
	(build_external_ref): Likewise.
	(build_function_call): Use 0 for unconditional pedwarn_init.
	(pointer_diff): Use either OPT_pedantic or OPT_Wpointer_arith.
	(build_unary_op): Use either OPT_pedantic or
	OPT_Wpointer_arith. Use OPT_pedantic for pedwarn conditional on
	-pedantic. Use pedwarn0 for unconditional pedwarn.
	(c_mark_addressable): Likewise.
	(build_conditional_expr): Likewise.
	(build_c_cast): Likewise.
	(convert_for_assignment): Likewise.
	(pedwarn_init): Add opt parameter.
	(maybe_warn_string_init): Use OPT_pedantic for pedwarn conditional on
	-pedantic. Use pedwarn0 for unconditional pedwarn.
	(digest_init): Likewise.
	(pop_init_level): Likewise.
	(output_init_element): Likewise.
	(process_init_element): Likewise.
	(c_finish_goto_label): Likewise.
	(c_finish_return): Use either 0 or OPT_Wreturn_type.
	(build_binary_op): Use OPT_pedantic for pedwarn conditional on
	-pedantic. Use pedwarn0 for unconditional pedwarn.
	* c-common.c (fname_decl): Likewise.
	(fix_string_type): Use OPT_Woverlenght_strings.
	(constant_expression_warning): Use OPT_Woverflow.
	(check_main_parameter_types): Use OPT_pedantic for pedwarn
	conditional on -pedantic. Use pedwarn0 for unconditional pedwarn.
	(pointer_int_sum): Likewise. Use either OPT_pedantic or
	OPT_Wpointer_arith.
	(c_sizeof_or_alignof_type): Likewise.
	(finish_label_address_expr): Likewise.
	* c-parser.c (c_parser_translation_unit): Likewise.
	(c_parser_external_declaration): Likewise.
	(c_parser_declaration_or_fndef): Likewise.
	(c_parser_enum_specifier): Likewise.
	(c_parser_struct_or_union_specifier): Likewise.
	(c_parser_struct_declaration): Likewise.
	(c_parser_braced_init): Likewise.
	(c_parser_initelt): Likewise.
	(c_parser_compound_statement_nostart): Likewise. Use either
	OPT_pedantic or OPT_Wdeclaration_after_statement.
	(c_parser_conditional_expression): Use OPT_pedantic for pedwarn
	conditional on -pedantic. Use pedwarn0 for unconditional pedwarn.
	(c_parser_postfix_expression): Likewise.
	(c_parser_objc_class_instance_variables): Likewise.
	(c_parser_objc_method_definition): Likewise.
	(c_parser_objc_methodprotolist): Likewise.
	
	fortran/
	* f95-lang.c (gfc_mark_addressable): Likewise.
	
	cp/
	* typeck.c (composite_pointer_type_r): Likewise.
	(composite_pointer_type): Likewise.
	(cxx_sizeof_or_alignof_type): Likewise. Use either OPT_pedantic or
	OPT_Wpointer_arith.
	(cxx_sizeof_expr): Likewise.
	(cxx_alignof_expr): Likewise.
	(check_template_keyword): Likewise.
	(build_array_ref): Likewise.
	(cp_build_function_call): Likewise.
	(cp_build_binary_op): Likewise.
	(pointer_diff): Likewise. Use either OPT_pedantic or
	OPT_Wpointer_arith.
	(cp_build_unary_op): Likewise.
	(build_x_compound_expr_from_list): Likewise.
	(convert_member_func_to_ptr): Likewise. Use either OPT_pedantic or
	OPT_Wpmf_conversions.
	(build_reinterpret_cast_1): Likewise.
	(cp_build_c_cast): Likewise.
	(check_return_expr): Likewise.
	(cp_apply_type_quals_to_decl): Likewise.
	* init.c (perform_member_init): Likewise.
	(build_new_1): Likewise.
	* decl.c (warn_extern_redeclared_static): Likewise.
	(duplicate_decls): Likewise.
	(decl_jump_unsafe): Likewise.
	(check_previous_goto_1): Likewise.
	(check_goto): Likewise.
	(define_label): Likewise.
	(check_tag_decl): Likewise.
	(start_decl): Likewise.
	(check_class_member_definition_namespace): Likewise.
	(grokfndecl): Likewise.
	(check_static_variable_definition): Likewise.
	(compute_array_index_type): Likewise. Use OPT_Wvla for pedwarn
	conditional on -Wvla.
	(grokdeclarator): Likewise. Use either 0 or OPT_pedantic.
	(grok_op_properties): Likewise.
	* call.c (build_conditional_expr): Likewise.
	* except.c (check_handlers): Likewise.
	* error.c (maybe_warn_variadic_templates): Likewise.
	* friend.c (make_friend_class): Likewise.
	* typeck2.c (cxx_incomplete_type_diagnostic): Likewise.
	(digest_init): Likewise.
	* pt.c (check_specialization_namespace): Likewise.
	(check_explicit_instantiation_namespace): Likewise.
	(maybe_process_partial_specialization): Likewise.
	(check_explicit_specialization): Likewise.
	(convert_template_argument): Likewise.
	(do_decl_instantiation): Likewise.
	(do_type_instantiation): Likewise.
	(instantiate_decl):  Likewise.
	* semantics.c (finish_translation_unit): Likewise.
	* name-lookup.c (pushdecl_maybe_friend): Likewise.
	(check_for_out_of_scope_variable): Likewise.
	(finish_static_data_member_decl): Likewise.
	(build_anon_union_vars): Likewise.
	(coerce_new_type): Likewise.
	* parser.c (cp_parser_check_decl_spec): Use OPT_Wlong_long.
	(cp_parser_primary_expression): Likewise.
	(cp_parser_nested_name_specifier_opt): Likewise.
	(cp_parser_postfix_expression): Likewise.
	(cp_parser_jump_statement): Likewise.
	(cp_parser_declaration_seq_opt): Likewise.
	(cp_parser_mem_initializer): Likewise.
	(cp_parser_elaborated_type_specifier): Likewise.
	(cp_parser_enumerator_list): Likewise.
	(cp_parser_initializer_list): Likewise.
	(cp_parser_class_head): Likewise.
	(cp_parser_member_declaration): Likewise.
	(cp_parser_token_is_class_key): Likewise.
	
	testsuite/
	* gcc.dg/Wdeclaration-after-statement-3.c: New.
	* gcc/testsuite/gcc.dg/Wpointer-arith.c: New.
Index: gcc/c-lex.c
===================================================================
--- gcc/c-lex.c	(revision 136559)
+++ gcc/c-lex.c	(working copy)
@@ -583,12 +583,12 @@ interpret_integer (const cpp_token *toke
     type = integer_types[itk];
 
   if (itk > itk_unsigned_long
       && (flags & CPP_N_WIDTH) != CPP_N_LARGE
       && !in_system_header && !flag_isoc99)
-    pedwarn ("integer constant is too large for %qs type",
-	     (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
+    pedwarn0 ("integer constant is too large for %qs type",
+	      (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
 
   value = build_int_cst_wide (type, integer.low, integer.high);
 
   /* Convert imaginary to a complex type.  */
   if (flags & CPP_N_IMAGINARY)
@@ -637,12 +637,12 @@ interpret_float (const cpp_token *token,
 	    error ("unsupported non-standard suffix on floating constant");
 	    errorcount++;
 
 	    return error_mark_node;
 	  }
-	else if (pedantic)
-	  pedwarn ("non-standard suffix on floating constant");
+	else
+	  pedwarn (OPT_pedantic, "non-standard suffix on floating constant");
 
 	type = c_common_type_for_mode (mode, 0);
 	gcc_assert (type);
       }
     else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
@@ -680,11 +680,11 @@ interpret_float (const cpp_token *token,
      have __builtin_inf* to produce an infinity, this is now a
      mandatory pedwarn if the target does not support infinities.  */
   if (REAL_VALUE_ISINF (real)) 
     {
       if (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
-	pedwarn ("floating constant exceeds range of %qT", type);
+	pedwarn0 ("floating constant exceeds range of %qT", type);
       else
 	warning (OPT_Woverflow, "floating constant exceeds range of %qT", type);
     }
   /* We also give a warning if the value underflows.  */
   else if (REAL_VALUES_EQUAL (real, dconst0))
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 136559)
+++ gcc/diagnostic.c	(working copy)
@@ -503,20 +503,39 @@ warning0 (const char *gmsgid, ...)
    this for diagnostics required by the relevant language standard,
    if you have chosen not to make them errors.
 
    Note that these diagnostics are issued independent of the setting
    of the -pedantic command-line switch.  To get a warning enabled
-   only with that switch, write "if (pedantic) pedwarn (...);"  */
+   only with that switch, use either "if (pedantic) pedwarn
+   (OPT_pedantic,...)" or just "pedwarn (OPT_pedantic,..)".  To get a
+   pedwarn independently of the -pedantic switch use "pedwarn0 (...)"
+   or "pedwarn (0,...)".  */
+
+void
+pedwarn (int opt, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
+                      pedantic_warning_kind ());
+  diagnostic.option_index = opt;
+
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
 void
-pedwarn (const char *gmsgid, ...)
+pedwarn0 (const char *gmsgid, ...)
 {
   diagnostic_info diagnostic;
   va_list ap;
 
   va_start (ap, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
-		       pedantic_warning_kind ());
+                      pedantic_warning_kind ());
   report_diagnostic (&diagnostic);
   va_end (ap);
 }
 
 /* A "permissive" error: issues an error unless -fpermissive was given
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 136559)
+++ gcc/builtins.c	(working copy)
@@ -7227,11 +7227,11 @@ fold_builtin_inf (tree type, int warn)
      time", footnote "In this case, using INFINITY will violate the
      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
      Thus we pedwarn to ensure this constraint violation is
      diagnosed.  */
   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
-    pedwarn ("target format does not support infinity");
+    pedwarn0 ("target format does not support infinity");
 
   real_inf (&real);
   return build_real (type, real);
 }
 
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 136559)
+++ gcc/toplev.c	(working copy)
@@ -828,11 +828,11 @@ check_global_declaration_1 (tree decl)
       && ! TREE_PUBLIC (decl)
       && (warn_unused_function
 	  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
     {
       if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
-	pedwarn ("%q+F used but never defined", decl);
+	pedwarn0 ("%q+F used but never defined", decl);
       else
 	warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl);
       /* This symbol is effectively an "extern" declaration now.  */
       TREE_PUBLIC (decl) = 1;
       assemble_external (decl);
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h	(revision 136559)
+++ gcc/toplev.h	(working copy)
@@ -59,11 +59,13 @@ extern void warning0 (const char *, ...)
 /* Pass one of the OPT_W* from options.h as the first parameter.  */
 extern void warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
      ATTRIBUTE_NORETURN;
-extern void pedwarn (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+extern void pedwarn0 (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+/* Pass one of the OPT_W* from options.h as the first parameter.  */
+extern void pedwarn (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void permerror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void inform (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 
Index: gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c
===================================================================
--- gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c	(revision 0)
@@ -0,0 +1,24 @@
+/* PR 35058: -Werror= works only with some warnings. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedanti -Werror=declaration-after-statement" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+  int i = 0;
+  if (i != 0)
+    abort ();
+  i++;
+  if (i != 1)
+    abort ();
+  int j = i;				/* { dg-warning "" "declaration-after-statement" } */
+  if (j != 1)
+    abort ();
+  struct foo { int i0; } k = { 4 };	/* { dg-warning "" "declaration-after-statement" } */
+  if (k.i0 != 4)
+    abort ();
+  exit (0);
+}
Index: gcc/testsuite/gcc.dg/Wpointer-arith.c
===================================================================
--- gcc/testsuite/gcc.dg/Wpointer-arith.c	(revision 0)
+++ gcc/testsuite/gcc.dg/Wpointer-arith.c	(revision 0)
@@ -0,0 +1,10 @@
+/* PR 35058: -Werror= works only with some warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Werror=pointer-arith" } */
+void *a;
+
+void *test(){
+  int x=5;
+  if(a) a++; /* { dg-error "wrong type argument to increment" } */
+  return a+x; /* { dg-error "pointer of type" } */
+}
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 136559)
+++ gcc/cp/typeck.c	(working copy)
@@ -433,13 +433,12 @@ composite_pointer_type_r (tree t1, tree 
     result_type = composite_pointer_type_r (pointee1, pointee2, location,
 					    complain);
   else
     {
       if (complain & tf_error)
-	pedwarn ("%s between distinct pointer types %qT and %qT "
-		 "lacks a cast",
-		 location, t1, t2);
+	pedwarn0 ("%s between distinct pointer types %qT and %qT "
+		  "lacks a cast", location, t1, t2);
       result_type = void_type_node;
     }
   result_type = cp_build_qualified_type (result_type,
 					 (cp_type_quals (pointee1)
 					  | cp_type_quals (pointee2)));
@@ -448,13 +447,12 @@ composite_pointer_type_r (tree t1, tree 
   if (TYPE_PTR_TO_MEMBER_P (t1))
     {
       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
 			TYPE_PTRMEM_CLASS_TYPE (t2))
 	  && (complain & tf_error))
-	pedwarn ("%s between distinct pointer types %qT and %qT "
-		 "lacks a cast",
-		 location, t1, t2);
+	pedwarn0 ("%s between distinct pointer types %qT and %qT "
+		  "lacks a cast", location, t1, t2);
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
 				       result_type);
     }
   else
     result_type = build_pointer_type (result_type);
@@ -509,13 +507,14 @@ composite_pointer_type (tree t1, tree t2
   if (TREE_CODE (t1) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t1)))
     {
       tree attributes;
       tree result_type;
 
-      if (pedantic && TYPE_PTRFN_P (t2) && (complain & tf_error))
-	pedwarn ("ISO C++ forbids %s between pointer of type %<void *%> "
-		 "and pointer-to-function", location);
+      if (TYPE_PTRFN_P (t2) && (complain & tf_error))
+	pedwarn (OPT_pedantic, "ISO C++ forbids %s "
+		 "between pointer of type %<void *%> and pointer-to-function",
+		 location);
       result_type
 	= cp_build_qualified_type (void_type_node,
 				   (cp_type_quals (TREE_TYPE (t1))
 				    | cp_type_quals (TREE_TYPE (t2))));
       result_type = build_pointer_type (result_type);
@@ -1276,12 +1275,13 @@ cxx_sizeof_or_alignof_type (tree type, e
     return error_mark_node;
 
   type = non_reference (type);
   if (TREE_CODE (type) == METHOD_TYPE)
     {
-      if (complain && (pedantic || warn_pointer_arith))
-	pedwarn ("invalid application of %qs to a member function", 
+      if (complain)
+	pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+		 "invalid application of %qs to a member function", 
 		 operator_name_info[(int) op].name);
       value = size_one_node;
     }
 
   dependent_p = dependent_type_p (type);
@@ -1353,12 +1353,12 @@ cxx_sizeof_expr (tree e, tsubst_flags_t 
       e = char_type_node;
     }
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        pedwarn ("ISO C++ forbids applying %<sizeof%> to an expression of "
-                 "function type");
+        pedwarn0 ("ISO C++ forbids applying %<sizeof%> to an expression of "
+		  "function type");
       else
         return error_mark_node;
       e = char_type_node;
     }
   else if (type_unknown_p (e))
@@ -1413,12 +1413,12 @@ cxx_alignof_expr (tree e, tsubst_flags_t
 	   && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
     t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of "
-                 "function type");
+        pedwarn0 ("ISO C++ forbids applying %<__alignof%> to an expression of "
+		  "function type");
       else
         return error_mark_node;
       if (TREE_CODE (e) == FUNCTION_DECL)
 	t = size_int (DECL_ALIGN_UNIT (e));
       else
@@ -2144,11 +2144,11 @@ check_template_keyword (tree decl)
      functions containing at least one template function.  */
   if (TREE_CODE (decl) != TEMPLATE_DECL
       && TREE_CODE (decl) != TEMPLATE_ID_EXPR)
     {
       if (!is_overloaded_fn (decl))
-	pedwarn ("%qD is not a template", decl);
+	pedwarn0 ("%qD is not a template", decl);
       else
 	{
 	  tree fns;
 	  fns = decl;
 	  if (BASELINK_P (fns))
@@ -2164,11 +2164,11 @@ check_template_keyword (tree decl)
 		  && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
 		break;
 	      fns = OVL_NEXT (fns);
 	    }
 	  if (!fns)
-	    pedwarn ("%qD is not a template", decl);
+	    pedwarn0 ("%qD is not a template", decl);
 	}
     }
 }
 
 /* This function is called by the parser to process a class member
@@ -2594,12 +2594,12 @@ build_array_ref (tree array, tree idx)
 	{
 	  if (!cxx_mark_addressable (array))
 	    return error_mark_node;
 	}
 
-      if (pedantic && !lvalue_p (array))
-	pedwarn ("ISO C++ forbids subscripting non-lvalue array");
+      if (!lvalue_p (array))
+	pedwarn (OPT_pedantic, "ISO C++ forbids subscripting non-lvalue array");
 
       /* Note in C++ it is valid to subscript a `register' array, since
 	 it is valid to take the address of something with that
 	 storage specification.  */
       if (extra_warnings)
@@ -2820,12 +2820,13 @@ cp_build_function_call (tree function, t
 
       mark_used (function);
       fndecl = function;
 
       /* Convert anything with function type to a pointer-to-function.  */
-      if (pedantic && DECL_MAIN_P (function) && (complain & tf_error))
-	pedwarn ("ISO C++ forbids calling %<::main%> from within program");
+      if (DECL_MAIN_P (function) && (complain & tf_error))
+	pedwarn (OPT_pedantic, 
+		 "ISO C++ forbids calling %<::main%> from within program");
 
       /* Differs from default_conversion by not setting TREE_ADDRESSABLE
 	 (because calling an inline function does not mean the function
 	 needs to be separately compiled).  */
 
@@ -3256,23 +3257,23 @@ cp_build_binary_op (enum tree_code code,
     {
       tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none);
       if (t != error_mark_node)
 	{
 	  if (complain & tf_error)
-	    pedwarn ("assuming cast to type %qT from overloaded function",
-		     TREE_TYPE (t));
+	    pedwarn0 ("assuming cast to type %qT from overloaded function",
+		      TREE_TYPE (t));
 	  op0 = t;
 	}
     }
   if (type_unknown_p (op1))
     {
       tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none);
       if (t != error_mark_node)
 	{
 	  if (complain & tf_error)
-	    pedwarn ("assuming cast to type %qT from overloaded function",
-		     TREE_TYPE (t));
+	    pedwarn0 ("assuming cast to type %qT from overloaded function",
+		      TREE_TYPE (t));
 	  op1 = t;
 	}
     }
 
   type0 = TREE_TYPE (op0);
@@ -3542,19 +3543,19 @@ cp_build_binary_op (enum tree_code code,
 	}
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  result_type = type0;
 	  if (complain & tf_error) 
-            pedwarn ("ISO C++ forbids comparison between pointer and integer");
+            pedwarn0 ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
 	{
 	  result_type = type1;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    pedwarn0 ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
       else if (TYPE_PTRMEMFUNC_P (type0) && null_ptr_cst_p (op1))
 	{
@@ -3730,19 +3731,19 @@ cp_build_binary_op (enum tree_code code,
 	result_type = type1;
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  result_type = type0;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    pedwarn0 ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
 	{
 	  result_type = type1;
 	  if (complain & tf_error)
-	    pedwarn ("ISO C++ forbids comparison between pointer and integer");
+	    pedwarn0 ("ISO C++ forbids comparison between pointer and integer");
           else
             return error_mark_node;
 	}
       break;
 
@@ -4106,19 +4107,19 @@ pointer_diff (tree op0, tree op1, tree p
   tree target_type = TREE_TYPE (ptrtype);
 
   if (!complete_type_or_else (target_type, NULL_TREE))
     return error_mark_node;
 
-  if (pedantic || warn_pointer_arith)
-    {
-      if (TREE_CODE (target_type) == VOID_TYPE)
-	pedwarn ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
-      if (TREE_CODE (target_type) == FUNCTION_TYPE)
-	pedwarn ("ISO C++ forbids using pointer to a function in subtraction");
-      if (TREE_CODE (target_type) == METHOD_TYPE)
-	pedwarn ("ISO C++ forbids using pointer to a method in subtraction");
-    }
+  if (TREE_CODE (target_type) == VOID_TYPE)
+    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	     "ISO C++ forbids using pointer of type %<void *%> in subtraction");
+  if (TREE_CODE (target_type) == FUNCTION_TYPE)
+    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	     "ISO C++ forbids using pointer to a function in subtraction");
+  if (TREE_CODE (target_type) == METHOD_TYPE)
+    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	     "ISO C++ forbids using pointer to a method in subtraction");
 
   /* First do the subtraction as integers;
      then drop through to build the divide operator.  */
 
   op0 = cp_build_binary_op (MINUS_EXPR,
@@ -4479,13 +4480,13 @@ cp_build_unary_op (enum tree_code code, 
 
 	/* ARM $5.2.5 last annotation says this should be forbidden.  */
 	if (TREE_CODE (argtype) == ENUMERAL_TYPE)
           {
             if (complain & tf_error)
-              pedwarn ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-                       ? G_("ISO C++ forbids incrementing an enum")
-                       : G_("ISO C++ forbids decrementing an enum"));
+              pedwarn0 ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+			? G_("ISO C++ forbids incrementing an enum")
+			: G_("ISO C++ forbids decrementing an enum"));
             else
               return error_mark_node;
           }
 
 	/* Compute the increment.  */
@@ -4507,15 +4508,15 @@ cp_build_unary_op (enum tree_code code, 
               }
 	    else if ((pedantic || warn_pointer_arith)
 		     && !TYPE_PTROB_P (argtype)) 
               {
                 if (complain & tf_error)
-                  pedwarn ((code == PREINCREMENT_EXPR
-                            || code == POSTINCREMENT_EXPR)
-                           ? G_("ISO C++ forbids incrementing a pointer of type %qT")
-                           : G_("ISO C++ forbids decrementing a pointer of type %qT"),
-                           argtype);
+                  pedwarn0 ((code == PREINCREMENT_EXPR
+			     || code == POSTINCREMENT_EXPR)
+			    ? G_("ISO C++ forbids incrementing a pointer of type %qT")
+			    : G_("ISO C++ forbids decrementing a pointer of type %qT"),
+			    argtype);
                 else
                   return error_mark_node;
               }
 
 	    inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
@@ -4568,11 +4569,12 @@ cp_build_unary_op (enum tree_code code, 
 	}
       else if (pedantic && DECL_MAIN_P (arg))
         {
           /* ARM $3.4 */
           if (complain & tf_error)
-            pedwarn ("ISO C++ forbids taking address of function %<::main%>");
+            pedwarn (OPT_pedantic, 
+		     "ISO C++ forbids taking address of function %<::main%>");
           else
             return error_mark_node;
         }
 
       /* Let &* cancel out to simplify resulting code.  */
@@ -4629,19 +4631,19 @@ cp_build_unary_op (enum tree_code code, 
               if (!(complain & tf_error))
                 return error_mark_node;
 	      else if (current_class_type
                        && TREE_OPERAND (arg, 0) == current_class_ref)
                   /* An expression like &memfn.  */
-                pedwarn ("ISO C++ forbids taking the address of an unqualified"
-                         " or parenthesized non-static member function to form"
-                         " a pointer to member function.  Say %<&%T::%D%>",
-                         base, name);
+                pedwarn0 ("ISO C++ forbids taking the address of an unqualified"
+			  " or parenthesized non-static member function to form"
+			  " a pointer to member function.  Say %<&%T::%D%>",
+			  base, name);
 	      else
-		pedwarn ("ISO C++ forbids taking the address of a bound member"
-			 " function to form a pointer to member function."
-			 "  Say %<&%T::%D%>",
-			 base, name);
+		pedwarn0 ("ISO C++ forbids taking the address of a bound member"
+			  " function to form a pointer to member function."
+			  "  Say %<&%T::%D%>",
+			  base, name);
 	    }
 	  arg = build_offset_ref (base, fn, /*address_p=*/true);
 	}
 
     offset_ref:
@@ -4663,11 +4665,13 @@ cp_build_unary_op (enum tree_code code, 
              extension when we're instantiating in a SFINAE
              context.  */
 	  if (! lvalue_p (arg) && (pedantic || complain == tf_none))
             {
               if (complain & tf_error)
-                pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
+                pedwarn ((complain == tf_none) ? 0 : OPT_pedantic, 
+			 "ISO C++ forbids taking the address of a cast to a "
+			 "non-lvalue expression");
               else
                 return error_mark_node;
             }
 	  break;
 
@@ -5008,11 +5012,11 @@ tree build_x_compound_expr_from_list (tr
   tree expr = TREE_VALUE (list);
 
   if (TREE_CHAIN (list))
     {
       if (msg)
-	pedwarn ("%s expression list treated as compound expression", msg);
+	pedwarn0 ("%s expression list treated as compound expression", msg);
 
       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
 	expr = build_x_compound_expr (expr, TREE_VALUE (list), 
                                       tf_warning_or_error);
     }
@@ -5448,11 +5452,12 @@ convert_member_func_to_ptr (tree type, t
   intype = TREE_TYPE (expr);
   gcc_assert (TYPE_PTRMEMFUNC_P (intype)
 	      || TREE_CODE (intype) == METHOD_TYPE);
 
   if (pedantic || warn_pmf2ptr)
-    pedwarn ("converting from %qT to %qT", intype, type);
+    pedwarn (pedantic ? OPT_pedantic : OPT_Wpmf_conversions,
+	     "converting from %qT to %qT", intype, type);
 
   if (TREE_CODE (intype) == METHOD_TYPE)
     expr = build_addr_func (expr);
   else if (TREE_CODE (expr) == PTRMEM_CST)
     expr = build_address (PTRMEM_CST_MEMBER (expr));
@@ -5559,12 +5564,12 @@ build_reinterpret_cast_1 (tree type, tre
   if (CP_INTEGRAL_TYPE_P (type) && TYPE_PTR_P (intype))
     {
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
           if (complain & tf_error)
-            pedwarn ("cast from %qT to %qT loses precision",
-                     intype, type);
+            pedwarn0 ("cast from %qT to %qT loses precision",
+		      intype, type);
           else
             return error_mark_node;
         }
     }
   /* [expr.reinterpret.cast]
@@ -5836,11 +5841,11 @@ cp_build_c_cast (tree type, tree expr, t
       /* Allow casting from T1* to T2[] because Cfront allows it.
 	 NIHCL uses it. It is not valid ISO C++ however.  */
       if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
 	{
           if (complain & tf_error)
-            pedwarn ("ISO C++ forbids casting to an array type %qT", type);
+            pedwarn0 ("ISO C++ forbids casting to an array type %qT", type);
           else
             return error_mark_node;
 	  type = build_pointer_type (TREE_TYPE (type));
 	}
       else
@@ -6962,12 +6967,12 @@ check_return_expr (tree retval, bool *no
 
   /* Check for a return statement with no return value in a function
      that's supposed to return a value.  */
   if (!retval && fn_returns_value_p)
     {
-      pedwarn ("return-statement with no value, in function returning %qT",
-	       valtype);
+      pedwarn0 ("return-statement with no value, in function returning %qT",
+		valtype);
       /* Clear this, so finish_function won't say that we reach the
 	 end of a non-void function (which we don't, we gave a
 	 return!).  */
       current_function_returns_null = 0;
       /* And signal caller that TREE_NO_WARNING should be set on the
@@ -6983,12 +6988,12 @@ check_return_expr (tree retval, bool *no
 	/* You can return a `void' value from a function of `void'
 	   type.  In that case, we have to evaluate the expression for
 	   its side-effects.  */
 	  finish_expr_stmt (retval);
       else
-	pedwarn ("return-statement with a value, in function "
-		 "returning 'void'");
+	pedwarn0 ("return-statement with a value, in function "
+		  "returning 'void'");
 
       current_function_returns_null = 1;
 
       /* There's really no value to return, after all.  */
       return NULL_TREE;
@@ -7341,11 +7346,12 @@ cp_apply_type_quals_to_decl (int type_qu
 	 a function type), but DR 295 makes the code well-formed by
 	 dropping the extra qualifiers. */
       if (pedantic)
 	{
 	  tree bad_type = build_qualified_type (type, type_quals);
-	  pedwarn ("ignoring %qV qualifiers added to function type %qT",
+	  pedwarn (OPT_pedantic, 
+		   "ignoring %qV qualifiers added to function type %qT",
 		   bad_type, type);
 	}
 
       TREE_TYPE (decl) = TYPE_MAIN_VARIANT (type);
       return;
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c	(revision 136559)
+++ gcc/cp/init.c	(working copy)
@@ -531,15 +531,15 @@ perform_member_init (tree member, tree i
 			 "which has reference type",
 			 current_function_decl, member);
 	    }
 	  /* member traversal: note it leaves init NULL */
 	  else if (TREE_CODE (type) == REFERENCE_TYPE)
-	    pedwarn ("%Juninitialized reference member %qD",
-		     current_function_decl, member);
+	    pedwarn0 ("%Juninitialized reference member %qD",
+		      current_function_decl, member);
 	  else if (CP_TYPE_CONST_P (type))
-	    pedwarn ("%Juninitialized member %qD with %<const%> type %qT",
-		     current_function_decl, member, type);
+	    pedwarn0 ("%Juninitialized member %qD with %<const%> type %qT",
+		      current_function_decl, member, type);
 	}
       else if (TREE_CODE (init) == TREE_LIST)
 	/* There was an explicit member initialization.  Do some work
 	   in that case.  */
 	init = build_x_compound_expr_from_list (init, "member initializer");
@@ -2156,11 +2156,11 @@ build_new_1 (tree placement, tree type, 
 	      explicit_default_init_p = true;
 	    }
 	  else if (init)
             {
               if (complain & tf_error)
-                pedwarn ("ISO C++ forbids initialization in array new");
+                pedwarn0 ("ISO C++ forbids initialization in array new");
               else
                 return error_mark_node;
             }
 	  init_expr
 	    = build_vec_init (init_expr,
@@ -2368,11 +2368,11 @@ build_new (tree placement, tree type, tr
   if (nelts)
     {
       if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
         {
           if (complain & tf_error)
-            pedwarn ("size in array new must have integral type");
+            pedwarn0 ("size in array new must have integral type");
           else
             return error_mark_node;
         }
       nelts = cp_save_expr (cp_convert (sizetype, nelts));
     }
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 136559)
+++ gcc/cp/decl.c	(working copy)
@@ -1053,12 +1053,12 @@ warn_extern_redeclared_static (tree newd
   if (TREE_CODE (olddecl) == FUNCTION_DECL
       && DECL_ARTIFICIAL (olddecl))
     return;
 
   name = DECL_ASSEMBLER_NAME (newdecl);
-  pedwarn ("%qD was declared %<extern%> and later %<static%>", newdecl);
-  pedwarn ("previous declaration of %q+D", olddecl);
+  pedwarn0 ("%qD was declared %<extern%> and later %<static%>", newdecl);
+  pedwarn0 ("previous declaration of %q+D", olddecl);
 }
 
 /* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
    function templates.  If their exception specifications do not
    match, issue a diagnostic.  */
@@ -1537,13 +1537,13 @@ duplicate_decls (tree newdecl, tree oldd
 	    if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
 	      {
 		if (1 == simple_cst_equal (TREE_PURPOSE (t1),
 					   TREE_PURPOSE (t2)))
 		  {
-		    pedwarn ("default argument given for parameter %d of %q#D",
-			     i, newdecl);
-		    pedwarn ("after previous specification in %q+#D", olddecl);
+		    pedwarn0 ("default argument given for parameter %d of %q#D",
+			      i, newdecl);
+		    pedwarn0 ("after previous specification in %q+#D", olddecl);
 		  }
 		else
 		  {
 		    error ("default argument given for parameter %d of %q#D",
 			   i, newdecl);
@@ -2456,15 +2456,15 @@ decl_jump_unsafe (tree decl)
 
 static void
 identify_goto (tree decl, const location_t *locus)
 {
   if (decl)
-    pedwarn ("jump to label %qD", decl);
+    pedwarn0 ("jump to label %qD", decl);
   else
-    pedwarn ("jump to case label");
+    pedwarn0 ("jump to case label");
   if (locus)
-    pedwarn ("%H  from here", locus);
+    pedwarn0 ("%H  from here", locus);
 }
 
 /* Check that a single previously seen jump to a newly defined label
    is OK.  DECL is the LABEL_DECL or 0; LEVEL is the binding_level for
    the jump context; NAMES are the names in scope in LEVEL at the jump
@@ -2502,11 +2502,11 @@ check_previous_goto_1 (tree decl, struct
 	      identified = true;
 	    }
 	  if (problem > 1)
 	    error ("  crosses initialization of %q+#D", new_decls);
 	  else
-	    pedwarn ("  enters scope of non-POD %q+#D", new_decls);
+	    pedwarn0 ("  enters scope of non-POD %q+#D", new_decls);
 	}
 
       if (b == level)
 	break;
       if ((b->kind == sk_try || b->kind == sk_catch) && !saw_eh)
@@ -2598,12 +2598,12 @@ check_goto (tree decl)
     }
 
   if (ent->in_try_scope || ent->in_catch_scope
       || ent->in_omp_scope || ent->bad_decls)
     {
-      pedwarn ("jump to label %q+D", decl);
-      pedwarn ("  from here");
+      pedwarn0 ("jump to label %q+D", decl);
+      pedwarn0 ("  from here");
       identified = true;
     }
 
   for (bad = ent->bad_decls; bad; bad = TREE_CHAIN (bad))
     {
@@ -2617,11 +2617,11 @@ check_goto (tree decl)
 	  saw_catch = true;
 	}
       else if (u > 1)
 	error ("  skips initialization of %q+#D", b);
       else
-	pedwarn ("  enters scope of non-POD %q+#D", b);
+	pedwarn0 ("  enters scope of non-POD %q+#D", b);
     }
 
   if (ent->in_try_scope)
     error ("  enters try block");
   else if (ent->in_catch_scope && !saw_catch)
@@ -2638,12 +2638,12 @@ check_goto (tree decl)
 	    break;
 	  if (b->kind == sk_omp)
 	    {
 	      if (!identified)
 		{
-		  pedwarn ("jump to label %q+D", decl);
-		  pedwarn ("  from here");
+		  pedwarn0 ("jump to label %q+D", decl);
+		  pedwarn0 ("  from here");
 		  identified = true;
 		}
 	      error ("  exits OpenMP structured block");
 	      break;
 	    }
@@ -2691,11 +2691,11 @@ define_label (location_t location, tree 
        p->kind != sk_function_parms;
        p = p->level_chain)
     p->more_cleanups_ok = 0;
 
   if (name == get_identifier ("wchar_t"))
-    pedwarn ("label named wchar_t");
+    pedwarn0 ("label named wchar_t");
 
   if (DECL_INITIAL (decl) != NULL_TREE)
     {
       error ("duplicate label %qD", decl);
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@@ -3765,12 +3765,12 @@ check_tag_decl (cp_decl_specifier_seq *d
   if (declspecs->multiple_types_p)
     error ("multiple types in one declaration");
   else if (declspecs->redefined_builtin_type)
     {
       if (!in_system_header)
-	pedwarn ("redeclaration of C++ built-in type %qT",
-		 declspecs->redefined_builtin_type);
+	pedwarn0 ("redeclaration of C++ built-in type %qT",
+		  declspecs->redefined_builtin_type);
       return NULL_TREE;
     }
 
   if (declspecs->type
       && TYPE_P (declspecs->type)
@@ -3779,11 +3779,11 @@ check_tag_decl (cp_decl_specifier_seq *d
 	  || TREE_CODE (declspecs->type) == ENUMERAL_TYPE))
     declared_type = declspecs->type;
   else if (declspecs->type == error_mark_node)
     error_p = true;
   if (declared_type == NULL_TREE && ! saw_friend && !error_p)
-    pedwarn ("declaration does not declare anything");
+    pedwarn0 ("declaration does not declare anything");
   /* Check for an anonymous union.  */
   else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
 	   && TYPE_ANONYMOUS_P (declared_type))
     {
       /* 7/3 In a simple-declaration, the optional init-declarator-list
@@ -3810,11 +3810,11 @@ check_tag_decl (cp_decl_specifier_seq *d
       /* Anonymous unions are objects, so they can have specifiers.  */;
       SET_ANON_AGGR_TYPE_P (declared_type);
 
       if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
 	  && !in_system_header)
-	pedwarn ("ISO C++ prohibits anonymous structs");
+	pedwarn0 ("ISO C++ prohibits anonymous structs");
     }
 
   else
     {
       if (declspecs->specs[(int)ds_inline]
@@ -4052,14 +4052,14 @@ start_decl (const cp_declarator *declara
 	  else
 	    {
 	      if (DECL_CONTEXT (field) != context)
 		{
 		  if (!same_type_p (DECL_CONTEXT (field), context))
-		    pedwarn ("ISO C++ does not permit %<%T::%D%> "
-			     "to be defined as %<%T::%D%>",
-			     DECL_CONTEXT (field), DECL_NAME (decl),
-			     context, DECL_NAME (decl));
+		    pedwarn0 ("ISO C++ does not permit %<%T::%D%> "
+			      "to be defined as %<%T::%D%>",
+			      DECL_CONTEXT (field), DECL_NAME (decl),
+			      context, DECL_NAME (decl));
 		  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
 		}
 	      if (processing_specialization
 		  && template_class_depth (context) == 0
 		  && CLASSTYPE_TEMPLATE_SPECIALIZATION (context))
@@ -4108,12 +4108,12 @@ start_decl (const cp_declarator *declara
 	  if (!initialized && processing_specialization)
 	    DECL_EXTERNAL (decl) = 1;
 	}
 
       if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
-	pedwarn ("declaration of %q#D outside of class is not definition",
-		 decl);
+	pedwarn0 ("declaration of %q#D outside of class is not definition",
+		  decl);
     }
 
   was_public = TREE_PUBLIC (decl);
 
   /* Enter this declaration into the symbol table.  */
@@ -6317,12 +6317,12 @@ check_class_member_definition_namespace 
      [class.static.data]
 
      The definition for a static data member shall appear in a
      namespace scope enclosing the member's class definition.  */
   if (!is_ancestor (current_namespace, DECL_CONTEXT (decl)))
-    pedwarn ("definition of %qD is not in namespace enclosing %qT",
-	     decl, DECL_CONTEXT (decl));
+    pedwarn0 ("definition of %qD is not in namespace enclosing %qT",
+	      decl, DECL_CONTEXT (decl));
 }
 
 /* Build a PARM_DECL for the "this" parameter.  TYPE is the
    METHOD_TYPE for a non-static member function; QUALS are the
    cv-qualifiers that apply to the function.  */
@@ -6551,20 +6551,20 @@ grokfndecl (tree ctype,
 	    {
 	      if (DECL_EXTERN_C_P (decl))
 		/* Allow this; it's pretty common in C.  */;
 	      else
 		{
-		  pedwarn ("non-local function %q#D uses anonymous type",
-			      decl);
+		  pedwarn0 ("non-local function %q#D uses anonymous type",
+			    decl);
 		  if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
-		    pedwarn ("%q+#D does not refer to the unqualified "
-			     "type, so it is not used for linkage",
-			     TYPE_NAME (t));
+		    pedwarn0 ("%q+#D does not refer to the unqualified "
+			      "type, so it is not used for linkage",
+			      TYPE_NAME (t));
 		}
 	    }
 	  else
-	    pedwarn ("non-local function %q#D uses local type %qT", decl, t);
+	    pedwarn0 ("non-local function %q#D uses local type %qT", decl, t);
 	}
     }
 
   TREE_PUBLIC (decl) = publicp;
   if (! publicp)
@@ -6975,12 +6975,12 @@ check_static_variable_definition (tree d
     }
   else if (!CP_TYPE_CONST_P (type))
     error ("ISO C++ forbids in-class initialization of non-const "
 	   "static member %qD",
 	   decl);
-  else if (pedantic && !INTEGRAL_TYPE_P (type))
-    pedwarn ("ISO C++ forbids initialization of member constant "
+  else if (!INTEGRAL_TYPE_P (type))
+    pedwarn (OPT_pedantic, "ISO C++ forbids initialization of member constant "
 	     "%qD of non-integral type %qT", decl, type);
 
   return 0;
 }
 
@@ -7053,16 +7053,16 @@ compute_array_index_type (tree name, tre
 	    error ("size of array is negative");
 	  size = integer_one_node;
 	}
       /* As an extension we allow zero-sized arrays.  We always allow
 	 them in system headers because glibc uses them.  */
-      else if (integer_zerop (size) && pedantic && !in_system_header)
+      else if (integer_zerop (size) && !in_system_header)
 	{
 	  if (name)
-	    pedwarn ("ISO C++ forbids zero-size array %qD", name);
+	    pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
 	  else
-	    pedwarn ("ISO C++ forbids zero-size array");
+	    pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array");
 	}
     }
   else if (TREE_CONSTANT (size))
     {
       /* `(int) &fn' is not a valid array bound.  */
@@ -7074,13 +7074,13 @@ compute_array_index_type (tree name, tre
       size = integer_one_node;
     }
   else if (pedantic && warn_vla != 0)
     {
       if (name)
-	pedwarn ("ISO C++ forbids variable length array %qD", name);
+	pedwarn (OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
       else
-	pedwarn ("ISO C++ forbids variable length array");
+	pedwarn (OPT_Wvla, "ISO C++ forbids variable length array");
     }
   else if (warn_vla > 0)
     {
       if (name)
 	warning (OPT_Wvla, 
@@ -7705,11 +7705,12 @@ grokdeclarator (const cp_declarator *dec
       if (type_was_error_mark_node)
 	/* We've already issued an error, don't complain more.  */;
       else if (in_system_header || flag_ms_extensions)
 	/* Allow it, sigh.  */;
       else if (pedantic || ! is_main)
-	pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
+	pedwarn (!is_main ? 0 : OPT_pedantic, 
+		 "ISO C++ forbids declaration of %qs with no type", name);
       else
 	warning (OPT_Wreturn_type,
                  "ISO C++ forbids declaration of %qs with no type", name);
 
       type = integer_type_node;
@@ -7760,11 +7761,12 @@ grokdeclarator (const cp_declarator *dec
       else
 	{
 	  ok = 1;
 	  if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
 	    {
-	      pedwarn ("long, short, signed or unsigned used invalidly for %qs",
+	      pedwarn (OPT_pedantic, 
+		       "long, short, signed or unsigned used invalidly for %qs",
 		       name);
 	      if (flag_pedantic_errors)
 		ok = 0;
 	    }
 	}
@@ -7865,11 +7867,12 @@ grokdeclarator (const cp_declarator *dec
 	 a function type), but DR 295 makes the code well-formed by
 	 dropping the extra qualifiers. */
       if (pedantic)
 	{
 	  tree bad_type = build_qualified_type (type, type_quals);
-	  pedwarn ("ignoring %qV qualifiers added to function type %qT",
+	  pedwarn (OPT_pedantic, 
+		   "ignoring %qV qualifiers added to function type %qT",
 		   bad_type, type);
 	}
       type_quals = TYPE_UNQUALIFIED;
     }
   type_quals |= cp_type_quals (type);
@@ -8155,11 +8158,11 @@ grokdeclarator (const cp_declarator *dec
 		    /* It's a constructor.  */
 		    if (explicitp == 1)
 		      explicitp = 2;
 		    if (virtualp)
 		      {
-			pedwarn ("constructors cannot be declared virtual");
+			pedwarn0 ("constructors cannot be declared virtual");
 			virtualp = 0;
 		      }
 		    if (decl_context == FIELD
 			&& sfk != sfk_constructor)
 		      return error_mark_node;
@@ -8378,15 +8381,15 @@ grokdeclarator (const cp_declarator *dec
 
       if (ctype == current_class_type)
 	{
 	  if (friendp)
 	    {
-	      pedwarn ("member functions are implicitly friends of their class");
+	      pedwarn0 ("member functions are implicitly friends of their class");
 	      friendp = 0;
 	    }
 	  else
-	    pedwarn ("extra qualification %<%T::%> on member %qs",
+	    pedwarn0 ("extra qualification %<%T::%> on member %qs",
 		     ctype, name);
 	}
       else if (/* If the qualifying type is already complete, then we
 		  can skip the following checks.  */
 	       !COMPLETE_TYPE_P (ctype)
@@ -8567,13 +8570,13 @@ grokdeclarator (const cp_declarator *dec
 	       be copies of this TYPE_DECL generated in those
 	       clones.  */
 	    DECL_ABSTRACT (decl) = 1;
 	}
       else if (constructor_name_p (unqualified_id, current_class_type))
-	pedwarn ("ISO C++ forbids nested type %qD with same name "
-		 "as enclosing class",
-		 unqualified_id);
+	pedwarn0 ("ISO C++ forbids nested type %qD with same name "
+		  "as enclosing class",
+		  unqualified_id);
 
       /* If the user declares "typedef struct {...} foo" then the
 	 struct will have an anonymous name.  Fill that name in now.
 	 Nothing can refer to it, so nothing needs know about the name
 	 change.  */
@@ -8692,19 +8695,18 @@ grokdeclarator (const cp_declarator *dec
 
 	  if (!current_aggr)
 	    {
 	      /* Don't allow friend declaration without a class-key.  */
 	      if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
-		pedwarn ("template parameters cannot be friends");
+		pedwarn0 ("template parameters cannot be friends");
 	      else if (TREE_CODE (type) == TYPENAME_TYPE)
-		pedwarn ("friend declaration requires class-key, "
-			 "i.e. %<friend class %T::%D%>",
-			 TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
+		pedwarn0 ("friend declaration requires class-key, "
+			  "i.e. %<friend class %T::%D%>",
+			  TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
 	      else
-		pedwarn ("friend declaration requires class-key, "
-			 "i.e. %<friend %#T%>",
-			 type);
+		pedwarn0 ("friend declaration requires class-key, "
+			  "i.e. %<friend %#T%>", type);
 	    }
 
 	  /* Only try to do this stuff if we didn't already give up.  */
 	  if (type != integer_type_node)
 	    {
@@ -9026,13 +9028,13 @@ grokdeclarator (const cp_declarator *dec
 
 		       This used to be relatively common practice, but
 		       the rest of the compiler does not correctly
 		       handle the initialization unless the member is
 		       static so we make it static below.  */
-		    pedwarn ("ISO C++ forbids initialization of member %qD",
-			     unqualified_id);
-		    pedwarn ("making %qD static", unqualified_id);
+		    pedwarn0 ("ISO C++ forbids initialization of member %qD",
+			      unqualified_id);
+		    pedwarn0 ("making %qD static", unqualified_id);
 		    staticp = 1;
 		  }
 
 		if (uses_template_parms (type))
 		  /* We'll check at instantiation time.  */
@@ -9108,14 +9110,16 @@ grokdeclarator (const cp_declarator *dec
 	    && (storage_class == sc_static
 		|| declspecs->specs[(int)ds_inline])
 	    && pedantic)
 	  {
 	    if (storage_class == sc_static)
-	      pedwarn ("%<static%> specified invalid for function %qs "
+	      pedwarn (OPT_pedantic, 
+		       "%<static%> specified invalid for function %qs "
 		       "declared out of global scope", name);
 	    else
-	      pedwarn ("%<inline%> specifier invalid for function %qs "
+	      pedwarn (OPT_pedantic, 
+		       "%<inline%> specifier invalid for function %qs "
 		       "declared out of global scope", name);
 	  }
 
 	if (ctype == NULL_TREE)
 	  {
@@ -9150,12 +9154,12 @@ grokdeclarator (const cp_declarator *dec
 
 	    /* Don't allow a static member function in a class, and forbid
 	       declaring main to be static.  */
 	    if (TREE_CODE (type) == METHOD_TYPE)
 	      {
-		pedwarn ("cannot declare member function %qD to have "
-			 "static linkage", decl);
+		pedwarn0 ("cannot declare member function %qD to have "
+			  "static linkage", decl);
 		invalid_static = 1;
 	      }
 	    else if (current_function_decl)
 	      {
 		/* FIXME need arm citation */
@@ -9187,25 +9191,25 @@ grokdeclarator (const cp_declarator *dec
 	if (ctype)
 	  {
 	    DECL_CONTEXT (decl) = ctype;
 	    if (staticp == 1)
 	      {
-		pedwarn ("%<static%> may not be used when defining "
-			 "(as opposed to declaring) a static data member");
+		pedwarn0 ("%<static%> may not be used when defining "
+			  "(as opposed to declaring) a static data member");
 		staticp = 0;
 		storage_class = sc_none;
 	      }
 	    if (storage_class == sc_register && TREE_STATIC (decl))
 	      {
 		error ("static member %qD declared %<register%>", decl);
 		storage_class = sc_none;
 	      }
 	    if (storage_class == sc_extern && pedantic)
 	      {
-		pedwarn ("cannot explicitly declare member %q#D to have "
-			 "extern linkage",
-			 decl);
+		pedwarn (OPT_pedantic, 
+			 "cannot explicitly declare member %q#D to have "
+			 "extern linkage", decl);
 		storage_class = sc_none;
 	      }
 	  }
       }
 
@@ -10073,12 +10077,12 @@ grok_op_properties (tree decl, bool comp
 	  {
 	    TREE_PURPOSE (argtypes) = NULL_TREE;
 	    if (operator_code == POSTINCREMENT_EXPR
 		|| operator_code == POSTDECREMENT_EXPR)
 	      {
-		if (pedantic)
-		  pedwarn ("%qD cannot have default arguments", decl);
+		pedwarn (OPT_pedantic, "%qD cannot have default arguments", 
+			 decl);
 	      }
 	    else
 	      {
 		error ("%qD cannot have default arguments", decl);
 		return false;
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 136559)
+++ gcc/cp/call.c	(working copy)
@@ -3291,12 +3291,13 @@ build_conditional_expr (tree arg1, tree 
      omitted.  (So that `a ? : c' is roughly equivalent to `a ? a :
      c'.)  If the second operand is omitted, make sure it is
      calculated only once.  */
   if (!arg2)
     {
-      if (pedantic && (complain & tf_error))
-	pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
+      if (complain & tf_error)
+	pedwarn (OPT_pedantic, 
+		 "ISO C++ forbids omitting the middle term of a ?: expression");
 
       /* Make sure that lvalues remain lvalues.  See g++.oliva/ext1.C.  */
       if (real_lvalue_p (arg1))
 	arg2 = arg1 = stabilize_reference (arg1);
       else
@@ -6561,11 +6562,11 @@ tweak:
 	winner = -1, w = cand2, l = cand1;
       if (winner)
 	{
 	  if (warn)
 	    {
-	      pedwarn ("\
+	      pedwarn0 ("\
 ISO C++ says that these are ambiguous, even \
 though the worst conversion for the first is better than \
 the worst conversion for the second:");
 	      print_z_candidate (_("candidate 1:"), w);
 	      print_z_candidate (_("candidate 2:"), l);
Index: gcc/cp/except.c
===================================================================
--- gcc/cp/except.c	(revision 136559)
+++ gcc/cp/except.c	(working copy)
@@ -1013,11 +1013,11 @@ check_handlers (tree handlers)
 
 	/* No more handlers; nothing to shadow.  */
 	if (tsi_end_p (i))
 	  break;
 	if (TREE_TYPE (handler) == NULL_TREE)
-	  pedwarn ("%H%<...%> handler must be the last handler for"
-		   " its try block", EXPR_LOCUS (handler));
+	  pedwarn0 ("%H%<...%> handler must be the last handler for"
+		    " its try block", EXPR_LOCUS (handler));
 	else
 	  check_handlers_1 (handler, i);
       }
 }
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 136559)
+++ gcc/cp/error.c	(working copy)
@@ -2680,7 +2680,7 @@ maybe_warn_variadic_templates (void)
 {
   if ((cxx_dialect == cxx98) && !in_system_header)
     /* We really want to suppress this warning in system headers,
        because libstdc++ uses variadic templates even when we aren't
        in C++0x mode. */
-    pedwarn ("ISO C++ does not include variadic templates");
+    pedwarn0 ("ISO C++ does not include variadic templates");
 }
Index: gcc/cp/friend.c
===================================================================
--- gcc/cp/friend.c	(revision 136559)
+++ gcc/cp/friend.c	(working copy)
@@ -251,12 +251,11 @@ make_friend_class (tree type, tree frien
 	}
     }
   else if (same_type_p (type, friend_type))
     {
       if (complain)
-	pedwarn ("class %qT is implicitly friends with itself",
-		 type);
+	pedwarn0 ("class %qT is implicitly friends with itself", type);
       return;
     }
 
   /* [temp.friend]
 
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 136559)
+++ gcc/cp/typeck2.c	(working copy)
@@ -342,11 +342,11 @@ cxx_incomplete_type_diagnostic (const_tr
   void (*p_msg) (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1,2);
 
   if (diag_type == 1)
     p_msg = warning0;
   else if (diag_type == 2)
-    p_msg = pedwarn;
+    p_msg = pedwarn0;
   else
     p_msg = error;
 
   /* Avoid duplicate error message.  */
   if (TREE_CODE (type) == ERROR_MARK)
@@ -692,11 +692,11 @@ digest_init (tree type, tree init)
 	      /* In C it is ok to subtract 1 from the length of the string
 		 because it's ok to ignore the terminating null char that is
 		 counted in the length of the constant, but in C++ this would
 		 be invalid.  */
 	      if (size < TREE_STRING_LENGTH (init))
-		pedwarn ("initializer-string for array of chars is too long");
+		pedwarn0 ("initializer-string for array of chars is too long");
 	    }
 	  return init;
 	}
     }
 
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 136559)
+++ gcc/cp/pt.c	(working copy)
@@ -708,12 +708,12 @@ check_specialization_namespace (tree tmp
   if (is_associated_namespace (current_namespace, tpl_ns))
     /* Same or super-using namespace.  */
     return true;
   else
     {
-      pedwarn ("specialization of %qD in different namespace", tmpl);
-      pedwarn ("  from definition of %q+#D", tmpl);
+      pedwarn0 ("specialization of %qD in different namespace", tmpl);
+      pedwarn0 ("  from definition of %q+#D", tmpl);
       return false;
     }
 }
 
 /* SPEC is an explicit instantiation.  Check that it is valid to
@@ -726,13 +726,13 @@ check_explicit_instantiation_namespace (
 
   /* DR 275: An explicit instantiation shall appear in an enclosing
      namespace of its template.  */
   ns = decl_namespace_context (spec);
   if (!is_ancestor (current_namespace, ns))
-    pedwarn ("explicit instantiation of %qD in namespace %qD "
-	     "(which does not enclose namespace %qD)",
-	     spec, current_namespace, ns);
+    pedwarn0 ("explicit instantiation of %qD in namespace %qD "
+	      "(which does not enclose namespace %qD)",
+	      spec, current_namespace, ns);
 }
 
 /* The TYPE is being declared.  If it is a template type, that means it
    is a partial specialization.  Do appropriate error-checking.  */
 
@@ -805,13 +805,13 @@ maybe_process_partial_specialization (tr
 	  tree t;
 
 	  if (current_namespace
 	      != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
 	    {
-	      pedwarn ("specializing %q#T in different namespace", type);
-	      pedwarn ("  from definition of %q+#D",
-		       CLASSTYPE_TI_TEMPLATE (type));
+	      pedwarn0 ("specializing %q#T in different namespace", type);
+	      pedwarn0 ("  from definition of %q+#D",
+			CLASSTYPE_TI_TEMPLATE (type));
 	    }
 
 	  /* Check for invalid specialization after instantiation:
 
 	       template <> template <> class C<int>::D<int>;
@@ -2000,11 +2000,11 @@ check_explicit_specialization (tree decl
     {
       tree t = TYPE_ARG_TYPES (TREE_TYPE (decl));
       for (; t; t = TREE_CHAIN (t))
 	if (TREE_PURPOSE (t))
 	  {
-	    pedwarn
+	    pedwarn0
 	      ("default argument specified in explicit specialization");
 	    break;
 	  }
     }
 
@@ -4936,12 +4936,12 @@ convert_template_argument (tree parm,
   is_type = TYPE_P (arg) || is_tmpl_type;
 
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      pedwarn ("to refer to a type member of a template parameter, "
-	       "use %<typename %E%>", orig_arg);
+      pedwarn0 ("to refer to a type member of a template parameter, "
+		"use %<typename %E%>", orig_arg);
 
       orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
 				     TREE_OPERAND (arg, 1),
 				     typename_type,
 				     complain & tf_error);
@@ -14561,11 +14561,11 @@ do_decl_instantiation (tree decl, tree s
 
 	 We check DECL_NOT_REALLY_EXTERN so as not to complain when
 	 the first instantiation was `extern' and the second is not,
 	 and EXTERN_P for the opposite case.  */
       if (DECL_NOT_REALLY_EXTERN (result) && !extern_p)
-	pedwarn ("duplicate explicit instantiation of %q#D", result);
+	pedwarn0 ("duplicate explicit instantiation of %q#D", result);
       /* If an "extern" explicit instantiation follows an ordinary
 	 explicit instantiation, the template is instantiated.  */
       if (extern_p)
 	return;
     }
@@ -14574,21 +14574,21 @@ do_decl_instantiation (tree decl, tree s
       error ("no matching template for %qD found", result);
       return;
     }
   else if (!DECL_TEMPLATE_INFO (result))
     {
-      pedwarn ("explicit instantiation of non-template %q#D", result);
+      pedwarn0 ("explicit instantiation of non-template %q#D", result);
       return;
     }
 
   if (storage == NULL_TREE)
     ;
   else if (storage == ridpointers[(int) RID_EXTERN])
     {
-      if (pedantic && !in_system_header)
-	pedwarn ("ISO C++ forbids the use of %<extern%> on explicit "
-		 "instantiations");
+      if (!in_system_header)
+	pedwarn (OPT_pedantic, "ISO C++ forbids "
+		 "the use of %<extern%> on explicit instantiations");
       extern_p = 1;
     }
   else
     error ("storage class %qD applied to template instantiation", storage);
 
@@ -14669,13 +14669,14 @@ do_type_instantiation (tree t, tree stor
       return;
     }
 
   if (storage != NULL_TREE)
     {
-      if (pedantic && !in_system_header)
-	pedwarn("ISO C++ forbids the use of %qE on explicit instantiations",
-		storage);
+      if (!in_system_header)
+	pedwarn (OPT_pedantic, 
+		 "ISO C++ forbids the use of %qE on explicit instantiations",
+		 storage);
 
       if (storage == ridpointers[(int) RID_INLINE])
 	nomem_p = 1;
       else if (storage == ridpointers[(int) RID_EXTERN])
 	extern_p = 1;
@@ -14715,11 +14716,11 @@ do_type_instantiation (tree t, tree stor
 	 These cases are OK.  */
       previous_instantiation_extern_p = CLASSTYPE_INTERFACE_ONLY (t);
 
       if (!previous_instantiation_extern_p && !extern_p
 	  && (complain & tf_error))
-	pedwarn ("duplicate explicit instantiation of %q#T", t);
+	pedwarn0 ("duplicate explicit instantiation of %q#T", t);
 
       /* If we've already instantiated the template, just return now.  */
       if (!CLASSTYPE_INTERFACE_ONLY (t))
 	return;
     }
@@ -15162,11 +15163,11 @@ instantiate_decl (tree d, int defer_ok,
 	   The definition of a non-exported function template, a
 	   non-exported member function template, or a non-exported
 	   member function or static data member of a class template
 	   shall be present in every translation unit in which it is
 	   explicitly instantiated.  */
-	pedwarn
+	pedwarn0
 	  ("explicit instantiation of %qD but no definition available", d);
 
       /* ??? Historically, we have instantiated inline functions, even
 	 when marked as "extern template".  */
       if (!(external_p && TREE_CODE (d) == VAR_DECL))
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 136559)
+++ gcc/cp/semantics.c	(working copy)
@@ -2168,11 +2168,12 @@ finish_translation_unit (void)
 tree
 finish_template_type_parm (tree aggr, tree identifier)
 {
   if (aggr != class_type_node)
     {
-      pedwarn ("template type parameters must use the keyword %<class%> or %<typename%>");
+      pedwarn0 ("template type parameters must use the keyword "
+		"%<class%> or %<typename%>");
       aggr = class_type_node;
     }
 
   return build_tree_list (aggr, identifier);
 }
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 136559)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -721,14 +721,14 @@ pushdecl_maybe_friend (tree x, bool is_f
 		    || DECL_FUNCTION_TEMPLATE_P (x))
 		   && is_overloaded_fn (t))
 	    /* Don't do anything just yet.  */;
 	  else if (t == wchar_decl_node)
 	    {
-	      if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
-		pedwarn ("redeclaration of %<wchar_t%> as %qT",
+	      if (! DECL_IN_SYSTEM_HEADER (x))
+		pedwarn (OPT_pedantic, "redeclaration of %<wchar_t%> as %qT",
 			 TREE_TYPE (x));
-
+	      
 	      /* Throw away the redeclaration.  */
 	      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 	    }
 	  else
 	    {
@@ -844,12 +844,12 @@ pushdecl_maybe_friend (tree x, bool is_f
 	      && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
 	      /* If different sort of thing, we already gave an error.  */
 	      && TREE_CODE (decl) == TREE_CODE (x)
 	      && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
 	    {
-	      pedwarn ("type mismatch with previous external decl of %q#D", x);
-	      pedwarn ("previous external decl of %q+#D", decl);
+	      pedwarn0 ("type mismatch with previous external decl of %q#D", x);
+	      pedwarn0 ("previous external decl of %q+#D", decl);
 	    }
 	}
 
       if (TREE_CODE (x) == FUNCTION_DECL
 	  && is_friend
@@ -1171,13 +1171,13 @@ check_for_out_of_scope_variable (tree de
 	     "it has a destructor", decl);
       return error_mark_node;
     }
   else
     {
-      pedwarn ("name lookup of %qD changed for new ISO %<for%> scoping",
-	       DECL_NAME (decl));
-      pedwarn ("  using obsolete binding at %q+D", decl);
+      pedwarn0 ("name lookup of %qD changed for new ISO %<for%> scoping",
+		DECL_NAME (decl));
+      pedwarn0 ("  using obsolete binding at %q+D", decl);
     }
 
   return decl;
 }
 
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 136559)
+++ gcc/cp/decl2.c	(working copy)
@@ -714,12 +714,12 @@ finish_static_data_member_decl (tree dec
 
   if (! processing_template_decl)
     VEC_safe_push (tree, gc, pending_statics, decl);
 
   if (LOCAL_CLASS_P (current_class_type))
-    pedwarn ("local class %q#T shall not have static data member %q#D",
-	     current_class_type, decl);
+    pedwarn0 ("local class %q#T shall not have static data member %q#D",
+	      current_class_type, decl);
 
   /* Static consts need not be initialized in the class definition.  */
   if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
     {
       static int explained = 0;
@@ -1226,19 +1226,19 @@ build_anon_union_vars (tree type, tree o
 
       if (DECL_ARTIFICIAL (field))
 	continue;
       if (TREE_CODE (field) != FIELD_DECL)
 	{
-	  pedwarn ("%q+#D invalid; an anonymous union can only "
-		   "have non-static data members", field);
+	  pedwarn0 ("%q+#D invalid; an anonymous union can only "
+		    "have non-static data members", field);
 	  continue;
 	}
 
       if (TREE_PRIVATE (field))
-	pedwarn ("private member %q+#D in anonymous union", field);
+	pedwarn0 ("private member %q+#D in anonymous union", field);
       else if (TREE_PROTECTED (field))
-	pedwarn ("protected member %q+#D in anonymous union", field);
+	pedwarn0 ("protected member %q+#D in anonymous union", field);
 
       if (processing_template_decl)
 	ref = build_min_nt (COMPONENT_REF, object,
 			    DECL_NAME (field), NULL_TREE);
       else
@@ -1369,12 +1369,12 @@ coerce_new_type (tree type)
     }
   else
     e = 2;
 
   if (e == 2)
-    pedwarn ("%<operator new%> takes type %<size_t%> (%qT) "
-	     "as first parameter", size_type_node);
+    pedwarn0 ("%<operator new%> takes type %<size_t%> (%qT) "
+	      "as first parameter", size_type_node);
 
   switch (e)
   {
     case 2:
       args = tree_cons (NULL_TREE, size_type_node, args);
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 136559)
+++ gcc/cp/parser.c	(working copy)
@@ -2153,11 +2153,12 @@ cp_parser_check_decl_spec (cp_decl_speci
 	{
 	  if (count > 2)
 	    error ("%<long long long%> is too long for GCC");
 	  else if (pedantic && !in_system_header && warn_long_long
                    && cxx_dialect == cxx98)
-	    pedwarn ("ISO C++ 1998 does not support %<long long%>");
+	    pedwarn (OPT_Wlong_long, 
+		     "ISO C++ 1998 does not support %<long long%>");
 	}
       else if (count > 1)
 	{
 	  static const char *const decl_spec_names[] = {
 	    "signed",
@@ -3193,12 +3194,12 @@ cp_parser_primary_expression (cp_parser 
 	   a GNU statement-expression.  */
 	if (cp_parser_allow_gnu_extensions_p (parser)
 	    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 	  {
 	    /* Statement-expressions are not allowed by the standard.  */
-	    if (pedantic)
-	      pedwarn ("ISO C++ forbids braced-groups within expressions");
+	    pedwarn (OPT_pedantic, 
+		     "ISO C++ forbids braced-groups within expressions");
 
 	    /* And they're not allowed outside of a function-body; you
 	       cannot, for example, write:
 
 		 int i = ({ int j = 3; j + 1; });
@@ -4109,14 +4110,14 @@ cp_parser_nested_name_specifier_opt (cp_
 		    && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (new_scope)))
 		   || CLASSTYPE_IS_TEMPLATE (new_scope)))
 	  && !(TREE_CODE (new_scope) == TYPENAME_TYPE
 	       && (TREE_CODE (TYPENAME_TYPE_FULLNAME (new_scope))
 		   == TEMPLATE_ID_EXPR)))
-	pedwarn (TYPE_P (new_scope)
-		 ? "%qT is not a template"
-		 : "%qD is not a template",
-		 new_scope);
+	pedwarn0 (TYPE_P (new_scope)
+		  ? "%qT is not a template"
+		  : "%qD is not a template",
+		  new_scope);
       /* If it is a class scope, try to complete it; we are about to
 	 be looking up names inside the class.  */
       if (TYPE_P (new_scope)
 	  /* Since checking types for dependency can be expensive,
 	     avoid doing it if the type is already complete.  */
@@ -4513,12 +4514,11 @@ cp_parser_postfix_expression (cp_parser 
 	       compound-literal expression.  */
 	    if (cp_parser_parse_definitely (parser))
 	      {
 		/* Warn the user that a compound literal is not
 		   allowed in standard C++.  */
-		if (pedantic)
-		  pedwarn ("ISO C++ forbids compound-literals");
+		pedwarn (OPT_pedantic, "ISO C++ forbids compound-literals");
 		/* For simplicity, we disallow compound literals in
 		   constant-expressions.  We could
 		   allow compound literals of integer type, whose
 		   initializer was a constant, in constant
 		   expressions.  Permitting that usage, as a further
@@ -7513,12 +7513,11 @@ cp_parser_jump_statement (cp_parser* par
     case RID_GOTO:
       /* Create the goto-statement.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
 	{
 	  /* Issue a warning about this use of a GNU extension.  */
-	  if (pedantic)
-	    pedwarn ("ISO C++ forbids computed gotos");
+	  pedwarn (OPT_pedantic, "ISO C++ forbids computed gotos");
 	  /* Consume the '*' token.  */
 	  cp_lexer_consume_token (parser->lexer);
 	  /* Parse the dependent expression.  */
 	  finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false));
 	}
@@ -7653,12 +7652,12 @@ cp_parser_declaration_seq_opt (cp_parser
       if (token->type == CPP_SEMICOLON)
 	{
 	  /* A declaration consisting of a single semicolon is
 	     invalid.  Allow it unless we're being pedantic.  */
 	  cp_lexer_consume_token (parser->lexer);
-	  if (pedantic && !in_system_header)
-	    pedwarn ("extra %<;%>");
+	  if (!in_system_header)
+	    pedwarn (OPT_pedantic, "extra %<;%>");
 	  continue;
 	}
 
       /* If we're entering or exiting a region that's implicitly
 	 extern "C", modify the lang context appropriately.  */
@@ -8926,11 +8925,11 @@ cp_parser_mem_initializer (cp_parser* pa
   tree member;
 
   /* Find out what is being initialized.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
     {
-      pedwarn ("anachronistic old-style base class initializer");
+      pedwarn0 ("anachronistic old-style base class initializer");
       mem_initializer_id = NULL_TREE;
     }
   else
     mem_initializer_id = cp_parser_mem_initializer_id (parser);
   member = expand_member_init (mem_initializer_id);
@@ -11184,11 +11183,11 @@ cp_parser_elaborated_type_specifier (cp_
       cp_lexer_consume_token (parser->lexer);
       /* Remember that it's a `typename' type.  */
       tag_type = typename_type;
       /* The `typename' keyword is only allowed in templates.  */
       if (!processing_template_decl)
-	pedwarn ("using %<typename%> outside of template");
+	pedwarn0 ("using %<typename%> outside of template");
     }
   /* Otherwise it must be a class-key.  */
   else
     {
       tag_type = cp_parser_class_key (parser);
@@ -11557,12 +11556,12 @@ cp_parser_enumerator_list (cp_parser* pa
       /* Otherwise, consume the `,' and keep going.  */
       cp_lexer_consume_token (parser->lexer);
       /* If the next token is a `}', there is a trailing comma.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
 	{
-	  if (pedantic && !in_system_header)
-	    pedwarn ("comma at end of enumerator list");
+	  if (!in_system_header)
+	    pedwarn (OPT_pedantic, "comma at end of enumerator list");
 	  break;
 	}
     }
 }
 
@@ -14127,12 +14126,12 @@ cp_parser_initializer_list (cp_parser* p
       if (cp_parser_allow_gnu_extensions_p (parser)
 	  && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
 	  && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
 	{
 	  /* Warn the user that they are using an extension.  */
-	  if (pedantic)
-	    pedwarn ("ISO C++ does not allow designated initializers");
+	  pedwarn (OPT_pedantic, 
+		   "ISO C++ does not allow designated initializers");
 	  /* Consume the identifier.  */
 	  identifier = cp_lexer_consume_token (parser->lexer)->u.value;
 	  /* Consume the `:'.  */
 	  cp_lexer_consume_token (parser->lexer);
 	}
@@ -14756,11 +14755,11 @@ cp_parser_class_head (cp_parser* parser,
 	 definition of a ... nested class outside of its class
 	 ... [or] a the definition or explicit instantiation of a
 	 class member of a namespace outside of its namespace.  */
       if (scope == nested_name_specifier)
 	{
-	  pedwarn ("extra qualification ignored");
+	  pedwarn0 ("extra qualification ignored");
 	  nested_name_specifier = NULL_TREE;
 	  num_templates = 0;
 	}
     }
   /* An explicit-specialization must be preceded by "template <>".  If
@@ -15115,12 +15114,12 @@ cp_parser_member_declaration (cp_parser*
 	 Each member-declaration shall declare at least one member
 	 name of the class.  */
       if (!decl_specifiers.any_specifiers_p)
 	{
 	  cp_token *token = cp_lexer_peek_token (parser->lexer);
-	  if (pedantic && !token->in_system_header)
-	    pedwarn ("%Hextra %<;%>", &token->location);
+	  if (!token->in_system_header)
+	    pedwarn (OPT_pedantic, "%Hextra %<;%>", &token->location);
 	}
       else
 	{
 	  tree type;
 
@@ -18114,14 +18113,14 @@ cp_parser_token_is_class_key (cp_token* 
 
 static void
 cp_parser_check_class_key (enum tag_types class_key, tree type)
 {
   if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
-    pedwarn ("%qs tag used in naming %q#T",
-	    class_key == union_type ? "union"
-	     : class_key == record_type ? "struct" : "class",
-	     type);
+    pedwarn0 ("%qs tag used in naming %q#T",
+	      class_key == union_type ? "union"
+	      : class_key == record_type ? "struct" : "class",
+	      type);
 }
 
 /* Issue an error message if DECL is redeclared with different
    access than its original declaration [class.access.spec/3].
    This applies to nested classes and nested class templates.
Index: gcc/c-tree.h
===================================================================
--- gcc/c-tree.h	(revision 136559)
+++ gcc/c-tree.h	(working copy)
@@ -561,11 +561,11 @@ extern tree build_conditional_expr (tree
 extern tree build_compound_expr (tree, tree);
 extern tree c_cast_expr (struct c_type_name *, tree);
 extern tree build_c_cast (tree, tree);
 extern void store_init_value (tree, tree);
 extern void error_init (const char *);
-extern void pedwarn_init (const char *);
+extern void pedwarn_init (int opt, const char *);
 extern void maybe_warn_string_init (tree, struct c_expr);
 extern void start_init (tree, tree, int);
 extern void finish_init (void);
 extern void really_start_incremental_init (tree);
 extern void push_init_level (int);
@@ -638,9 +638,9 @@ extern void c_write_global_declarations 
 #define ATTRIBUTE_GCC_CDIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m ,n))) ATTRIBUTE_NONNULL(m)
 #else
 #define ATTRIBUTE_GCC_CDIAG(m, n) ATTRIBUTE_NONNULL(m)
 #endif
 
-extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
-extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
+extern void pedwarn_c90 (int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(2,3);
+extern void pedwarn_c99 (int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(2,3);
 
 #endif /* ! GCC_C_TREE_H */
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 136559)
+++ gcc/c-decl.c	(working copy)
@@ -784,11 +784,11 @@ pop_scope (void)
 	     same translation unit."  */
 	  else if (DECL_DECLARED_INLINE_P (p)
 		   && TREE_PUBLIC (p)
 		   && !DECL_INITIAL (p)
 		   && !flag_gnu89_inline)
-	    pedwarn ("inline function %q+D declared but never defined", p);
+	    pedwarn0 ("inline function %q+D declared but never defined", p);
 
 	  goto common_symbol;
 
 	case VAR_DECL:
 	  /* Warnings for unused variables.  */
@@ -1221,11 +1221,11 @@ diagnose_mismatched_decls (tree newdecl,
       else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl)
 	       && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node
 	       && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
 	       && C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
 	{
-	  pedwarn ("conflicting types for %q+D", newdecl);
+	  pedwarn0 ("conflicting types for %q+D", newdecl);
 	  /* Make sure we keep void as the return type.  */
 	  TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
 	  C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
 	  pedwarned = true;
 	}
@@ -1234,11 +1234,11 @@ diagnose_mismatched_decls (tree newdecl,
       else if (TREE_CODE (newdecl) == FUNCTION_DECL
 	       && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == void_type_node
 	       && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
 	       && C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
 	{
-	  pedwarn ("conflicting types for %q+D", newdecl);
+	  pedwarn0 ("conflicting types for %q+D", newdecl);
 	  /* Make sure we keep void as the return type.  */
 	  TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
 	  pedwarned = true;
 	}
       else
@@ -1583,11 +1583,11 @@ diagnose_mismatched_decls (tree newdecl,
       warned = true;
     }
 
   /* Report location of previous decl/defn in a consistent manner.  */
   if (warned || pedwarned)
-    locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
+    locate_old_decl (olddecl, pedwarned ? pedwarn0 : warning0);
 
 #undef DECL_EXTERN_INLINE
 
   return retval;
 }
@@ -2336,11 +2336,12 @@ static void
 implicit_decl_warning (tree id, tree olddecl)
 {
   if (warn_implicit_function_declaration)
     {
       if (flag_isoc99)
-	pedwarn (G_("implicit declaration of function %qE"), id);
+	pedwarn (OPT_Wimplicit_function_declaration, 
+		 G_("implicit declaration of function %qE"), id);
       else 
 	warning (OPT_Wimplicit_function_declaration, 
 		 G_("implicit declaration of function %qE"), id);
       if (olddecl)
 	locate_old_decl (olddecl, inform);
@@ -2888,31 +2889,31 @@ shadow_tag_warned (const struct c_declsp
 	  if (name == 0)
 	    {
 	      if (warned != 1 && code != ENUMERAL_TYPE)
 		/* Empty unnamed enum OK */
 		{
-		  pedwarn ("unnamed struct/union that defines no instances");
+		  pedwarn0 ("unnamed struct/union that defines no instances");
 		  warned = 1;
 		}
 	    }
 	  else if (!declspecs->tag_defined_p
 		   && declspecs->storage_class != csc_none)
 	    {
 	      if (warned != 1)
-		pedwarn ("empty declaration with storage class specifier "
-			 "does not redeclare tag");
+		pedwarn0 ("empty declaration with storage class specifier "
+			  "does not redeclare tag");
 	      warned = 1;
 	      pending_xref_error ();
 	    }
 	  else if (!declspecs->tag_defined_p
 		   && (declspecs->const_p
 		       || declspecs->volatile_p
 		       || declspecs->restrict_p))
 	    {
 	      if (warned != 1)
-		pedwarn ("empty declaration with type qualifier "
-			 "does not redeclare tag");
+		pedwarn0 ("empty declaration with type qualifier "
+			  "does not redeclare tag");
 	      warned = 1;
 	      pending_xref_error ();
 	    }
 	  else
 	    {
@@ -2928,18 +2929,18 @@ shadow_tag_warned (const struct c_declsp
 	}
       else
 	{
 	  if (warned != 1 && !in_system_header)
 	    {
-	      pedwarn ("useless type name in empty declaration");
+	      pedwarn0 ("useless type name in empty declaration");
 	      warned = 1;
 	    }
 	}
     }
   else if (warned != 1 && !in_system_header && declspecs->typedef_p)
     {
-      pedwarn ("useless type name in empty declaration");
+      pedwarn0 ("useless type name in empty declaration");
       warned = 1;
     }
 
   pending_invalid_xref = 0;
 
@@ -2982,11 +2983,11 @@ shadow_tag_warned (const struct c_declsp
     }
 
   if (warned != 1)
     {
       if (!found_tag)
-	pedwarn ("empty declaration");
+	pedwarn0 ("empty declaration");
     }
 }
 
 
 /* Return the qualifiers from SPECS as a bitwise OR of TYPE_QUAL_*
@@ -3045,17 +3046,17 @@ build_array_declarator (tree expr, struc
       declarator->u.array.attrs = NULL_TREE;
       declarator->u.array.quals = 0;
     }
   declarator->u.array.static_p = static_p;
   declarator->u.array.vla_unspec_p = vla_unspec_p;
-  if (pedantic && !flag_isoc99)
+  if (!flag_isoc99)
     {
       if (static_p || quals != NULL)
-	pedwarn ("ISO C90 does not support %<static%> or type "
+	pedwarn (OPT_pedantic, "ISO C90 does not support %<static%> or type "
 		 "qualifiers in parameter array declarators");
       if (vla_unspec_p)
-	pedwarn ("ISO C90 does not support %<[*]%> array declarators");
+	pedwarn (OPT_pedantic, "ISO C90 does not support %<[*]%> array declarators");
     }
   if (vla_unspec_p)
     {
       if (!current_scope->parm_flag)
 	{
@@ -3306,12 +3307,12 @@ start_decl (struct c_declarator *declara
       && current_scope != file_scope
       && TREE_STATIC (decl)
       && !TREE_READONLY (decl)
       && DECL_DECLARED_INLINE_P (current_function_decl)
       && DECL_EXTERNAL (current_function_decl))
-    pedwarn ("%q+D is static but declared in inline function %qD "
-	     "which is not static", decl, current_function_decl);
+    pedwarn0 ("%q+D is static but declared in inline function %qD "
+	      "which is not static", decl, current_function_decl);
 
   /* Add this decl to the current scope.
      TEM may equal DECL or it may be a previous decl of the same name.  */
   tem = pushdecl (decl);
 
@@ -3684,11 +3685,11 @@ mark_forward_parm_decls (void)
 {
   struct c_binding *b;
 
   if (pedantic && !current_scope->warned_forward_parm_decls)
     {
-      pedwarn ("ISO C forbids forward parameter declarations");
+      pedwarn (OPT_pedantic, "ISO C forbids forward parameter declarations");
       current_scope->warned_forward_parm_decls = true;
     }
 
   for (b = current_scope->bindings; b; b = b->prev)
     if (TREE_CODE (b->decl) == PARM_DECL)
@@ -3831,16 +3832,15 @@ check_bitfield_type_and_width (tree *typ
       error ("bit-field %qs has invalid type", name);
       *type = unsigned_type_node;
     }
 
   type_mv = TYPE_MAIN_VARIANT (*type);
-  if (pedantic
-      && !in_system_header
+  if (!in_system_header
       && type_mv != integer_type_node
       && type_mv != unsigned_type_node
       && type_mv != boolean_type_node)
-    pedwarn ("type of bit-field %qs is a GCC extension", name);
+    pedwarn (OPT_pedantic, "type of bit-field %qs is a GCC extension", name);
 
   max_width = TYPE_PRECISION (*type);
 
   if (0 < compare_tree_int (*width, max_width))
     {
@@ -3866,32 +3866,31 @@ check_bitfield_type_and_width (tree *typ
 /* Print warning about variable length array if necessary.  */
 
 static void
 warn_variable_length_array (const char *name, tree size)
 {
-  int ped = !flag_isoc99 && pedantic && warn_vla != 0;
   int const_size = TREE_CONSTANT (size);
 
-  if (ped)
+  if (!flag_isoc99 && pedantic && warn_vla != 0)
     {
       if (const_size)
 	{
 	  if (name)
-	    pedwarn ("ISO C90 forbids array %qs whose size "
+	    pedwarn (OPT_Wvla, "ISO C90 forbids array %qs whose size "
 		     "can%'t be evaluated",
 		     name);
 	  else
-	    pedwarn ("ISO C90 forbids array whose size "
+	    pedwarn (OPT_Wvla, "ISO C90 forbids array whose size "
 		     "can%'t be evaluated");
 	}
       else
 	{
 	  if (name) 
-	    pedwarn ("ISO C90 forbids variable length array %qs",
+	    pedwarn (OPT_Wvla, "ISO C90 forbids variable length array %qs",
 		     name);
 	  else
-	    pedwarn ("ISO C90 forbids variable length array");
+	    pedwarn (OPT_Wvla, "ISO C90 forbids variable length array");
 	}
     }
   else if (warn_vla > 0)
     {
       if (const_size)
@@ -4048,12 +4047,13 @@ grokdeclarator (const struct c_declarato
 	 -Wreturn-type and this is a function, or if -Wimplicit;
 	 prefer the former warning since it is more explicit.  */
       if ((warn_implicit_int || warn_return_type || flag_isoc99)
 	  && funcdef_flag)
 	warn_about_return_type = 1;
-      else if (warn_implicit_int || flag_isoc99)
-	pedwarn_c99 ("type defaults to %<int%> in declaration of %qs", name);
+      else 
+	pedwarn_c99 (flag_isoc99 ? 0 : OPT_Wimplicit_int, 
+		     "type defaults to %<int%> in declaration of %qs", name);
     }
 
   /* Adjust the type if a bit-field is being declared,
      -funsigned-bitfields applied and the type is not explicitly
      "signed".  */
@@ -4077,15 +4077,15 @@ grokdeclarator (const struct c_declarato
   restrictp = declspecs->restrict_p + TYPE_RESTRICT (element_type);
   volatilep = declspecs->volatile_p + TYPE_VOLATILE (element_type);
   if (pedantic && !flag_isoc99)
     {
       if (constp > 1)
-	pedwarn ("duplicate %<const%>");
+	pedwarn (OPT_pedantic, "duplicate %<const%>");
       if (restrictp > 1)
-	pedwarn ("duplicate %<restrict%>");
+	pedwarn (OPT_pedantic, "duplicate %<restrict%>");
       if (volatilep > 1)
-	pedwarn ("duplicate %<volatile%>");
+	pedwarn (OPT_pedantic, "duplicate %<volatile%>");
     }
   if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
     type = TYPE_MAIN_VARIANT (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
 		| (restrictp ? TYPE_QUAL_RESTRICT : 0)
@@ -4098,13 +4098,13 @@ grokdeclarator (const struct c_declarato
       && (threadp
 	  || storage_class == csc_auto
 	  || storage_class == csc_register
 	  || storage_class == csc_typedef))
     {
-      if (storage_class == csc_auto
-	  && (pedantic || current_scope == file_scope))
-	pedwarn ("function definition declared %<auto%>");
+      if (storage_class == csc_auto)
+	pedwarn ((current_scope == file_scope) ? 0 : OPT_pedantic, 
+		 "function definition declared %<auto%>");
       if (storage_class == csc_register)
 	error ("function definition declared %<register%>");
       if (storage_class == csc_typedef)
 	error ("function definition declared %<typedef%>");
       if (threadp)
@@ -4156,11 +4156,11 @@ grokdeclarator (const struct c_declarato
   else if (current_scope == file_scope)
     {
       if (storage_class == csc_auto)
 	error ("file-scope declaration of %qs specifies %<auto%>", name);
       if (pedantic && storage_class == csc_register)
-	pedwarn ("file-scope declaration of %qs specifies %<register%>", name);
+	pedwarn (OPT_pedantic, "file-scope declaration of %qs specifies %<register%>", name);
     }
   else
     {
       if (storage_class == csc_extern && funcdef_flag)
 	error ("nested function %qs declared %<extern%>", name);
@@ -4269,11 +4269,11 @@ grokdeclarator (const struct c_declarato
 		error ("declaration of %qs as array of functions", name);
 		type = error_mark_node;
 	      }
 
 	    if (pedantic && !in_system_header && flexible_array_type_p (type))
-	      pedwarn ("invalid use of structure with flexible array member");
+	      pedwarn (OPT_pedantic, "invalid use of structure with flexible array member");
 
 	    if (size == error_mark_node)
 	      type = error_mark_node;
 
 	    if (type == error_mark_node)
@@ -4294,11 +4294,11 @@ grokdeclarator (const struct c_declarato
 		    error ("size of array %qs has non-integer type", name);
 		    size = integer_one_node;
 		  }
 
 		if (pedantic && integer_zerop (size))
-		  pedwarn ("ISO C forbids zero-size array %qs", name);
+		  pedwarn (OPT_pedantic, "ISO C forbids zero-size array %qs", name);
 
 		if (TREE_CODE (size) == INTEGER_CST)
 		  {
 		    constant_expression_warning (size);
 		    if (tree_int_cst_sgn (size) < 0)
@@ -4366,11 +4366,11 @@ grokdeclarator (const struct c_declarato
 		  }
 	      }
 	    else if (decl_context == FIELD)
 	      {
 		if (pedantic && !flag_isoc99 && !in_system_header)
-		  pedwarn ("ISO C90 does not support flexible array members");
+		  pedwarn (OPT_pedantic, "ISO C90 does not support flexible array members");
 
 		/* ISO C99 Flexible array members are effectively
 		   identical to GCC's zero-length array extension.  */
 		itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
 	      }
@@ -4511,11 +4511,11 @@ grokdeclarator (const struct c_declarato
 		   effect, so give a warning at -Wreturn-type.
 		   Qualifiers on a void return type are banned on
 		   function definitions in ISO C; GCC used to used
 		   them for noreturn functions.  */
 		if (VOID_TYPE_P (type) && really_funcdef)
-		  pedwarn ("function definition has qualified void return type");
+		  pedwarn0 ("function definition has qualified void return type");
 		else
 		  warning (OPT_Wignored_qualifiers,
 			   "type qualifiers ignored on function return type");
 
 		type = c_build_qualified_type (type, type_quals);
@@ -4543,11 +4543,11 @@ grokdeclarator (const struct c_declarato
 	    /* Merge any constancy or volatility into the target type
 	       for the pointer.  */
 
 	    if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
 		&& type_quals)
-	      pedwarn ("ISO C forbids qualified function types");
+	      pedwarn (OPT_pedantic, "ISO C forbids qualified function types");
 	    if (type_quals)
 	      type = c_build_qualified_type (type, type_quals);
 	    size_varies = 0;
 
 	    /* When the pointed-to type involves components of variable size,
@@ -4624,19 +4624,19 @@ grokdeclarator (const struct c_declarato
   if (storage_class == csc_typedef)
     {
       tree decl;
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
 	  && type_quals)
-	pedwarn ("ISO C forbids qualified function types");
+	pedwarn (OPT_pedantic, "ISO C forbids qualified function types");
       if (type_quals)
 	type = c_build_qualified_type (type, type_quals);
       decl = build_decl (TYPE_DECL, declarator->u.id, type);
       DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
       if (declspecs->explicit_signed_p)
 	C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
       if (declspecs->inline_p)
-	pedwarn ("typedef %q+D declared %<inline%>", decl);
+	pedwarn0 ("typedef %q+D declared %<inline%>", decl);
       return decl;
     }
 
   /* If this is a type name (such as, in a cast or sizeof),
      compute the type and return it now.  */
@@ -4647,21 +4647,22 @@ grokdeclarator (const struct c_declarato
 	 and fields.  */
       gcc_assert (storage_class == csc_none && !threadp
 		  && !declspecs->inline_p);
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
 	  && type_quals)
-	pedwarn ("ISO C forbids const or volatile function types");
+	pedwarn (OPT_pedantic, "ISO C forbids const or volatile function types");
       if (type_quals)
 	type = c_build_qualified_type (type, type_quals);
       return type;
     }
 
   if (pedantic && decl_context == FIELD
       && variably_modified_type_p (type, NULL_TREE))
     {
       /* C99 6.7.2.1p8 */
-      pedwarn ("a member of a structure or union cannot have a variably modified type");
+      pedwarn (OPT_pedantic, 
+	       "a member of a structure or union cannot have a variably modified type");
     }
 
   /* Aside from typedefs and type names (handle above),
      `void' at top level (not within pointer)
      is allowed only in public variables.
@@ -4710,12 +4711,12 @@ grokdeclarator (const struct c_declarato
 
 	    size_varies = 0;
 	  }
 	else if (TREE_CODE (type) == FUNCTION_TYPE)
 	  {
-	    if (pedantic && type_quals)
-	      pedwarn ("ISO C forbids qualified function types");
+	    if (type_quals)
+	      pedwarn (OPT_pedantic, "ISO C forbids qualified function types");
 	    if (type_quals)
 	      type = c_build_qualified_type (type, type_quals);
 	    type = build_pointer_type (type);
 	    type_quals = TYPE_UNQUALIFIED;
 	  }
@@ -4737,11 +4738,11 @@ grokdeclarator (const struct c_declarato
 	else
 	  promoted_type = c_type_promotes_to (type);
 
 	DECL_ARG_TYPE (decl) = promoted_type;
 	if (declspecs->inline_p)
-	  pedwarn ("parameter %q+D declared %<inline%>", decl);
+	  pedwarn0 ("parameter %q+D declared %<inline%>", decl);
       }
     else if (decl_context == FIELD)
       {
 	/* Note that the grammar rejects storage classes in typenames
 	   and fields.  */
@@ -4783,14 +4784,11 @@ grokdeclarator (const struct c_declarato
 	       classes other than `extern' are not allowed, C99
 	       6.7.1p5, and `extern' makes no difference.  However,
 	       GCC allows 'auto', perhaps with 'inline', to support
 	       nested functions.  */
 	    if (storage_class == csc_auto)
-	      {
-		if (pedantic)
-		  pedwarn ("invalid storage class for function %qs", name);
-	      }
+		pedwarn (OPT_pedantic, "invalid storage class for function %qs", name);
 	    else if (storage_class == csc_static)
 	      {
 		error ("invalid storage class for function %qs", name);
 		if (funcdef_flag)
 		  storage_class = declspecs->storage_class = csc_none;
@@ -4802,11 +4800,12 @@ grokdeclarator (const struct c_declarato
 	decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
 	DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
 	decl = build_decl_attribute_variant (decl, decl_attr);
 
 	if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
-	  pedwarn ("ISO C forbids qualified function types");
+	  pedwarn (OPT_pedantic,
+		   "ISO C forbids qualified function types");
 
 	/* GNU C interprets a volatile-qualified function type to indicate
 	   that the function does not return.  */
 	if ((type_quals & TYPE_QUAL_VOLATILE)
 	    && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
@@ -4844,11 +4843,11 @@ grokdeclarator (const struct c_declarato
 
 	/* Record presence of `inline', if it is reasonable.  */
 	if (flag_hosted && MAIN_NAME_P (declarator->u.id))
 	  {
 	    if (declspecs->inline_p)
-	      pedwarn ("cannot inline function %<main%>");
+	      pedwarn0 ("cannot inline function %<main%>");
 	  }
 	else if (declspecs->inline_p)
 	  {
 	    /* Record that the function is declared `inline'.  */
 	    DECL_DECLARED_INLINE_P (decl) = 1;
@@ -4897,11 +4896,11 @@ grokdeclarator (const struct c_declarato
 	DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
 	if (size_varies)
 	  C_DECL_VARIABLE_SIZE (decl) = 1;
 
 	if (declspecs->inline_p)
-	  pedwarn ("variable %q+D declared %<inline%>", decl);
+	  pedwarn0 ("variable %q+D declared %<inline%>", decl);
 
 	/* At file scope, an initialized extern declaration may follow
 	   a static declaration.  In that case, DECL_EXTERNAL will be
 	   reset later in start_decl.  */
 	DECL_EXTERNAL (decl) = (storage_class == csc_extern);
@@ -5005,11 +5004,11 @@ grokparms (struct c_arg_info *arg_info, 
     return 0;  /* don't set TYPE_ARG_TYPES in this case */
 
   else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
     {
       if (!funcdef_flag)
-	pedwarn ("parameter names (without types) in function declaration");
+	pedwarn0 ("parameter names (without types) in function declaration");
 
       arg_info->parms = arg_info->types;
       arg_info->types = 0;
       return 0;
     }
@@ -5419,15 +5418,14 @@ grokfield (struct c_declarator *declarat
 	  else
 	    ok = false;
 	}
       if (!ok)
 	{
-	  pedwarn ("declaration does not declare anything");
+	  pedwarn0 ("declaration does not declare anything");
 	  return NULL_TREE;
 	}
-      if (pedantic)
-	pedwarn ("ISO C doesn%'t support unnamed structs/unions");
+      pedwarn (OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions");
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
 			  width ? &width : NULL, decl_attrs,
 			  DEPRECATED_NORMAL);
@@ -5522,20 +5520,20 @@ finish_struct (tree t, tree fieldlist, t
       if (x == 0)
 	{
 	  if (TREE_CODE (t) == UNION_TYPE)
 	    {
 	      if (fieldlist)
-		pedwarn ("union has no named members");
+		pedwarn (OPT_pedantic, "union has no named members");
 	      else
-		pedwarn ("union has no members");
+		pedwarn (OPT_pedantic, "union has no members");
 	    }
 	  else
 	    {
 	      if (fieldlist)
-		pedwarn ("struct has no named members");
+		pedwarn (OPT_pedantic, "struct has no named members");
 	      else
-		pedwarn ("struct has no members");
+		pedwarn (OPT_pedantic, "struct has no members");
 	    }
 	}
     }
 
   /* Install struct as DECL_CONTEXT of each field decl.
@@ -5610,11 +5608,12 @@ finish_struct (tree t, tree fieldlist, t
 	    }
 	}
 
       if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
 	  && flexible_array_type_p (TREE_TYPE (x)))
-	pedwarn ("%Jinvalid use of structure with flexible array member", x);
+	pedwarn (OPT_pedantic, 
+		 "%Jinvalid use of structure with flexible array member", x);
 
       if (DECL_NAME (x))
 	saw_named_field = 1;
     }
 
@@ -5995,11 +5994,11 @@ build_enumerator (struct c_enum_contents
 	error ("overflow in enumeration values");
     }
 
   if (pedantic && !int_fits_type_p (value, integer_type_node))
     {
-      pedwarn ("ISO C restricts enumerator values to range of %<int%>");
+      pedwarn (OPT_pedantic, "ISO C restricts enumerator values to range of %<int%>");
       /* XXX This causes -pedantic to change the meaning of the program.
 	 Remove?  -zw 2004-03-15  */
       value = convert (integer_type_node, value);
     }
 
@@ -6110,11 +6109,13 @@ start_function (struct c_declspecs *decl
 	= build_function_type (void_type_node,
 			       TYPE_ARG_TYPES (TREE_TYPE (decl1)));
     }
 
   if (warn_about_return_type)
-    pedwarn_c99 ("return type defaults to %<int%>");
+    pedwarn_c99 (flag_isoc99 ? 0 
+		 : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
+		 "return type defaults to %<int%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
   DECL_INITIAL (decl1) = error_mark_node;
 
@@ -6231,16 +6232,16 @@ start_function (struct c_declspecs *decl
   /* Warn for unlikely, improbable, or stupid declarations of `main'.  */
   if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
 	  != integer_type_node)
-	pedwarn ("return type of %q+D is not %<int%>", decl1);
+	pedwarn (OPT_Wmain, "return type of %q+D is not %<int%>", decl1);
 
       check_main_parameter_types(decl1);
 
       if (!TREE_PUBLIC (decl1))
-	pedwarn ("%q+D is normally a non-static function", decl1);
+	pedwarn (OPT_Wmain, "%q+D is normally a non-static function", decl1);
     }
 
   /* Record the decl so that the function name is defined.
      If we already have a decl for this name, and it is a FUNCTION_DECL,
      use the old decl.  */
@@ -6384,11 +6385,11 @@ store_parm_decls_oldstyle (tree fndecl, 
 	  DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (fndecl);
 	  pushdecl (decl);
 	  warn_if_shadowing (decl);
 
 	  if (flag_isoc99)
-	    pedwarn ("type of %q+D defaults to %<int%>", decl);
+	    pedwarn0 ("type of %q+D defaults to %<int%>", decl);
 	  else 
 	    warning (OPT_Wmissing_parameter_type, "type of %q+D defaults to %<int%>", decl);
 	}
 
       TREE_PURPOSE (parm) = decl;
@@ -6495,26 +6496,23 @@ store_parm_decls_oldstyle (tree fndecl, 
 		      && INTEGRAL_TYPE_P (TREE_TYPE (parm))
 		      && TYPE_PRECISION (TREE_TYPE (parm))
 		      < TYPE_PRECISION (integer_type_node))
 		    DECL_ARG_TYPE (parm) = integer_type_node;
 
-		  if (pedantic)
+		  /* ??? Is it possible to get here with a
+		     built-in prototype or will it always have
+		     been diagnosed as conflicting with an
+		     old-style definition and discarded?  */
+		  if (current_function_prototype_built_in)
+		    warning (OPT_pedantic, "promoted argument %qD "
+			     "doesn%'t match built-in prototype", parm);
+		  else
 		    {
-		      /* ??? Is it possible to get here with a
-			 built-in prototype or will it always have
-			 been diagnosed as conflicting with an
-			 old-style definition and discarded?  */
-		      if (current_function_prototype_built_in)
-			warning (0, "promoted argument %qD "
-				 "doesn%'t match built-in prototype", parm);
-		      else
-			{
-			  pedwarn ("promoted argument %qD "
-				   "doesn%'t match prototype", parm);
-			  pedwarn ("%Hprototype declaration",
-				   &current_function_prototype_locus);
-			}
+		      pedwarn (OPT_pedantic, "promoted argument %qD "
+			       "doesn%'t match prototype", parm);
+		      pedwarn (OPT_pedantic, "%Hprototype declaration",
+			       &current_function_prototype_locus);
 		    }
 		}
 	      else
 		{
 		  if (current_function_prototype_built_in)
@@ -6702,11 +6700,11 @@ finish_function (void)
 	  != integer_type_node)
 	{
 	  /* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
 	     If warn_main is -1 (-Wno-main) we don't want to be warned.  */
 	  if (!warn_main)
-	    pedwarn ("return type of %q+D is not %<int%>", fndecl);
+	    pedwarn0 ("return type of %q+D is not %<int%>", fndecl);
 	}
       else
 	{
 	  if (flag_isoc99)
 	    {
@@ -7153,12 +7151,12 @@ declspecs_add_qual (struct c_declspecs *
       specs->restrict_p = true;
       break;
     default:
       gcc_unreachable ();
     }
-  if (dupe && pedantic && !flag_isoc99)
-    pedwarn ("duplicate %qE", qual);
+  if (dupe && !flag_isoc99)
+    pedwarn (OPT_pedantic, "duplicate %qE", qual);
   return specs;
 }
 
 /* Add the type specifier TYPE to the declaration specifiers SPECS,
    returning SPECS.  */
@@ -7200,13 +7198,12 @@ declspecs_add_type (struct c_declspecs *
 		    {
 		      error ("both %<long long%> and %<double%> in "
 			     "declaration specifiers");
 		      break;
 		    }
-		  if (pedantic && !flag_isoc99 && !in_system_header
-		      && warn_long_long)
-		    pedwarn ("ISO C90 does not support %<long long%>");
+		  if (pedantic && !flag_isoc99 && !in_system_header)
+		    pedwarn (OPT_Wlong_long, "ISO C90 does not support %<long long%>");
 		  specs->long_long_p = 1;
 		  break;
 		}
 	      if (specs->short_p)
 		error ("both %<long%> and %<short%> in "
@@ -7325,12 +7322,12 @@ declspecs_add_type (struct c_declspecs *
 	      else
 		specs->unsigned_p = true;
 	      break;
 	    case RID_COMPLEX:
 	      dupe = specs->complex_p;
-	      if (pedantic && !flag_isoc99 && !in_system_header)
-		pedwarn ("ISO C90 does not support complex types");
+	      if (!flag_isoc99 && !in_system_header)
+		pedwarn (OPT_pedantic, "ISO C90 does not support complex types");
 	      if (specs->typespec_word == cts_void)
 		error ("both %<complex%> and %<void%> in "
 		       "declaration specifiers");
 	      else if (specs->typespec_word == cts_bool)
 		error ("both %<complex%> and %<_Bool%> in "
@@ -7356,12 +7353,11 @@ declspecs_add_type (struct c_declspecs *
 	      else
 		specs->complex_p = true;
 	      break;
 	    case RID_SAT:
 	      dupe = specs->saturating_p;
-	      if (pedantic)
-		pedwarn ("ISO C does not support saturating types");
+	      pedwarn (OPT_pedantic, "ISO C does not support saturating types");
 	      if (specs->typespec_word == cts_void)
 		error ("both %<_Sat%> and %<void%> in "
 		       "declaration specifiers");
 	      else if (specs->typespec_word == cts_bool)
 		error ("both %<_Sat%> and %<_Bool%> in "
@@ -7554,12 +7550,12 @@ declspecs_add_type (struct c_declspecs *
 		else
 		  specs->typespec_word = cts_dfloat128;
 	      }
 	      if (!targetm.decimal_float_supported_p ())
 		error ("decimal floating point not supported for this target");
-	      if (pedantic)
-		pedwarn ("ISO C does not support decimal floating point");
+	      pedwarn (OPT_pedantic, 
+		       "ISO C does not support decimal floating point");
 	      return specs;
 	    case RID_FRACT:
 	    case RID_ACCUM:
 	      {
 		const char *str;
@@ -7575,12 +7571,12 @@ declspecs_add_type (struct c_declspecs *
 		else
 		    specs->typespec_word = cts_accum;
 	      }
 	      if (!targetm.fixed_point_supported_p ())
 		error ("fixed-point types not supported for this target");
-	      if (pedantic)
-		pedwarn ("ISO C does not support fixed-point types");
+	      pedwarn (OPT_pedantic, 
+		       "ISO C does not support fixed-point types");
 	      return specs;
 	    default:
 	      /* ObjC reserved word "id", handled below.  */
 	      break;
 	    }
@@ -7762,13 +7758,13 @@ finish_declspecs (struct c_declspecs *sp
 	  specs->typespec_word = cts_int;
 	}
       else if (specs->complex_p)
 	{
 	  specs->typespec_word = cts_double;
-	  if (pedantic)
-	    pedwarn ("ISO C does not support plain %<complex%> meaning "
-		     "%<double complex%>");
+	  pedwarn (OPT_pedantic, 
+		   "ISO C does not support plain %<complex%> meaning "
+		   "%<double complex%>");
 	}
       else
 	{
 	  specs->typespec_word = cts_int;
 	  specs->default_int_p = true;
@@ -7807,12 +7803,12 @@ finish_declspecs (struct c_declspecs *sp
 	specs->type = unsigned_char_type_node;
       else
 	specs->type = char_type_node;
       if (specs->complex_p)
 	{
-	  if (pedantic)
-	    pedwarn ("ISO C does not support complex integer types");
+	  pedwarn (OPT_pedantic, 
+		   "ISO C does not support complex integer types");
 	  specs->type = build_complex_type (specs->type);
 	}
       break;
     case cts_int:
       gcc_assert (!(specs->long_p && specs->short_p));
@@ -7833,12 +7829,12 @@ finish_declspecs (struct c_declspecs *sp
 	specs->type = (specs->unsigned_p
 		       ? unsigned_type_node
 		       : integer_type_node);
       if (specs->complex_p)
 	{
-	  if (pedantic)
-	    pedwarn ("ISO C does not support complex integer types");
+	  pedwarn (OPT_pedantic, 
+		   "ISO C does not support complex integer types");
 	  specs->type = build_complex_type (specs->type);
 	}
       break;
     case cts_float:
       gcc_assert (!specs->long_p && !specs->short_p
@@ -7984,11 +7980,11 @@ c_write_global_declarations_1 (tree glob
 	  && DECL_INITIAL (decl) == 0
 	  && DECL_EXTERNAL (decl)
 	  && !TREE_PUBLIC (decl)
 	  && C_DECL_USED (decl))
 	{
-	  pedwarn ("%q+F used but never defined", decl);
+	  pedwarn0 ("%q+F used but never defined", decl);
 	  TREE_NO_WARNING (decl) = 1;
 	}
 
       wrapup_global_declaration_1 (decl);
     }
Index: gcc/fortran/f95-lang.c
===================================================================
--- gcc/fortran/f95-lang.c	(revision 136559)
+++ gcc/fortran/f95-lang.c	(working copy)
@@ -632,12 +632,12 @@ gfc_mark_addressable (tree exp)
 	      {
 		error ("global register variable %qs used in nested function",
 		       IDENTIFIER_POINTER (DECL_NAME (x)));
 		return false;
 	      }
-	    pedwarn ("register variable %qs used in nested function",
-		     IDENTIFIER_POINTER (DECL_NAME (x)));
+	    pedwarn0 ("register variable %qs used in nested function",
+		      IDENTIFIER_POINTER (DECL_NAME (x)));
 	  }
 	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
 	  {
 	    if (TREE_PUBLIC (x))
 	      {
@@ -657,11 +657,11 @@ gfc_mark_addressable (tree exp)
 		error ("cannot put object with volatile field into register");
 		return false;
 	      }
 #endif
 
-	    pedwarn ("address of register variable %qs requested",
+	    pedwarn0 ("address of register variable %qs requested",
 		     IDENTIFIER_POINTER (DECL_NAME (x)));
 	  }
 
 	/* drops in */
       case FUNCTION_DECL:
Index: gcc/c-errors.c
===================================================================
--- gcc/c-errors.c	(revision 136559)
+++ gcc/c-errors.c	(working copy)
@@ -29,34 +29,36 @@ along with GCC; see the file COPYING3.  
 #include "diagnostic.h"
 
 /* Issue an ISO C99 pedantic warning MSGID.  */
 
 void
-pedwarn_c99 (const char *gmsgid, ...)
+pedwarn_c99 (int opt, const char *gmsgid, ...)
 {
   diagnostic_info diagnostic;
   va_list ap;
 
   va_start (ap, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
 		       flag_isoc99 ? pedantic_warning_kind () : DK_WARNING);
+  diagnostic.option_index = opt;
   report_diagnostic (&diagnostic);
   va_end (ap);
 }
 
 /* Issue an ISO C90 pedantic warning MSGID.  This function is supposed to
    be used for matters that are allowed in ISO C99 but not supported in
    ISO C90, thus we explicitly don't pedwarn when C99 is specified.
    (There is no flag_c90.)  */
 
 void
-pedwarn_c90 (const char *gmsgid, ...)
+pedwarn_c90 (int opt, const char *gmsgid, ...)
 {
   diagnostic_info diagnostic;
   va_list ap;
 
   va_start (ap, gmsgid);
   diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
 		       flag_isoc99 ? DK_WARNING : pedantic_warning_kind ());
+  diagnostic.option_index = opt;
   report_diagnostic (&diagnostic);
   va_end (ap);
 }
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c	(revision 136559)
+++ gcc/c-typeck.c	(working copy)
@@ -468,12 +468,12 @@ composite_type (tree t1, tree t2)
 		      mv3 = TYPE_MAIN_VARIANT (mv3);
 		    if (comptypes (mv3, mv2))
 		      {
 			TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
 							 TREE_VALUE (p2));
-			if (pedantic)
-			  pedwarn ("function types not truly compatible in ISO C");
+			pedwarn (OPT_pedantic, 
+				 "function types not truly compatible in ISO C");
 			goto parm_done;
 		      }
 		  }
 	      }
 	    if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
@@ -493,12 +493,12 @@ composite_type (tree t1, tree t2)
 		      mv3 = TYPE_MAIN_VARIANT (mv3);
 		    if (comptypes (mv3, mv1))
 		      {
 			TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
 							 TREE_VALUE (p1));
-			if (pedantic)
-			  pedwarn ("function types not truly compatible in ISO C");
+			pedwarn (OPT_pedantic, 
+				 "function types not truly compatible in ISO C");
 			goto parm_done;
 		      }
 		  }
 	      }
 	    TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
@@ -1037,12 +1037,12 @@ comp_target_types (tree ttl, tree ttr)
     mvl = TYPE_MAIN_VARIANT (mvl);
   if (TREE_CODE (mvr) != ARRAY_TYPE)
     mvr = TYPE_MAIN_VARIANT (mvr);
   val = comptypes (mvl, mvr);
 
-  if (val == 2 && pedantic)
-    pedwarn ("types are not quite compatible");
+  if (val == 2)
+    pedwarn (OPT_pedantic, "types are not quite compatible");
   return val;
 }
 
 /* Subroutines of `comptypes'.  */
 
@@ -1361,11 +1361,11 @@ function_types_compatible_p (const_tree 
   ret2 = TREE_TYPE (f2);
 
   /* 'volatile' qualifiers on a function's return type used to mean
      the function is noreturn.  */
   if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
-    pedwarn ("function return types not compatible due to %<volatile%>");
+    pedwarn0 ("function return types not compatible due to %<volatile%>");
   if (TYPE_VOLATILE (ret1))
     ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
 				 TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
   if (TYPE_VOLATILE (ret2))
     ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
@@ -2113,13 +2113,15 @@ build_array_ref (tree array, tree index)
 	{
 	  tree foo = array;
 	  while (TREE_CODE (foo) == COMPONENT_REF)
 	    foo = TREE_OPERAND (foo, 0);
 	  if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
-	    pedwarn ("ISO C forbids subscripting %<register%> array");
+	    pedwarn (OPT_pedantic, 
+		     "ISO C forbids subscripting %<register%> array");
 	  else if (!flag_isoc99 && !lvalue_p (foo))
-	    pedwarn ("ISO C90 forbids subscripting non-lvalue array");
+	    pedwarn (OPT_pedantic, 
+		     "ISO C90 forbids subscripting non-lvalue array");
 	}
 
       type = TREE_TYPE (TREE_TYPE (array));
       rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
       /* Array ref is const/volatile if the array elements are
@@ -2231,12 +2233,12 @@ build_external_ref (tree id, int fun, lo
 	   && DECL_EXTERNAL (current_function_decl)
 	   && VAR_OR_FUNCTION_DECL_P (ref)
 	   && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref))
 	   && ! TREE_PUBLIC (ref)
 	   && DECL_CONTEXT (ref) != current_function_decl)
-    pedwarn ("%H%qD is static but used in inline function %qD "
-	     "which is not static", &loc, ref, current_function_decl);
+    pedwarn0 ("%H%qD is static but used in inline function %qD "
+	      "which is not static", &loc, ref, current_function_decl);
 
   return ref;
 }
 
 /* Record details of decls possibly used inside sizeof or typeof.  */
@@ -2456,11 +2458,11 @@ build_function_call (tree function, tree
       result = fold_build_call_array_initializer (TREE_TYPE (fntype),
 						  function, nargs, argarray);
       if (TREE_CONSTANT (result)
 	  && (name == NULL_TREE
 	      || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
-	pedwarn_init ("initializer element is not constant");
+	pedwarn_init (0, "initializer element is not constant");
     }
   else
     result = fold_build_call_array (TREE_TYPE (fntype),
 				    function, nargs, argarray);
 
@@ -2800,17 +2802,16 @@ pointer_diff (tree op0, tree op1)
 
   tree target_type = TREE_TYPE (TREE_TYPE (op0));
   tree con0, con1, lit0, lit1;
   tree orig_op1 = op1;
 
-  if (pedantic || warn_pointer_arith)
-    {
-      if (TREE_CODE (target_type) == VOID_TYPE)
-	pedwarn ("pointer of type %<void *%> used in subtraction");
-      if (TREE_CODE (target_type) == FUNCTION_TYPE)
-	pedwarn ("pointer to a function used in subtraction");
-    }
+  if (TREE_CODE (target_type) == VOID_TYPE)
+    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	     "pointer of type %<void *%> used in subtraction");
+  if (TREE_CODE (target_type) == FUNCTION_TYPE)
+    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	     "pointer to a function used in subtraction");
 
   /* If the conversion to ptrdiff_type does anything like widening or
      converting a partial to an integral mode, we get a convert_expression
      that is in the way to do any simplifications.
      (fold-const.c doesn't know that the extra bits won't be needed.
@@ -2948,12 +2949,12 @@ build_unary_op (enum tree_code code, tre
 	    arg = default_conversion (arg);
 	}
       else if (typecode == COMPLEX_TYPE)
 	{
 	  code = CONJ_EXPR;
-	  if (pedantic)
-	    pedwarn ("ISO C does not support %<~%> for complex conjugation");
+	  pedwarn (OPT_pedantic, 
+		   "ISO C does not support %<~%> for complex conjugation");
 	  if (!noconvert)
 	    arg = default_conversion (arg);
 	}
       else
 	{
@@ -3020,13 +3021,12 @@ build_unary_op (enum tree_code code, tre
 	 and don't change the imaginary part.  */
       if (typecode == COMPLEX_TYPE)
 	{
 	  tree real, imag;
 
-	  if (pedantic)
-	    pedwarn ("ISO C does not support %<++%> and %<--%>"
-		     " on complex types");
+	  pedwarn (OPT_pedantic, "ISO C does not support %<++%> and %<--%>"
+		   " on complex types");
 
 	  arg = stabilize_reference (arg);
 	  real = build_unary_op (REALPART_EXPR, arg, 1);
 	  imag = build_unary_op (IMAGPART_EXPR, arg, 1);
 	  real = build_unary_op (code, real, 1);
@@ -3067,18 +3067,19 @@ build_unary_op (enum tree_code code, tre
 		if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
 		  error ("increment of pointer to unknown structure");
 		else
 		  error ("decrement of pointer to unknown structure");
 	      }
-	    else if ((pedantic || warn_pointer_arith)
-		     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
-			 || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
+	    else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
+		     || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
 	      {
 		if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-		  pedwarn ("wrong type argument to increment");
+		  pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+			   "wrong type argument to increment");
 		else
-		  pedwarn ("wrong type argument to decrement");
+		  pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+			   "wrong type argument to decrement");
 	      }
 
 	    inc = c_size_in_bytes (TREE_TYPE (result_type));
 	    inc = fold_convert (sizetype, inc);
 	  }
@@ -3349,11 +3350,11 @@ c_mark_addressable (tree exp)
 	      {
 		error
 		  ("global register variable %qD used in nested function", x);
 		return false;
 	      }
-	    pedwarn ("register variable %qD used in nested function", x);
+	    pedwarn0 ("register variable %qD used in nested function", x);
 	  }
 	else if (C_DECL_REGISTER (x))
 	  {
 	    if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
 	      error ("address of global register variable %qD requested", x);
@@ -3456,12 +3457,13 @@ build_conditional_expr (tree ifexp, tree
 	    }
 	}
     }
   else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
     {
-      if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
-	pedwarn ("ISO C forbids conditional expr with only one void side");
+      if (code1 != VOID_TYPE || code2 != VOID_TYPE)
+	pedwarn (OPT_pedantic, 
+		 "ISO C forbids conditional expr with only one void side");
       result_type = void_type_node;
     }
   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
     {
       if (comp_target_types (type1, type2))
@@ -3470,44 +3472,44 @@ build_conditional_expr (tree ifexp, tree
 	result_type = qualify_type (type2, type1);
       else if (null_pointer_constant_p (orig_op2))
 	result_type = qualify_type (type1, type2);
       else if (VOID_TYPE_P (TREE_TYPE (type1)))
 	{
-	  if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
-	    pedwarn ("ISO C forbids conditional expr between "
+	  if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
+	    pedwarn (OPT_pedantic, "ISO C forbids conditional expr between "
 		     "%<void *%> and function pointer");
 	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
 							  TREE_TYPE (type2)));
 	}
       else if (VOID_TYPE_P (TREE_TYPE (type2)))
 	{
-	  if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
-	    pedwarn ("ISO C forbids conditional expr between "
+	  if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
+	    pedwarn (OPT_pedantic, "ISO C forbids conditional expr between "
 		     "%<void *%> and function pointer");
 	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
 							  TREE_TYPE (type1)));
 	}
       else
 	{
-	  pedwarn ("pointer type mismatch in conditional expression");
+	  pedwarn0 ("pointer type mismatch in conditional expression");
 	  result_type = build_pointer_type (void_type_node);
 	}
     }
   else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
     {
       if (!null_pointer_constant_p (orig_op2))
-	pedwarn ("pointer/integer type mismatch in conditional expression");
+	pedwarn0 ("pointer/integer type mismatch in conditional expression");
       else
 	{
 	  op2 = null_pointer_node;
 	}
       result_type = type1;
     }
   else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
     {
       if (!null_pointer_constant_p (orig_op1))
-	pedwarn ("pointer/integer type mismatch in conditional expression");
+	pedwarn0 ("pointer/integer type mismatch in conditional expression");
       else
 	{
 	  op1 = null_pointer_node;
 	}
       result_type = type2;
@@ -3614,16 +3616,14 @@ build_c_cast (tree type, tree expr)
 	return error_mark_node;
     }
 
   if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
     {
-      if (pedantic)
-	{
-	  if (TREE_CODE (type) == RECORD_TYPE
-	      || TREE_CODE (type) == UNION_TYPE)
-	    pedwarn ("ISO C forbids casting nonscalar to the same type");
-	}
+      if (TREE_CODE (type) == RECORD_TYPE
+	  || TREE_CODE (type) == UNION_TYPE)
+	pedwarn (OPT_pedantic, 
+		 "ISO C forbids casting nonscalar to the same type");
     }
   else if (TREE_CODE (type) == UNION_TYPE)
     {
       tree field;
 
@@ -3635,12 +3635,11 @@ build_c_cast (tree type, tree expr)
 
       if (field)
 	{
 	  tree t;
 
-	  if (pedantic)
-	    pedwarn ("ISO C forbids casts to union type");
+	  pedwarn (OPT_pedantic, "ISO C forbids casts to union type");
 	  t = digest_init (type,
 			   build_constructor_single (type, field, value),
 			   true, 0);
 	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
 	  return t;
@@ -3747,19 +3746,21 @@ build_c_cast (tree type, tree expr)
       if (pedantic
 	  && TREE_CODE (type) == POINTER_TYPE
 	  && TREE_CODE (otype) == POINTER_TYPE
 	  && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
 	  && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
-	pedwarn ("ISO C forbids conversion of function pointer to object pointer type");
+	pedwarn (OPT_pedantic, "ISO C forbids "
+		 "conversion of function pointer to object pointer type");
 
       if (pedantic
 	  && TREE_CODE (type) == POINTER_TYPE
 	  && TREE_CODE (otype) == POINTER_TYPE
 	  && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
 	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
 	  && !null_pointer_constant_p (value))
-	pedwarn ("ISO C forbids conversion of object pointer to function pointer type");
+	pedwarn (OPT_pedantic, "ISO C forbids "
+		 "conversion of object pointer to function pointer type");
 
       ovalue = value;
       value = convert (type, value);
 
       /* Ignore any integer overflow caused by the cast.  */
@@ -3951,23 +3952,23 @@ convert_for_assignment (tree type, tree 
 #define WARN_FOR_ASSIGNMENT(AR, AS, IN, RE)	\
   do {						\
     switch (errtype)				\
       {						\
       case ic_argpass:				\
-	pedwarn (AR, parmnum, rname);		\
+	pedwarn (0, AR, parmnum, rname);	\
 	break;					\
       case ic_argpass_nonproto:			\
-	warning (0, AR, parmnum, rname);		\
+	warning (0, AR, parmnum, rname);	\
 	break;					\
       case ic_assign:				\
-	pedwarn (AS);				\
+	pedwarn (0, AS);			\
 	break;					\
       case ic_init:				\
-	pedwarn (IN);				\
+	pedwarn (0, IN);			\
 	break;					\
       case ic_return:				\
-	pedwarn (RE);				\
+	pedwarn (0, RE);			\
 	break;					\
       default:					\
 	gcc_unreachable ();			\
       }						\
   } while (0)
@@ -4170,12 +4171,13 @@ convert_for_assignment (tree type, tree 
 					"pointer target type"));
 
 	      memb = marginal_memb;
 	    }
 
-	  if (pedantic && (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl)))
-	    pedwarn ("ISO C prohibits argument conversion to union type");
+	  if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))
+	    pedwarn (OPT_pedantic, 
+		     "ISO C prohibits argument conversion to union type");
 
 	  rhs = fold_convert (TREE_TYPE (memb), rhs);
 	  return build_constructor_single (type, memb, rhs);
 	}
     }
@@ -4619,23 +4621,24 @@ error_init (const char *msgid)
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
     error ("(near initialization for %qs)", ofwhat);
 }
 
-/* Issue a pedantic warning for a bad initializer component.
-   MSGID identifies the message.
-   The component name is taken from the spelling stack.  */
+/* Issue a pedantic warning for a bad initializer component.  OPT is
+   the option OPT_* (from options.h) controlling this warning or 0 if
+   it is unconditionally given.  MSGID identifies the message.  The
+   component name is taken from the spelling stack.  */
 
 void
-pedwarn_init (const char *msgid)
+pedwarn_init (int opt, const char *msgid)
 {
   char *ofwhat;
 
-  pedwarn ("%s", _(msgid));
+  pedwarn (opt, "%s", _(msgid));
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
-    pedwarn ("(near initialization for %qs)", ofwhat);
+    pedwarn (opt, "(near initialization for %qs)", ofwhat);
 }
 
 /* Issue a warning for a bad initializer component.  
 
    OPT is the OPT_W* value corresponding to the warning option that
@@ -4662,11 +4665,12 @@ maybe_warn_string_init (tree type, struc
 {
   if (pedantic
       && TREE_CODE (type) == ARRAY_TYPE
       && TREE_CODE (expr.value) == STRING_CST
       && expr.original_code != STRING_CST)
-    pedwarn_init ("array initialized from parenthesized string constant");
+    pedwarn_init (OPT_pedantic, 
+		  "array initialized from parenthesized string constant");
 }
 
 /* Digest the parser output INIT as an initializer for type TYPE.
    Return a C expression of type TYPE to represent the initial value.
 
@@ -4746,11 +4750,11 @@ digest_init (tree type, tree init, bool 
 				       - ((TYPE_PRECISION (typ1)
 					   != TYPE_PRECISION (char_type_node))
 					  ? (TYPE_PRECISION (wchar_type_node)
 					     / BITS_PER_UNIT)
 					  : 1)))
-	    pedwarn_init ("initializer-string for array of chars is too long");
+	    pedwarn_init (0, "initializer-string for array of chars is too long");
 
 	  return inside_init;
 	}
       else if (INTEGRAL_TYPE_P (typ1))
 	{
@@ -4861,11 +4865,11 @@ digest_init (tree type, tree init, bool 
 	    = valid_compound_expr_initializer (inside_init,
 					       TREE_TYPE (inside_init));
 	  if (inside_init == error_mark_node)
 	    error_init ("initializer element is not constant");
 	  else
-	    pedwarn_init ("initializer element is not constant");
+	    pedwarn_init (OPT_pedantic, "initializer element is not constant");
 	  if (flag_pedantic_errors)
 	    inside_init = error_mark_node;
 	}
       else if (require_constant
 	       && !initializer_constant_valid_p (inside_init,
@@ -5534,12 +5538,12 @@ pop_init_level (int implicit)
 	{
 	  gcc_assert (!TYPE_SIZE (constructor_type));
 
 	  if (constructor_depth > 2)
 	    error_init ("initialization of flexible array member in a nested context");
-	  else if (pedantic)
-	    pedwarn_init ("initialization of a flexible array member");
+	  else
+	    pedwarn_init (OPT_pedantic, "initialization of a flexible array member");
 
 	  /* We have already issued an error message for the existence
 	     of a flexible array member not at the end of the structure.
 	     Discard the initializer so that we do not die later.  */
 	  if (TREE_CHAIN (constructor_fields) != NULL_TREE)
@@ -6280,11 +6284,11 @@ output_init_element (tree value, bool st
 	{
 	  error_init ("initializer element is not constant");
 	  value = error_mark_node;
 	}
       else if (require_constant_elements)
-	pedwarn ("initializer element is not computable at load time");
+	pedwarn0 ("initializer element is not computable at load time");
     }
 
   /* If this field is empty (and not at the end of structure),
      don't do anything other than checking the initializer.  */
   if (field
@@ -6607,11 +6611,11 @@ process_init_element (struct c_expr valu
 	  tree fieldtype;
 	  enum tree_code fieldcode;
 
 	  if (constructor_fields == 0)
 	    {
-	      pedwarn_init ("excess elements in struct initializer");
+	      pedwarn_init (0, "excess elements in struct initializer");
 	      break;
 	    }
 
 	  fieldtype = TREE_TYPE (constructor_fields);
 	  if (fieldtype != error_mark_node)
@@ -6690,11 +6694,11 @@ process_init_element (struct c_expr valu
 	  tree fieldtype;
 	  enum tree_code fieldcode;
 
 	  if (constructor_fields == 0)
 	    {
-	      pedwarn_init ("excess elements in union initializer");
+	      pedwarn_init (0, "excess elements in union initializer");
 	      break;
 	    }
 
 	  fieldtype = TREE_TYPE (constructor_fields);
 	  if (fieldtype != error_mark_node)
@@ -6777,11 +6781,11 @@ process_init_element (struct c_expr valu
 
 	  if (constructor_max_index != 0
 	      && (tree_int_cst_lt (constructor_max_index, constructor_index)
 		  || integer_all_onesp (constructor_max_index)))
 	    {
-	      pedwarn_init ("excess elements in array initializer");
+	      pedwarn_init (0, "excess elements in array initializer");
 	      break;
 	    }
 
 	  /* Now output the actual element.  */
 	  if (value.value)
@@ -6807,11 +6811,11 @@ process_init_element (struct c_expr valu
 
 	 /* Do a basic check of initializer size.  Note that vectors
 	    always have a fixed size derived from their type.  */
 	  if (tree_int_cst_lt (constructor_max_index, constructor_index))
 	    {
-	      pedwarn_init ("excess elements in vector initializer");
+	      pedwarn_init (0, "excess elements in vector initializer");
 	      break;
 	    }
 
 	  /* Now output the actual element.  */
 	  if (value.value)
@@ -6831,11 +6835,11 @@ process_init_element (struct c_expr valu
       /* Handle the sole element allowed in a braced initializer
 	 for a scalar variable.  */
       else if (constructor_type != error_mark_node
 	       && constructor_fields == 0)
 	{
-	  pedwarn_init ("excess elements in scalar initializer");
+	  pedwarn_init (0, "excess elements in scalar initializer");
 	  break;
 	}
       else
 	{
 	  if (value.value)
@@ -7062,12 +7066,11 @@ c_finish_goto_label (tree label)
 /* Generate a computed goto statement to EXPR.  */
 
 tree
 c_finish_goto_ptr (tree expr)
 {
-  if (pedantic)
-    pedwarn ("ISO C forbids %<goto *expr;%>");
+  pedwarn (OPT_pedantic, "ISO C forbids %<goto *expr;%>");
   expr = convert (ptr_type_node, expr);
   return add_stmt (build1 (GOTO_EXPR, void_type_node, expr));
 }
 
 /* Generate a C `return' statement.  RETVAL is the expression for what
@@ -7086,22 +7089,24 @@ c_finish_return (tree retval)
     {
       current_function_returns_null = 1;
       if ((warn_return_type || flag_isoc99)
 	  && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
 	{
-	  pedwarn_c99 ("%<return%> with no value, in "
+	  pedwarn_c99 (flag_isoc99 ? 0 : OPT_Wreturn_type, 
+		       "%<return%> with no value, in "
 		       "function returning non-void");
 	  no_warning = true;
 	}
     }
   else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
     {
       current_function_returns_null = 1;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
-	pedwarn ("%<return%> with a value, in function returning void");
-      else if (pedantic)
-	pedwarn ("ISO C forbids %<return%> with expression, in function returning void");
+	pedwarn0 ("%<return%> with a value, in function returning void");
+      else 
+	pedwarn (OPT_pedantic, "ISO C forbids "
+		 "%<return%> with expression, in function returning void");
     }
   else
     {
       tree t = convert_for_assignment (valtype, retval, ic_return,
 				       NULL_TREE, NULL_TREE, 0);
@@ -8167,24 +8172,24 @@ build_binary_op (enum tree_code code, tr
 	    {
 	      /* op0 != orig_op0 detects the case of something
 		 whose value is 0 but which isn't a valid null ptr const.  */
 	      if (pedantic && !null_pointer_constant_p (orig_op0)
 		  && TREE_CODE (tt1) == FUNCTION_TYPE)
-		pedwarn ("ISO C forbids comparison of %<void *%>"
-			 " with function pointer");
+		pedwarn (OPT_pedantic, "ISO C forbids "
+			 "comparison of %<void *%> with function pointer");
 	    }
 	  else if (VOID_TYPE_P (tt1))
 	    {
 	      if (pedantic && !null_pointer_constant_p (orig_op1)
 		  && TREE_CODE (tt0) == FUNCTION_TYPE)
-		pedwarn ("ISO C forbids comparison of %<void *%>"
-			 " with function pointer");
+		pedwarn (OPT_pedantic, "ISO C forbids "
+			 "comparison of %<void *%> with function pointer");
 	    }
 	  else
 	    /* Avoid warning about the volatile ObjC EH puts on decls.  */
 	    if (!objc_ok)
-	      pedwarn ("comparison of distinct pointer types lacks a cast");
+	      pedwarn0 ("comparison of distinct pointer types lacks a cast");
 
 	  if (result_type == NULL_TREE)
 	    result_type = ptr_type_node;
 	}
       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
@@ -8204,16 +8209,16 @@ build_binary_op (enum tree_code code, tr
 	  result_type = type1;
 	}
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  result_type = type0;
-	  pedwarn ("comparison between pointer and integer");
+	  pedwarn0 ("comparison between pointer and integer");
 	}
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
 	{
 	  result_type = type1;
-	  pedwarn ("comparison between pointer and integer");
+	  pedwarn0 ("comparison between pointer and integer");
 	}
       break;
 
     case LE_EXPR:
     case GE_EXPR:
@@ -8230,42 +8235,42 @@ build_binary_op (enum tree_code code, tr
 	  if (comp_target_types (type0, type1))
 	    {
 	      result_type = common_pointer_type (type0, type1);
 	      if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
 		  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
-		pedwarn ("comparison of complete and incomplete pointers");
-	      else if (pedantic
-		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
-		pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
+		pedwarn0 ("comparison of complete and incomplete pointers");
+	      else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
+		pedwarn (OPT_pedantic, "ISO C forbids "
+			 "ordered comparisons of pointers to functions");
 	    }
 	  else
 	    {
 	      result_type = ptr_type_node;
-	      pedwarn ("comparison of distinct pointer types lacks a cast");
+	      pedwarn0 ("comparison of distinct pointer types lacks a cast");
 	    }
 	}
       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
 	{
 	  result_type = type0;
-	  if (pedantic || extra_warnings)
-	    pedwarn ("ordered comparison of pointer with integer zero");
+	  pedwarn (OPT_pedantic, 
+		   "ordered comparison of pointer with integer zero");
 	}
       else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
 	{
 	  result_type = type1;
-	  if (pedantic)
-	    pedwarn ("ordered comparison of pointer with integer zero");
+	  pedwarn (OPT_pedantic, 
+		   "ordered comparison of pointer with integer zero");
 	}
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
 	{
 	  result_type = type0;
-	  pedwarn ("comparison between pointer and integer");
+	  pedwarn0 ("comparison between pointer and integer");
 	}
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
 	{
 	  result_type = type1;
-	  pedwarn ("comparison between pointer and integer");
+	  pedwarn0 ("comparison between pointer and integer");
 	}
       break;
 
     default:
       gcc_unreachable ();
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 136559)
+++ gcc/c-common.c	(working copy)
@@ -866,11 +866,11 @@ fname_decl (unsigned int rid, tree id)
 	  = tree_cons (decl, stmts, saved_function_name_decls);
       *fname_vars[ix].decl = decl;
       input_location = saved_location;
     }
   if (!ix && !current_function_decl)
-    pedwarn ("%qD is not defined outside of function scope", decl);
+    pedwarn0 ("%qD is not defined outside of function scope", decl);
 
   return decl;
 }
 
 /* Given a STRING_CST, give it a suitable array-of-chars data type.  */
@@ -915,11 +915,12 @@ fix_string_type (tree value)
       if (nchars - 1 > nchars_max)
 	/* Translators: The %d after 'ISO C' will be 90 or 99.  Do not
 	   separate the %d from the 'C'.  'ISO' should not be
 	   translated, but it may be moved after 'C%d' in languages
 	   where modifiers follow nouns.  */
-	pedwarn ("string length %qd is greater than the length %qd "
+	pedwarn (OPT_Woverlength_strings,
+		 "string length %qd is greater than the length %qd "
 		 "ISO C%d compilers are required to support",
 		 nchars - 1, nchars_max, relevant_std);
     }
 
   /* Create the array type for the string constant.  The ISO C++
@@ -962,11 +963,11 @@ constant_expression_warning (tree value)
       && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
 	  || TREE_CODE (value) == FIXED_CST
 	  || TREE_CODE (value) == VECTOR_CST
 	  || TREE_CODE (value) == COMPLEX_CST)
       && TREE_OVERFLOW (value))
-    pedwarn ("overflow in constant expression");
+    pedwarn (OPT_Woverflow, "overflow in constant expression");
 }
 
 /* The same as above but print an unconditional error.  */
 void
 constant_expression_error (tree value)
@@ -1174,38 +1175,38 @@ check_main_parameter_types (tree decl)
      ++argct;
      switch (argct)
        {
        case 1:
          if (TYPE_MAIN_VARIANT (type) != integer_type_node)
-           pedwarn ("first argument of %q+D should be %<int%>", decl);
+           pedwarn0 ("first argument of %q+D should be %<int%>", decl);
          break;
 
        case 2:
          if (TREE_CODE (type) != POINTER_TYPE
              || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
              || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                  != char_type_node))
-           pedwarn ("second argument of %q+D should be %<char **%>",
-                    decl);
+           pedwarn0 ("second argument of %q+D should be %<char **%>",
+		     decl);
          break;
 
        case 3:
          if (TREE_CODE (type) != POINTER_TYPE
              || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
              || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
                  != char_type_node))
-           pedwarn ("third argument of %q+D should probably be "
-                    "%<char **%>", decl);
+           pedwarn0 ("third argument of %q+D should probably be "
+		     "%<char **%>", decl);
          break;
        }
    }
 
   /* It is intentional that this message does not mention the third
     argument because it's only mentioned in an appendix of the
     standard.  */
   if (argct > 0 && (argct < 2 || argct > 3))
-   pedwarn ("%q+D takes only zero or two arguments", decl);
+   pedwarn0 ("%q+D takes only zero or two arguments", decl);
 }
 
 /* True if vector types T1 and T2 can be converted to each other
    without an explicit cast.  If EMIT_LAX_NOTE is true, and T1 and T2
    can only be converted with -flax-vector-conversions yet that is not
@@ -2854,24 +2855,24 @@ pointer_int_sum (enum tree_code resultco
   /* The result is a pointer of the same type that is being added.  */
   tree result_type = TREE_TYPE (ptrop);
 
   if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
     {
-      if (pedantic || warn_pointer_arith)
-	pedwarn ("pointer of type %<void *%> used in arithmetic");
+      pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	       "pointer of type %<void *%> used in arithmetic");
       size_exp = integer_one_node;
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
     {
-      if (pedantic || warn_pointer_arith)
-	pedwarn ("pointer to a function used in arithmetic");
+      pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	       "pointer to a function used in arithmetic");
       size_exp = integer_one_node;
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
     {
-      if (pedantic || warn_pointer_arith)
-	pedwarn ("pointer to member function used in arithmetic");
+      pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	       "pointer to member function used in arithmetic");
       size_exp = integer_one_node;
     }
   else
     size_exp = size_in_bytes (TREE_TYPE (result_type));
 
@@ -3379,11 +3380,12 @@ c_sizeof_or_alignof_type (tree type, boo
   if (type_code == FUNCTION_TYPE)
     {
       if (is_sizeof)
 	{
 	  if (complain && (pedantic || warn_pointer_arith))
-	    pedwarn ("invalid application of %<sizeof%> to a function type");
+	    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+		     "invalid application of %<sizeof%> to a function type");
           else if (!complain)
             return error_mark_node;
 	  value = size_one_node;
 	}
       else
@@ -3391,11 +3393,12 @@ c_sizeof_or_alignof_type (tree type, boo
     }
   else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
     {
       if (type_code == VOID_TYPE
 	  && complain && (pedantic || warn_pointer_arith))
-	pedwarn ("invalid application of %qs to a void type", op_name);
+	pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+		 "invalid application of %qs to a void type", op_name);
       else if (!complain)
         return error_mark_node;
       value = size_one_node;
     }
   else if (!COMPLETE_TYPE_P (type))
@@ -4243,12 +4246,13 @@ c_add_case_label (splay_tree cases, tree
       error ("pointers are not permitted as case values");
       goto error_out;
     }
 
   /* Case ranges are a GNU extension.  */
-  if (high_value && pedantic)
-    pedwarn ("range expressions in switch statements are non-standard");
+  if (high_value)
+    pedwarn (OPT_pedantic, 
+	     "range expressions in switch statements are non-standard");
 
   type = TREE_TYPE (cond);
   if (low_value)
     {
       low_value = check_case_value (low_value);
@@ -4557,12 +4561,11 @@ c_do_switch_warnings (splay_tree cases, 
 tree
 finish_label_address_expr (tree label)
 {
   tree result;
 
-  if (pedantic)
-    pedwarn ("taking the address of a label is non-standard");
+  pedwarn (OPT_pedantic, "taking the address of a label is non-standard");
 
   if (label == error_mark_node)
     return error_mark_node;
 
   label = lookup_label (label);
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c	(revision 136559)
+++ gcc/c-parser.c	(working copy)
@@ -1063,13 +1063,12 @@ static tree c_parser_objc_keywordexpr (c
 static void
 c_parser_translation_unit (c_parser *parser)
 {
   if (c_parser_next_token_is (parser, CPP_EOF))
     {
-      if (pedantic)
-	pedwarn ("%HISO C forbids an empty translation unit",
-		 &c_parser_peek_token (parser)->location);
+      pedwarn (OPT_pedantic, "%HISO C forbids an empty translation unit",
+	       &c_parser_peek_token (parser)->location);
     }
   else
     {
       void *obstack_position = obstack_alloc (&parser_obstack, 0);
       do
@@ -1149,13 +1148,13 @@ c_parser_external_declaration (c_parser 
 	default:
 	  goto decl_or_fndef;
 	}
       break;
     case CPP_SEMICOLON:
-      if (pedantic)
-	pedwarn ("%HISO C does not allow extra %<;%> outside of a function",
-		 &c_parser_peek_token (parser)->location);
+      pedwarn (OPT_pedantic, 
+	       "%HISO C does not allow extra %<;%> outside of a function",
+	       &c_parser_peek_token (parser)->location);
       c_parser_consume_token (parser);
       break;
     case CPP_PRAGMA:
       c_parser_pragma (parser, pragma_external);
       break;
@@ -1265,11 +1264,11 @@ c_parser_declaration_or_fndef (c_parser 
       if (empty_ok)
 	shadow_tag (specs);
       else
 	{
 	  shadow_tag_warned (specs, 1);
-	  pedwarn ("%Hempty declaration", &here);
+	  pedwarn0 ("%Hempty declaration", &here);
 	}
       c_parser_consume_token (parser);
       return;
     }
   pending_xref_error ();
@@ -1301,12 +1300,12 @@ c_parser_declaration_or_fndef (c_parser 
 	  tree asm_name = NULL_TREE;
 	  tree postfix_attrs = NULL_TREE;
 	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
 	    {
 	      diagnosed_no_specs = true;
-	      pedwarn ("%Hdata definition has no type or storage class",
-		       &here);
+	      pedwarn0 ("%Hdata definition has no type or storage class",
+			&here);
 	    }
 	  /* Having seen a data definition, there cannot now be a
 	     function definition.  */
 	  fndef_ok = false;
 	  if (c_parser_next_token_is_keyword (parser, RID_ASM))
@@ -1371,12 +1370,11 @@ c_parser_declaration_or_fndef (c_parser 
 	  return;
 	}
       /* Function definition (nested or otherwise).  */
       if (nested)
 	{
-	  if (pedantic)
-	    pedwarn ("%HISO C forbids nested functions", &here);
+	  pedwarn (OPT_pedantic, "%HISO C forbids nested functions", &here);
 	  c_push_function_context ();
 	}
       if (!start_function (specs, declarator, all_prefix_attrs))
 	{
 	  /* This can appear in many cases looking nothing like a
@@ -1766,12 +1764,13 @@ c_parser_enum_specifier (c_parser *parse
 	      seen_comma = true;
 	      c_parser_consume_token (parser);
 	    }
 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
 	    {
-	      if (seen_comma && pedantic && !flag_isoc99)
-		pedwarn ("%Hcomma at end of enumerator list", &comma_loc);
+	      if (seen_comma && !flag_isoc99)
+		pedwarn (OPT_pedantic, "%Hcomma at end of enumerator list", 
+			 &comma_loc);
 	      c_parser_consume_token (parser);
 	      break;
 	    }
 	  if (!seen_comma)
 	    {
@@ -1798,11 +1797,12 @@ c_parser_enum_specifier (c_parser *parse
   /* In ISO C, enumerated types can be referred to only if already
      defined.  */
   if (pedantic && !COMPLETE_TYPE_P (ret.spec))
     {
       gcc_assert (ident);
-      pedwarn ("%HISO C forbids forward references to %<enum%> types",
+      pedwarn (OPT_pedantic,
+	       "%HISO C forbids forward references to %<enum%> types",
 	       &ident_loc);
     }
   return ret;
 }
 
@@ -1923,13 +1923,13 @@ c_parser_struct_or_union_specifier (c_pa
 	{
 	  tree decls;
 	  /* Parse any stray semicolon.  */
 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
 	    {
-	      if (pedantic)
-		pedwarn ("%Hextra semicolon in struct or union specified",
-			 &c_parser_peek_token (parser)->location);
+	      pedwarn (OPT_pedantic, 
+		       "%Hextra semicolon in struct or union specified",
+		       &c_parser_peek_token (parser)->location);
 	      c_parser_consume_token (parser);
 	      continue;
 	    }
 	  /* Stop if at the end of the struct or union contents.  */
 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
@@ -1953,12 +1953,12 @@ c_parser_struct_or_union_specifier (c_pa
 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
 	    c_parser_consume_token (parser);
 	  else
 	    {
 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
-		pedwarn ("%Hno semicolon at end of struct or union",
-			 &c_parser_peek_token (parser)->location);
+		pedwarn0 ("%Hno semicolon at end of struct or union",
+			  &c_parser_peek_token (parser)->location);
 	      else
 		{
 		  c_parser_error (parser, "expected %<;%>");
 		  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
 		  break;
@@ -2045,13 +2045,13 @@ c_parser_struct_declaration (c_parser *p
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
       tree ret;
       if (!specs->type_seen_p)
 	{
-	  if (pedantic)
-	    pedwarn ("%HISO C forbids member declarations with no members",
-		     &decl_loc);
+	  pedwarn (OPT_pedantic, 
+		   "%HISO C forbids member declarations with no members",
+		   &decl_loc);
 	  shadow_tag_warned (specs, pedantic);
 	  ret = NULL_TREE;
 	}
       else
 	{
@@ -3100,12 +3100,12 @@ c_parser_braced_init (c_parser *parser, 
     push_init_level (0);
   else
     really_start_incremental_init (type);
   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
     {
-      if (pedantic)
-	pedwarn ("%HISO C forbids empty initializer braces", &brace_loc);
+      pedwarn (OPT_pedantic, "%HISO C forbids empty initializer braces",
+	       &brace_loc);
     }
   else
     {
       /* Parse a non-empty initializer list, possibly with a trailing
 	 comma.  */
@@ -3145,16 +3145,14 @@ c_parser_initelt (c_parser *parser)
   if (c_parser_next_token_is (parser, CPP_NAME)
       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
     {
       /* Old-style structure member designator.  */
       set_init_label (c_parser_peek_token (parser)->value);
-      if (pedantic)
-	{
-	  /* Use the colon as the error location.  */
-	  pedwarn ("%Hobsolete use of designated initializer with %<:%>",
-		   &c_parser_peek_2nd_token (parser)->location);
-	}
+      /* Use the colon as the error location.  */
+      pedwarn (OPT_pedantic, 
+	       "%Hobsolete use of designated initializer with %<:%>",
+	       &c_parser_peek_2nd_token (parser)->location);
       c_parser_consume_token (parser);
       c_parser_consume_token (parser);
     }
   else
     {
@@ -3278,12 +3276,13 @@ c_parser_initelt (c_parser *parser)
 		second = NULL_TREE;
 	      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
 		{
 		  c_parser_consume_token (parser);
 		  set_init_index (first, second);
-		  if (pedantic && second)
-		    pedwarn ("%HISO C forbids specifying range of "
+		  if (second)
+		    pedwarn (OPT_pedantic, 
+			     "%HISO C forbids specifying range of "
 			     "elements to initialize", &ellipsis_loc);
 		}
 	      else
 		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
 					   "expected %<]%>");
@@ -3291,23 +3290,24 @@ c_parser_initelt (c_parser *parser)
 	}
       if (des_seen >= 1)
 	{
 	  if (c_parser_next_token_is (parser, CPP_EQ))
 	    {
-	      if (pedantic && !flag_isoc99)
-		pedwarn ("%HISO C90 forbids specifying subobject "
+	      if (!flag_isoc99)
+		pedwarn (OPT_pedantic, 
+			 "%HISO C90 forbids specifying subobject "
 			 "to initialize", &des_loc);
 	      c_parser_consume_token (parser);
 	    }
 	  else
 	    {
 	      if (des_seen == 1)
 		{
-		  if (pedantic)
-		    pedwarn ("%Hobsolete use of designated initializer "
-			     "without %<=%>",
-			     &c_parser_peek_token (parser)->location);
+		  pedwarn (OPT_pedantic, 
+			   "%Hobsolete use of designated initializer "
+			   "without %<=%>",
+			   &c_parser_peek_token (parser)->location);
 		}
 	      else
 		{
 		  struct c_expr init;
 		  init.value = error_mark_node;
@@ -3454,12 +3454,11 @@ c_parser_compound_statement_nostart (c_p
 	      else
 		break;
 	    }
 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
 	}
-      if (pedantic)
-	pedwarn ("%HISO C forbids label declarations", &err_loc);
+      pedwarn (OPT_pedantic, "%HISO C forbids label declarations", &err_loc);
     }
   /* We must now have at least one statement, label or declaration.  */
   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
     {
       c_parser_error (parser, "expected declaration or statement");
@@ -3485,14 +3484,15 @@ c_parser_compound_statement_nostart (c_p
       else if (!last_label
 	       && c_parser_next_token_starts_declspecs (parser))
 	{
 	  last_label = false;
 	  c_parser_declaration_or_fndef (parser, true, true, true, true);
-	  if (last_stmt
-	      && ((pedantic && !flag_isoc99)
-		  || warn_declaration_after_statement))
-	    pedwarn_c90 ("%HISO C90 forbids mixed declarations and code",
+	  if (last_stmt)
+	    pedwarn_c90 ((pedantic && !flag_isoc99)
+			 ? OPT_pedantic
+			 : OPT_Wdeclaration_after_statement,
+			 "%HISO C90 forbids mixed declarations and code",
 			 &loc);
 	  last_stmt = false;
 	}
       else if (!last_label
 	       && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
@@ -3513,14 +3513,15 @@ c_parser_compound_statement_nostart (c_p
 	      last_label = false;
 	      c_parser_declaration_or_fndef (parser, true, true, true, true);
 	      /* Following the old parser, __extension__ does not
 		 disable this diagnostic.  */
 	      restore_extension_diagnostics (ext);
-	      if (last_stmt
-		  && ((pedantic && !flag_isoc99)
-		      || warn_declaration_after_statement))
-		pedwarn_c90 ("%HISO C90 forbids mixed declarations and code",
+	      if (last_stmt)
+		pedwarn_c90 ((pedantic && !flag_isoc99)
+			     ? OPT_pedantic
+			     : OPT_Wdeclaration_after_statement,
+			     "%HISO C90 forbids mixed declarations and code",
 			     &loc);
 	      last_stmt = false;
 	    }
 	  else
 	    goto statement;
@@ -4523,13 +4524,13 @@ c_parser_conditional_expression (c_parse
     return cond;
   cond = default_function_array_conversion (cond);
   c_parser_consume_token (parser);
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
-      if (pedantic)
-	pedwarn ("%HISO C forbids omitting the middle term of a ?: expression",
-		 &c_parser_peek_token (parser)->location);
+      pedwarn (OPT_pedantic, 
+	       "%HISO C forbids omitting the middle term of a ?: expression",
+	       &c_parser_peek_token (parser)->location);
       /* Make sure first operand is calculated only once.  */
       exp1.value = save_expr (default_conversion (cond.value));
       cond.value = c_objc_common_truthvalue_conversion (exp1.value);
       skip_evaluation += cond.value == truthvalue_true_node;
     }
@@ -5227,13 +5228,12 @@ c_parser_postfix_expression (c_parser *p
 	    }
 	  stmt = c_begin_stmt_expr ();
 	  c_parser_compound_statement_nostart (parser);
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
 				     "expected %<)%>");
-	  if (pedantic)
-	    pedwarn ("%HISO C forbids braced-groups within expressions",
-		     &here);
+	  pedwarn (OPT_pedantic, 
+		   "%HISO C forbids braced-groups within expressions", &here);
 	  expr.value = c_finish_stmt_expr (stmt);
 	  expr.original_code = ERROR_MARK;
 	}
       else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
 	{
@@ -5589,12 +5589,13 @@ c_parser_postfix_expression_after_paren_
     }
   init = c_parser_braced_init (parser, type, false);
   finish_init ();
   maybe_warn_string_init (type, init);
 
-  if (pedantic && !flag_isoc99)
-    pedwarn ("%HISO C90 forbids compound literals", &start_loc);
+  if (!flag_isoc99)
+    pedwarn (OPT_pedantic, "%HISO C90 forbids compound literals", 
+	     &start_loc);
   expr.value = build_compound_literal (type, init.value);
   expr.original_code = ERROR_MARK;
   return c_parser_postfix_expression_after_primary (parser, expr);
 }
 
@@ -5889,13 +5890,13 @@ c_parser_objc_class_instance_variables (
     {
       tree decls;
       /* Parse any stray semicolon.  */
       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
 	{
-	  if (pedantic)
-	    pedwarn ("%Hextra semicolon in struct or union specified",
-		     &c_parser_peek_token (parser)->location);
+	  pedwarn (OPT_pedantic, 
+		   "%Hextra semicolon in struct or union specified",
+		   &c_parser_peek_token (parser)->location);
 	  c_parser_consume_token (parser);
 	  continue;
 	}
       /* Stop if at the end of the instance variables.  */
       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
@@ -6107,13 +6108,13 @@ c_parser_objc_method_definition (c_parse
   parser->objc_pq_context = true;
   decl = c_parser_objc_method_decl (parser);
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
       c_parser_consume_token (parser);
-      if (pedantic)
-	pedwarn ("%Hextra semicolon in method definition specified",
-		 &c_parser_peek_token (parser)->location);
+      pedwarn (OPT_pedantic, 
+	       "%Hextra semicolon in method definition specified",
+	       &c_parser_peek_token (parser)->location);
     }
   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
     {
       c_parser_error (parser, "expected %<{%>");
       return;
@@ -6145,14 +6146,13 @@ c_parser_objc_methodprotolist (c_parser 
     {
       /* The list is terminated by @end.  */
       switch (c_parser_peek_token (parser)->type)
 	{
 	case CPP_SEMICOLON:
-	  if (pedantic)
-	    pedwarn ("%HISO C does not allow extra %<;%> "
-		     "outside of a function",
-		     &c_parser_peek_token (parser)->location);
+	  pedwarn (OPT_pedantic, "%HISO C does not allow extra %<;%> "
+		   "outside of a function",
+		   &c_parser_peek_token (parser)->location);
 	  c_parser_consume_token (parser);
 	  break;
 	case CPP_PLUS:
 	case CPP_MINUS:
 	  c_parser_objc_methodproto (parser);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]