Patchwork Make many more options use CPP()

login
register
mail settings
Submitter Manuel López-Ibáñez
Date Aug. 30, 2014, 12:03 p.m.
Message ID <CAESRpQCVM3CvOeiZvWPGLN5tLxX_UWUWqP5_jJB2ps5xttJzsg@mail.gmail.com>
Download mbox | patch
Permalink /patch/384472/
State New
Headers show

Comments

Manuel López-Ibáñez - Aug. 30, 2014, 12:03 p.m.
This converts almost all remaining CPP options to use CPP() in the
*.opt files. Following your comment here
(https://gcc.gnu.org/ml/gcc-patches/2014-08/msg02499.html) several
options now use explicit Init().

The only test I needed to tweak was gcc.dg/cpp/endif-pedantic2.c,
which tests that "-Wno-endif-labels -pedantic-errors" gives errors for
-Wendif-labels warnings. This might be the original intention
(https://gcc.gnu.org/ml/gcc-patches/2002-03/msg01732.html) but it is
at odds with how other -Wno-* flags work.

The current behavior enforced by the automatic machinery is that more
specific options have priority over more general options,
independently of the order. Although this is not documented in the
manual, it has been the consensus of several recent discussions (and
not so recent ones https://gcc.gnu.org/ml/gcc/2007-05/msg00720.html).
It would be a burden to special-case -Wno-endif-labels just for
keeping backwards compatibility. The affected users are likely very
few (if any): those that expect "-Wno-endif-labels -pedantic" to give
-Wendif-labels warnings. The effect on those users would be that they
won't get the warnings they expect until they remove -Wno-endif-labels
or append an explicit -Wendif-labels.

The two remaining options are a bit problematic:

1)  -Wall enables warn_sign_change, which does not have a -W* flag. I
could simply add one but perhaps it would be better under an already
existing flag.
2) -Wnormalized requires a bit more of special handling. I will try to
use the Enum() facility in the *.opt file if possible.


Bootstrapped and regression tested on x86_64-linux-gnu.

OK?

gcc/ChangeLog:

2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    * doc/options.texi: Document that Var and Init are required if CPP
    is given.
    * optc-gen.awk: Require Var and Init if CPP is given.
    * common.opt (Wpedantic): Use Init.

libcpp/ChangeLog:

2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    * macro.c (replace_args): Use cpp_pedwarning, cpp_warning and
    CPP_W flags.
    * include/cpplib.h: Add CPP_W_C90_C99_COMPAT and CPP_W_PEDANTIC.
    * init.c (cpp_create_reader): Do not init to -1 here.
    * expr.c (num_binary_op): Use cpp_pedwarning.


gcc/c-family/ChangeLog:

2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    * c.opt (Wc90-c99-compat,Wc++-compat,Wcomment,Wendif-labels,
    Winvalid-pch,Wlong-long,Wmissing-include-dirs,Wmultichar,Wpedantic,
    (Wdate-time,Wtraditional,Wundef,Wvariadic-macros): Add CPP, Var
    and Init.
    * c-opts.c (c_common_handle_option): Do not handle here.
    (sanitize_cpp_opts): Likewise.
    * c-common.c (struct reason_option_codes_t): Handle
    CPP_W_C90_C99_COMPAT and CPP_W_PEDANTIC.


gcc/testsuite/ChangeLog:

2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    * gcc.dg/cpp/endif-pedantic2.c: More general options do not
    override specific ones, but specific ones do.
Joseph S. Myers - Sept. 3, 2014, 10:42 p.m.
On Sat, 30 Aug 2014, Manuel López-Ibáñez wrote:

> gcc/ChangeLog:
> 
> 2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>
> 
>     * doc/options.texi: Document that Var and Init are required if CPP
>     is given.
>     * optc-gen.awk: Require Var and Init if CPP is given.
>     * common.opt (Wpedantic): Use Init.
> 
> libcpp/ChangeLog:
> 
> 2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>
> 
>     * macro.c (replace_args): Use cpp_pedwarning, cpp_warning and
>     CPP_W flags.
>     * include/cpplib.h: Add CPP_W_C90_C99_COMPAT and CPP_W_PEDANTIC.
>     * init.c (cpp_create_reader): Do not init to -1 here.
>     * expr.c (num_binary_op): Use cpp_pedwarning.
> 
> 
> gcc/c-family/ChangeLog:
> 
> 2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>
> 
>     * c.opt (Wc90-c99-compat,Wc++-compat,Wcomment,Wendif-labels,
>     Winvalid-pch,Wlong-long,Wmissing-include-dirs,Wmultichar,Wpedantic,
>     (Wdate-time,Wtraditional,Wundef,Wvariadic-macros): Add CPP, Var
>     and Init.
>     * c-opts.c (c_common_handle_option): Do not handle here.
>     (sanitize_cpp_opts): Likewise.
>     * c-common.c (struct reason_option_codes_t): Handle
>     CPP_W_C90_C99_COMPAT and CPP_W_PEDANTIC.
> 
> 
> gcc/testsuite/ChangeLog:
> 
> 2014-08-30  Manuel López-Ibáñez  <manu@gcc.gnu.org>
> 
>     * gcc.dg/cpp/endif-pedantic2.c: More general options do not
>     override specific ones, but specific ones do.

OK.

Patch

Index: gcc/doc/options.texi
===================================================================
--- gcc/doc/options.texi	(revision 214735)
+++ gcc/doc/options.texi	(working copy)
@@ -483,8 +483,9 @@  The option is omitted from the producer
 Even if this is a target option, this option will not be recorded / compared
 to determine if a precompiled header file matches.
 
 @item CPP(@var{var})
 The state of this option should be kept in sync with the preprocessor
-option @var{var}.
+option @var{var}.  If this property is set, then properties @code{Var}
+and @code{Init} must be set as well.
 
 @end table
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 214735)
+++ gcc/c-family/c.opt	(working copy)
@@ -294,19 +294,19 @@  Warn about boolean expression compared w
 Wbuiltin-macro-redefined
 C ObjC C++ ObjC++ CPP(warn_builtin_macro_redefined) Var(cpp_warn_builtin_macro_redefined) Init(1) Warning
 Warn when a built-in preprocessor macro is undefined or redefined
 
 Wc90-c99-compat
-C ObjC Var(warn_c90_c99_compat) Init(-1) Warning
+C ObjC CPP(cpp_warn_c90_c99_compat) Var(warn_c90_c99_compat) Init(-1) Warning
 Warn about features not present in ISO C90, but present in ISO C99
 
 Wc99-c11-compat
 C ObjC Var(warn_c99_c11_compat) Init(-1) Warning
 Warn about features not present in ISO C99, but present in ISO C11
 
 Wc++-compat
-C ObjC Var(warn_cxx_compat) Warning
+C ObjC Var(warn_cxx_compat) CPP(warn_cxx_operator_names) Init(0) Warning
 Warn about C constructs that are not in the common subset of C and C++
 
 Wc++0x-compat
 C++ ObjC++ Var(warn_cxx0x_compat) Warning LangEnabledBy(C++ ObjC++,Wall)
 Deprecated in favor of -Wc++11-compat
@@ -326,11 +326,11 @@  Warn about subscripts whose type is \"ch
 Wclobbered
 C ObjC C++ ObjC++ Var(warn_clobbered) Warning EnabledBy(Wextra)
 Warn about variables that might be changed by \"longjmp\" or \"vfork\"
 
 Wcomment
-C ObjC C++ ObjC++ CPP(warn_comments) Var(cpp_warn_comment) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
+C ObjC C++ ObjC++ CPP(warn_comments) Var(cpp_warn_comment) Init(0) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
 Warn about possibly nested block comments, and C++ comments spanning more than one physical line
 
 Wcomments
 C ObjC C++ ObjC++ Warning Alias(Wcomment)
 Synonym for -Wcomment
@@ -390,11 +390,11 @@  Warn about violations of Effective C++ s
 Wempty-body
 C ObjC C++ ObjC++ Var(warn_empty_body) Warning EnabledBy(Wextra)
 Warn about an empty body in an if or else statement
 
 Wendif-labels
-C ObjC C++ ObjC++ CPP(warn_endif_labels) Var(cpp_warn_endif_labels) Init(1) Warning
+C ObjC C++ ObjC++ CPP(warn_endif_labels) Var(cpp_warn_endif_labels) Init(1) Warning LangEnabledBy(C ObjC C++ ObjC++,Wpedantic)
 Warn about stray tokens after #elif and #endif
 
 Wenum-compare
 C ObjC C++ ObjC++ Var(warn_enum_compare) Init(-1) Warning LangEnabledBy(C ObjC,Wall)
 Warn about comparison of different enum types
@@ -501,11 +501,11 @@  Warn when there is a cast to a pointer f
 Winvalid-offsetof
 C++ ObjC++ Var(warn_invalid_offsetof) Init(1) Warning
 Warn about invalid uses of the \"offsetof\" macro
 
 Winvalid-pch
-C ObjC C++ ObjC++ CPP(warn_invalid_pch) Var(cpp_warn_invalid_pch) Warning
+C ObjC C++ ObjC++ CPP(warn_invalid_pch) Var(cpp_warn_invalid_pch) Init(0) Warning
 Warn about PCH files that are found but not used
 
 Wjump-misses-init
 C ObjC Var(warn_jump_misses_init) Warning LangEnabledby(C ObjC,Wc++-compat)
 Warn when a jump misses a variable initialization
@@ -521,11 +521,11 @@  Warn when a logical operator is suspicio
 Wlogical-not-parentheses
 C ObjC C++ ObjC++ Var(warn_logical_not_paren) Warning
 Warn when logical not is used on the left hand side operand of a comparison
 
 Wlong-long
-C ObjC C++ ObjC++ Var(warn_long_long) Init(-1) Warning
+C ObjC C++ ObjC++ CPP(cpp_warn_long_long) Var(warn_long_long) Init(-1) Warning LangEnabledBy(C ObjC,Wc90-c99-compat)
 Do not warn about using \"long long\" when -pedantic
 
 Wmain
 C ObjC C++ ObjC++ Var(warn_main) Init(-1) Warning LangEnabledBy(C ObjC,Wall, 2, 0)
 Warn about suspicious declarations of \"main\"
@@ -581,11 +581,11 @@  Warn about switches with boolean control
 Wmissing-format-attribute
 C ObjC C++ ObjC++ Alias(Wsuggest-attribute=format)
 ;
 
 Wmissing-include-dirs
-C ObjC C++ ObjC++ CPP(warn_missing_include_dirs) Var(cpp_warn_missing_include_dirs) Warning
+C ObjC C++ ObjC++ CPP(warn_missing_include_dirs) Var(cpp_warn_missing_include_dirs) Init(0) Warning
 Warn about user-specified include directories that do not exist
 
 Wmissing-parameter-type
 C ObjC Var(warn_missing_parameter_type) Warning EnabledBy(Wextra)
 Warn about function parameters declared without a type specifier in K&R-style functions
@@ -596,11 +596,11 @@  Warn about global functions without prot
 
 Wmudflap
 C ObjC C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
 
 Wmultichar
-C ObjC C++ ObjC++ CPP(warn_multichar) Var(cpp_warn_multichar) Warning
+C ObjC C++ ObjC++ CPP(warn_multichar) Var(cpp_warn_multichar) Init(0) Warning
 Warn about use of multi-character character constants
 
 Wnarrowing
 C ObjC C++ ObjC++ Warning Var(warn_narrowing) Init(-1) LangEnabledBy(C++ ObjC++,Wall)
 Warn about narrowing conversions within { } that are ill-formed in C++11
@@ -672,11 +672,11 @@  Warn about packed bit-fields whose offse
 Wparentheses
 C ObjC C++ ObjC++ Var(warn_parentheses) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
 Warn about possibly missing parentheses
 
 Wpedantic
-C ObjC C++ ObjC++ Warning
+C ObjC C++ ObjC++ CPP(cpp_pedantic) Warning
 ; Documented in common.opt
 
 Wpmf-conversions
 C++ ObjC++ Var(warn_pmf2ptr) Init(1) Warning
 Warn when converting the type of pointers to member functions
@@ -700,11 +700,11 @@  Warn when a pointer is cast to an intege
 Wpragmas
 C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning
 Warn about misuses of pragmas
 
 Wdate-time
-C ObjC C++ ObjC++ CPP(warn_date_time) Var(cpp_warn_date_time) Warning
+C ObjC C++ ObjC++ CPP(warn_date_time) Var(cpp_warn_date_time) Init(0) Warning
 Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage
 
 Wproperty-assign-default
 ObjC ObjC++ Var(warn_property_assign_default) Init(1) Warning
 Warn if a property for an Objective-C object has no assign semantics specified
@@ -784,11 +784,11 @@  Deprecated.  This switch has no effect
 Wsystem-headers
 C ObjC C++ ObjC++ Warning
 ; Documented in common.opt
 
 Wtraditional
-C ObjC Var(warn_traditional) Warning
+C ObjC CPP(cpp_warn_traditional) Var(warn_traditional) Init(0) Warning
 Warn about features not present in traditional C
 
 Wtraditional-conversion
 C ObjC Var(warn_traditional_conversion) Warning
 Warn of prototypes causing type conversions different from what would happen in the absence of prototype
@@ -800,11 +800,11 @@  Warn if trigraphs are encountered that m
 Wundeclared-selector
 ObjC ObjC++ Var(warn_undeclared_selector) Warning
 Warn about @selector()s without previously declared methods
 
 Wundef
-C ObjC C++ ObjC++ CPP(warn_undef) Var(cpp_warn_undef) Warning
+C ObjC C++ ObjC++ CPP(warn_undef) Var(cpp_warn_undef) Init(0) Warning
 Warn if an undefined macro is used in an #if directive
 
 Wuninitialized
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ;
@@ -836,11 +836,11 @@  Warn about macros defined in the main fi
 Wunused-result
 C ObjC C++ ObjC++ Var(warn_unused_result) Init(1) Warning
 Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value
 
 Wvariadic-macros
-C ObjC C++ ObjC++ CPP(warn_variadic_macros) Var(cpp_warn_variadic_macros) Warning LangEnabledBy(C ObjC C++ ObjC++,Wpedantic)
+C ObjC C++ ObjC++ CPP(warn_variadic_macros) Var(cpp_warn_variadic_macros) Init(0) Warning LangEnabledBy(C ObjC C++ ObjC++,Wpedantic)
 Warn about using variadic macros
 
 Wvariadic-macros
 LangEnabledBy(C ObjC C++ ObjC++,Wtraditional)
 ;
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 214735)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -382,18 +382,10 @@  c_common_handle_option (size_t scode, co
       /* ??? Don't add new options here. Use LangEnabledBy in c.opt.  */
 
       cpp_opts->warn_num_sign_change = value;
       break;
 
-    case OPT_Wc___compat:
-      cpp_opts->warn_cxx_operator_names = value;
-      break;
-
-    case OPT_Wlong_long:
-      cpp_opts->cpp_warn_long_long = value;
-      break;
-
     case OPT_Wnormalized_:
       /* FIXME: Move all this to c.opt.  */
       if (kind == DK_ERROR)
 	{
 	  gcc_assert (!arg);
@@ -413,14 +405,10 @@  c_common_handle_option (size_t scode, co
 	  else
 	    error ("argument %qs to %<-Wnormalized%> not recognized", arg);
 	  break;
 	}
 
-    case OPT_Wtraditional:
-      cpp_opts->cpp_warn_traditional = value;
-      break;
-
     case OPT_Wunknown_pragmas:
       /* Set to greater than 1, so that even unknown pragmas in
 	 system headers will be warned about.  */
       /* ??? There is no way to handle this automatically for now.  */
       warn_unknown_pragmas = value * 2;
@@ -632,18 +620,10 @@  c_common_handle_option (size_t scode, co
 	out_fname = arg;
       else
 	error ("output filename specified twice");
       break;
 
-      /* We need to handle the -Wpedantic switch here, rather than in
-	 c_common_post_options, so that a subsequent -Wno-endif-labels
-	 is not overridden.  */
-    case OPT_Wpedantic:
-      cpp_opts->cpp_pedantic = 1;
-      cpp_opts->warn_endif_labels = 1;
-      break;
-
     case OPT_print_objc_runtime_info:
       print_struct_values = 1;
       break;
 
     case OPT_remap:
@@ -1267,24 +1247,23 @@  sanitize_cpp_opts (void)
   else if (cpp_opts->deps.missing_files)
     error ("-MG may only be used with -M or -MM");
 
   cpp_opts->unsigned_char = !flag_signed_char;
   cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
-  cpp_opts->cpp_warn_c90_c99_compat = warn_c90_c99_compat;
 
   /* Wlong-long is disabled by default. It is enabled by:
       [-Wpedantic | -Wtraditional] -std=[gnu|c]++98 ; or
-      [-Wpedantic | -Wtraditional] -std=non-c99 ; or
-      -Wc90-c99-compat, if specified.
+      [-Wpedantic | -Wtraditional] -std=non-c99 
 
-      Either -Wlong-long or -Wno-long-long override any other settings.  */
-  if (warn_long_long == -1 && warn_c90_c99_compat != -1)
-    warn_long_long = warn_c90_c99_compat;
-  else if (warn_long_long == -1)
-    warn_long_long = ((pedantic || warn_traditional)
-		      && (c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99));
-  cpp_opts->cpp_warn_long_long = warn_long_long;
+      Either -Wlong-long or -Wno-long-long override any other settings.
+      ??? These conditions should be handled in c.opt.  */
+  if (warn_long_long == -1)
+    {
+      warn_long_long = ((pedantic || warn_traditional)
+			&& (c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99));
+      cpp_opts->cpp_warn_long_long = warn_long_long;
+    }
 
   /* If we're generating preprocessor output, emit current directory
      if explicitly requested or if debugging information is enabled.
      ??? Maybe we should only do it for debugging formats that
      actually output the current directory?  */
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 214735)
+++ gcc/c-family/c-common.c	(working copy)
@@ -9673,10 +9673,11 @@  struct reason_option_codes_t
   const int option_code;	/* gcc option that controls this message.  */
 };
 
 static const struct reason_option_codes_t option_codes[] = {
   {CPP_W_BUILTIN_MACRO_REDEFINED,	OPT_Wbuiltin_macro_redefined},
+  {CPP_W_C90_C99_COMPAT,                OPT_Wc90_c99_compat},
   {CPP_W_COMMENTS,			OPT_Wcomment},
   {CPP_W_CXX_OPERATOR_NAMES,		OPT_Wc___compat},
   {CPP_W_DATE_TIME,			OPT_Wdate_time},
   {CPP_W_DEPRECATED,			OPT_Wdeprecated},
   {CPP_W_ENDIF_LABELS,			OPT_Wendif_labels},
@@ -9684,10 +9685,11 @@  static const struct reason_option_codes_
   {CPP_W_LITERAL_SUFFIX,		OPT_Wliteral_suffix},
   {CPP_W_LONG_LONG,			OPT_Wlong_long},
   {CPP_W_MISSING_INCLUDE_DIRS,          OPT_Wmissing_include_dirs},
   {CPP_W_MULTICHAR,			OPT_Wmultichar},
   {CPP_W_NORMALIZE,			OPT_Wnormalized_},
+  {CPP_W_PEDANTIC,                      OPT_Wpedantic},
   {CPP_W_TRADITIONAL,			OPT_Wtraditional},
   {CPP_W_TRIGRAPHS,			OPT_Wtrigraphs},
   {CPP_W_UNDEF,				OPT_Wundef},
   {CPP_W_UNUSED_MACROS,			OPT_Wunused_macros},
   {CPP_W_VARIADIC_MACROS,		OPT_Wvariadic_macros},
Index: gcc/testsuite/gcc.dg/cpp/endif-pedantic2.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/endif-pedantic2.c	(revision 214735)
+++ gcc/testsuite/gcc.dg/cpp/endif-pedantic2.c	(working copy)
@@ -1,9 +1,9 @@ 
 /* Copyright (C) 2002 Free Software Foundation, Inc.  */
 
 /* { dg-do preprocess } */
-/* { dg-options "-Wno-endif-labels -pedantic-errors" } */
+/* { dg-options "-Wno-endif-labels -pedantic-errors -Wendif-labels" } */
 
 /* Tests combinations of -pedantic and -Wno-endif-labels; see extratokens2.c
    for more general tests.  */
 
 /* Source: Phil Edwards, 25 Mar 2002.  Copied from endif-pedantic1.c and
Index: gcc/optc-gen.awk
===================================================================
--- gcc/optc-gen.awk	(revision 214735)
+++ gcc/optc-gen.awk	(working copy)
@@ -498,15 +498,24 @@  for (i = 0; i < n_opts; i++) {
     while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
         i++;
     }
 
     cpp_option = nth_arg(0, opt_args("CPP", flags[i]));
-    opt_var_name = var_name(flags[i]);
-    if (cpp_option != "" && opt_var_name != "") {
-        print "    case " opt_enum(opts[i]) ":"
-        print "      cpp_opts->" cpp_option " = opts->x_" opt_var_name ";"
-        print "      break;"
+    if (cpp_option != "") {
+        opt_var_name = var_name(flags[i]);
+        init = opt_args("Init", flags[i])
+        if (opt_var_name != "" && init != "") {
+            print "    case " opt_enum(opts[i]) ":"
+            print "      cpp_opts->" cpp_option " = opts->x_" opt_var_name ";"
+            print "      break;"
+        } else if (opt_var_name == "" && init == "") {
+            print "#error CPP() requires setting Init() and Var() for " opts[i]
+        } else if (opt_var_name != "") {
+            print "#error CPP() requires setting Init() for " opts[i]
+        } else {
+            print "#error CPP() requires setting Var() for " opts[i]
+        }
     }
 }
 print "    default:    "
 print "      break;    "
 print "    }           "
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 214735)
+++ gcc/common.opt	(working copy)
@@ -602,11 +602,11 @@  Warn when the packed attribute has no ef
 Wpadded
 Common Var(warn_padded) Warning
 Warn when padding is required to align structure members
 
 Wpedantic
-Common Var(pedantic) Warning
+Common Var(pedantic) Init(0) Warning
 Issue warnings needed for strict compliance to the standard
 
 Wreturn-local-addr
 Common Var(warn_return_local_addr) Init(1) Warning
 Warn about returning a pointer/reference to a local or temporary variable.
Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c	(revision 214735)
+++ libcpp/macro.c	(working copy)
@@ -1774,39 +1774,36 @@  replace_args (cpp_reader *pfile, cpp_has
 	     token should be flagged PASTE_LEFT.  */
 	  if (src->flags & PASTE_LEFT)
 	    paste_flag =
 	      (const cpp_token **) tokens_buff_last_token_ptr (buff);
 	}
-      else if (CPP_PEDANTIC (pfile) && ! macro->syshdr
-	       && ! CPP_OPTION (pfile, c99)
-	       && ! cpp_in_system_header (pfile))
+      else if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99)
+	       && ! macro->syshdr && ! cpp_in_system_header (pfile))
 	{
 	  if (CPP_OPTION (pfile, cplusplus))
-	    cpp_error (pfile, CPP_DL_PEDWARN,
-		       "invoking macro %s argument %d: "
-		       "empty macro arguments are undefined"
-		       " in ISO C++98",
-		       NODE_NAME (node),
-		       src->val.macro_arg.arg_no);
+	    cpp_pedwarning (pfile, CPP_W_PEDANTIC,
+			    "invoking macro %s argument %d: "
+			    "empty macro arguments are undefined"
+			    " in ISO C++98",
+			    NODE_NAME (node), src->val.macro_arg.arg_no);
 	  else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat))
-	    cpp_error (pfile, CPP_DL_PEDWARN,
-		       "invoking macro %s argument %d: "
-		       "empty macro arguments are undefined"
-		       " in ISO C90",
-		       NODE_NAME (node),
-		       src->val.macro_arg.arg_no);
+	    cpp_pedwarning (pfile, 
+			    CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
+			    ? CPP_W_C90_C99_COMPAT : CPP_W_PEDANTIC,
+			    "invoking macro %s argument %d: "
+			    "empty macro arguments are undefined"
+			    " in ISO C90",
+			    NODE_NAME (node), src->val.macro_arg.arg_no);
 	}
       else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
-	       && ! macro->syshdr
-	       && ! cpp_in_system_header (pfile)
-	       && ! CPP_OPTION (pfile, cplusplus))
-	cpp_error (pfile, CPP_DL_WARNING,
-		   "invoking macro %s argument %d: "
-		   "empty macro arguments are undefined"
-		   " in ISO C90",
-		   NODE_NAME (node),
-		   src->val.macro_arg.arg_no);
+	       && ! CPP_OPTION (pfile, cplusplus)
+	       && ! macro->syshdr && ! cpp_in_system_header (pfile))
+	cpp_warning (pfile, CPP_W_C90_C99_COMPAT,
+		     "invoking macro %s argument %d: "
+		     "empty macro arguments are undefined"
+		     " in ISO C90",
+		     NODE_NAME (node), src->val.macro_arg.arg_no);
 
       /* Avoid paste on RHS (even case count == 0).  */
       if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT))
 	{
 	  const cpp_token *t = &pfile->avoid_paste;
Index: libcpp/include/cpplib.h
===================================================================
--- libcpp/include/cpplib.h	(revision 214735)
+++ libcpp/include/cpplib.h	(working copy)
@@ -937,11 +937,13 @@  enum {
   CPP_W_CXX_OPERATOR_NAMES,
   CPP_W_NORMALIZE,
   CPP_W_INVALID_PCH,
   CPP_W_WARNING_DIRECTIVE,
   CPP_W_LITERAL_SUFFIX,
-  CPP_W_DATE_TIME
+  CPP_W_DATE_TIME,
+  CPP_W_PEDANTIC,
+  CPP_W_C90_C99_COMPAT
 };
 
 /* Output a diagnostic of some kind.  */
 extern bool cpp_error (cpp_reader *, int, const char *msgid, ...)
   ATTRIBUTE_PRINTF_3;
Index: libcpp/init.c
===================================================================
--- libcpp/init.c	(revision 214735)
+++ libcpp/init.c	(working copy)
@@ -183,10 +183,11 @@  cpp_create_reader (enum c_lang lang, cpp
   CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1;
   CPP_OPTION (pfile, tabstop) = 8;
   CPP_OPTION (pfile, operator_names) = 1;
   CPP_OPTION (pfile, warn_trigraphs) = 2;
   CPP_OPTION (pfile, warn_endif_labels) = 1;
+  CPP_OPTION (pfile, cpp_warn_c90_c99_compat) = -1;
   CPP_OPTION (pfile, cpp_warn_deprecated) = 1;
   CPP_OPTION (pfile, cpp_warn_long_long) = 0;
   CPP_OPTION (pfile, dollars_in_ident) = 1;
   CPP_OPTION (pfile, warn_dollars) = 1;
   CPP_OPTION (pfile, warn_variadic_macros) = 1;
Index: libcpp/expr.c
===================================================================
--- libcpp/expr.c	(revision 214735)
+++ libcpp/expr.c	(working copy)
@@ -1878,12 +1878,12 @@  num_binary_op (cpp_reader *pfile, cpp_nu
 
       /* Comma.  */
     default: /* case CPP_COMMA: */
       if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99)
 				   || !pfile->state.skip_eval))
-	cpp_error (pfile, CPP_DL_PEDWARN,
-		   "comma operator in operand of #if");
+	cpp_pedwarning (pfile, CPP_W_PEDANTIC,
+			"comma operator in operand of #if");
       lhs = rhs;
       break;
     }
 
   return lhs;