[C] Encode CPP options in c.opt
diff mbox

Message ID CAESRpQCrPf2yFKu9TJL54wOMRpvaz-jnPD-KvGjiT71VqxwgqA@mail.gmail.com
State New
Headers show

Commit Message

Manuel López-Ibáñez Aug. 18, 2014, 10:23 p.m. UTC
The following patch adds a new CPP() to *.opt files that tells the
options machinery to keep in sync libcpp options and GCC options.

This will allow us to fix a lot of latent bugs where CPP warnings do
not follow the rules of other warnings options. In this patch, I only
deal with Wvariadic-macros, but I will convert others in follow-up
patches. (Nonetheless, help is very much appreciated. There are a lot
of them.)

For Wvariadic-macros, the c.opt and the documentation says it is
enabled by default, but this was not true. It is only enabled if
-Wpedantic or -Wtraditional are given. Worse, even if you give
-Wvariadic-macros, the warnings were not enabled. Of course, neither
#pragmas nor other nice things worked. All this is simply fixed by
using the common machinery and just taking care of keeping libcpp and
gcc in sync.

Bootstrapped and regression tested on x86_64-linux-gnu.

OK?

gcc/ChangeLog:

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

    PR c/60975
    PR c/53063
    * doc/options.texi (CPP): Document it.
    * doc/invoke.texi (Wvariadic-macros): Fix documentation.
    * optc-gen.awk: Handle CPP.
    * opth-gen.awk: Likewise.

gcc/c-family/ChangeLog:

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

    PR c/60975
    PR c/53063
    * c.opt (Wvariadic-macros): Use CPP and LangEnabledBy.
    * c-opts.c (c_common_handle_option): Call cpp_handle_option_auto.
    (c_common_post_options): Call init_global_opts_from_cpp.
    (sanitize_cpp_opts): Do not handle Wvariadic-macros here.

gcc/testsuite/ChangeLog:

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

    PR c/60975
    PR c/53063
    * gcc.dg/cpp/Wvariadic-1p.c: New test.

Comments

Joseph Myers Aug. 19, 2014, 10:09 p.m. UTC | #1
On Tue, 19 Aug 2014, Manuel López-Ibáñez wrote:

> The following patch adds a new CPP() to *.opt files that tells the
> options machinery to keep in sync libcpp options and GCC options.
> 
> This will allow us to fix a lot of latent bugs where CPP warnings do
> not follow the rules of other warnings options. In this patch, I only
> deal with Wvariadic-macros, but I will convert others in follow-up
> patches. (Nonetheless, help is very much appreciated. There are a lot
> of them.)
> 
> For Wvariadic-macros, the c.opt and the documentation says it is
> enabled by default, but this was not true. It is only enabled if
> -Wpedantic or -Wtraditional are given. Worse, even if you give
> -Wvariadic-macros, the warnings were not enabled. Of course, neither
> #pragmas nor other nice things worked. All this is simply fixed by
> using the common machinery and just taking care of keeping libcpp and
> gcc in sync.
> 
> Bootstrapped and regression tested on x86_64-linux-gnu.
> 
> OK?

OK.

Patch
diff mbox

Index: gcc/doc/options.texi
===================================================================
--- gcc/doc/options.texi	(revision 214063)
+++ gcc/doc/options.texi	(working copy)
@@ -480,6 +480,11 @@  The option is omitted from the producer
 @option{-grecord-gcc-switches}.
 
 @item PchIgnore
 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}.
+
 @end table
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 214063)
+++ gcc/doc/invoke.texi	(working copy)
@@ -5101,13 +5101,14 @@  Warn if @samp{long long} type is used.
 modes.  To inhibit the warning messages, use @option{-Wno-long-long}.
 
 @item -Wvariadic-macros
 @opindex Wvariadic-macros
 @opindex Wno-variadic-macros
-Warn if variadic macros are used in pedantic ISO C90 mode, or the GNU
-alternate syntax when in pedantic ISO C99 mode.  This is default.
-To inhibit the warning messages, use @option{-Wno-variadic-macros}.
+Warn if variadic macros are used in ISO C90 mode, or if the GNU
+alternate syntax is used in ISO C99 mode.  This is enabled by either
+@option{-Wpedantic} or @option{-Wtraditional}.  To inhibit the warning
+messages, use @option{-Wno-variadic-macros}.
 
 @item -Wvarargs
 @opindex Wvarargs
 @opindex Wno-varargs
 Warn upon questionable usage of the macros used to handle variable
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 214063)
+++ gcc/c-family/c.opt	(working copy)
@@ -828,13 +828,17 @@  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++ Var(cpp_warn_variadic_macros) Init(1) Warning
+C ObjC C++ ObjC++ CPP(warn_variadic_macros) Var(cpp_warn_variadic_macros) Warning LangEnabledBy(C ObjC C++ ObjC++,Wpedantic)
 Warn about using variadic macros
 
+Wvariadic-macros
+LangEnabledBy(C ObjC C++ ObjC++,Wtraditional)
+;
+
 Wvarargs
 C ObjC C++ ObjC++ Warning Var(warn_varargs) Init(1)
 Warn about questionable usage of the macros used to retrieve variable arguments
 
 Wvla
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 214063)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -792,11 +792,12 @@  c_common_handle_option (size_t scode, co
       break;
 
     default:
       gcc_unreachable ();
     }
-  
+
+  cpp_handle_option_auto (&global_options, scode, cpp_opts);
   return result;
 }
 
 /* Default implementation of TARGET_HANDLE_C_OPTION.  */
 
@@ -1028,10 +1029,11 @@  c_common_post_options (const char **pfil
 
   cb = cpp_get_callbacks (parse_in);
   cb->file_change = cb_file_change;
   cb->dir_change = cb_dir_change;
   cpp_post_options (parse_in);
+  init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in));
 
   input_location = UNKNOWN_LOCATION;
 
   *pfilename = this_input_filename
     = cpp_read_main_file (parse_in, in_fnames[0]);
@@ -1305,15 +1307,10 @@  sanitize_cpp_opts (void)
   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;
 
-  /* Similarly with -Wno-variadic-macros.  No check for c99 here, since
-     this also turns off warnings about GCCs extension.  */
-  cpp_opts->warn_variadic_macros
-    = cpp_warn_variadic_macros && (pedantic || warn_traditional);
-
   /* 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?  */
   if (flag_working_directory == -1)
Index: gcc/testsuite/gcc.dg/cpp/Wvariadic-1p.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/Wvariadic-1p.c	(revision 0)
+++ gcc/testsuite/gcc.dg/cpp/Wvariadic-1p.c	(revision 0)
@@ -0,0 +1,8 @@ 
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1990 " } */
+#pragma GCC diagnostic error "-Wpedantic"
+
+#define f(x,...)	/* { dg-error "variadic" } */
+#define g(x,y...)	/* { dg-error "variadic" } */
+int not_empty;
+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
Index: gcc/optc-gen.awk
===================================================================
--- gcc/optc-gen.awk	(revision 214063)
+++ gcc/optc-gen.awk	(working copy)
@@ -478,6 +478,57 @@  for (i = 0; i < n_langs; i++) {
     print "    }           "
     print "  return true;  "
     print "}               "
 }
 
+#Handle CPP()
+print "\n"
+print "#include " quote "cpplib.h" quote;
+print "void"
+print "cpp_handle_option_auto (const struct gcc_options * opts,                   "
+print "                        size_t scode, struct cpp_options * cpp_opts)"    
+print "{                                                                     "
+print "  enum opt_code code = (enum opt_code) scode;                         "
+print "                                                                      "
+print "  switch (code)                                                       "
+print "    {                                                                 "
+for (i = 0; i < n_opts; i++) {
+    # With identical flags, pick only the last one.  The
+    # earlier loop ensured that it has all flags merged,
+    # and a nonempty help text if one of the texts was nonempty.
+    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;"
+    }
+}
+print "    default:    "
+print "      break;    "
+print "    }           "
+print "}\n"
+print "void"
+print "init_global_opts_from_cpp(struct gcc_options * opts,                   "
+print "                         const struct cpp_options * cpp_opts)"    
+print "{                                                                     "
+for (i = 0; i < n_opts; i++) {
+    # With identical flags, pick only the last one.  The
+    # earlier loop ensured that it has all flags merged,
+    # and a nonempty help text if one of the texts was nonempty.
+    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 "  opts->x_" opt_var_name " = cpp_opts->" cpp_option ";"
+    }
 }
+print "}               "
+
+}
+
Index: gcc/opth-gen.awk
===================================================================
--- gcc/opth-gen.awk	(revision 214063)
+++ gcc/opth-gen.awk	(working copy)
@@ -313,10 +313,14 @@  for (i = 0; i < n_langs; i++) {
     print "                           unsigned int lang_mask, int kind,          "
     print "                           location_t loc,                            "
     print "                           const struct cl_option_handlers *handlers, "
     print "                           diagnostic_context *dc);                   "
 }
+print "void cpp_handle_option_auto (const struct gcc_options * opts, size_t scode,"
+print "                             struct cpp_options * cpp_opts);"
+print "void init_global_opts_from_cpp(struct gcc_options * opts,      "
+print "                               const struct cpp_options * cpp_opts);"    
 print "#endif";
 print "#endif";
 print "";
 
 for (i = 0; i < n_opts; i++) {