Hi,

The problem here is that builtin macros are marked with NO_WARN flag
depending on the value of Wbuiltin-macro-redefined, but this only
happens during libcpp initialization, so it doesn't work for #pragmas.
It neither works when using CPP(), since the default in the c.opt file
is set before libcpp initialization, overriding the default of libcpp.

The problem with #pragma is fixed in this patch by making NO_WARN
independent of the value of Wbuiltin-macro-redefined.

The problem with overriding the default in libcpp is fixed by setting
Init(1) in c.opt to match the default. However, it is too easy to
forget the Init(). It would be better if no Init() meant "use the
default of libcpp". This would require calling another generated
function just after initializing cpp_opts to set the defaults in
global_opts. Would that be ok? Or should I just set Init() explicitly
for every CPP()?

In any case, bootstrapped & regression tested x86_64-linux-gnu.

libcpp/ChangeLog:

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

    * macro.c (warn_of_redefinition): Suppress warnings for builtins
    that lack the NODE_WARN flag, unless Wbuiltin-macro-redefined.
    (_cpp_create_definition): Use Wbuiltin-macro-redefined for
    builtins that lack the NODE_WARN flag.
    * directives.c (do_undef): Likewise.
    * init.c (cpp_init_special_builtins): Do not change flags
    depending on Wbuiltin-macro-redefined.


gcc/c-family/ChangeLog:

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

    * c.opt (Wbuiltin-macro-redefined): Use CPP, Var and Init.
    * c-opts.c (c_common_handle_option): Do not handle here.
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt  (revision 214396)
+++ gcc/c-family/c.opt  (working copy)
@@ -290,11 +290,11 @@ Warn about casting functions to incompat
 Wbool-compare
 C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ 
ObjC++,Wall)
 Warn about boolean expression compared with an integer value different from 
true/false
 
 Wbuiltin-macro-redefined
-C ObjC C++ ObjC++ Warning
+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
 Warn about features not present in ISO C90, but present in ISO C99
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c       (revision 214396)
+++ gcc/c-family/c-opts.c       (working copy)
@@ -383,14 +383,10 @@ c_common_handle_option (size_t scode, co
 
       cpp_opts->warn_trigraphs = value;
       cpp_opts->warn_num_sign_change = value;
       break;
 
-    case OPT_Wbuiltin_macro_redefined:
-      cpp_opts->warn_builtin_macro_redefined = value;
-      break;
-
     case OPT_Wc___compat:
       cpp_opts->warn_cxx_operator_names = value;
       break;
 
     case OPT_Wdeprecated:
Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c      (revision 214396)
+++ libcpp/macro.c      (working copy)
@@ -2697,17 +2697,16 @@ warn_of_redefinition (cpp_reader *pfile,
 
   /* Some redefinitions need to be warned about regardless.  */
   if (node->flags & NODE_WARN)
     return true;
 
-  /* Suppress warnings for builtins that lack the NODE_WARN flag.  */
-  if (node->flags & NODE_BUILTIN)
-    {
-      if (!pfile->cb.user_builtin_macro
-         || !pfile->cb.user_builtin_macro (pfile, node))
-       return false;
-    }
+  /* Suppress warnings for builtins that lack the NODE_WARN flag,
+     unless Wbuiltin-macro-redefined.  */
+  if (node->flags & NODE_BUILTIN
+      && (!pfile->cb.user_builtin_macro
+         || !pfile->cb.user_builtin_macro (pfile, node)))
+    return CPP_OPTION (pfile, warn_builtin_macro_redefined);
 
   /* Redefinitions of conditional (context-sensitive) macros, on
      the other hand, must be allowed silently.  */
   if (node->flags & NODE_CONDITIONAL)
     return false;
@@ -3179,18 +3178,18 @@ _cpp_create_definition (cpp_reader *pfil
       if (CPP_OPTION (pfile, warn_unused_macros))
        _cpp_warn_if_unused_macro (pfile, node, NULL);
 
       if (warn_of_redefinition (pfile, node, macro))
        {
-          const int reason = (node->flags & NODE_BUILTIN)
+          const int reason = ((node->flags & NODE_BUILTIN)
+                             && !(node->flags & NODE_WARN))
                              ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
-         bool warned;
 
-         warned = cpp_pedwarning_with_line (pfile, reason,
-                                            pfile->directive_line, 0,
-                                            "\"%s\" redefined",
-                                             NODE_NAME (node));
+         bool warned = 
+           cpp_pedwarning_with_line (pfile, reason,
+                                     pfile->directive_line, 0,
+                                     "\"%s\" redefined", NODE_NAME (node));
 
          if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
            cpp_error_with_line (pfile, CPP_DL_NOTE,
                                 node->value.macro->line, 0,
                         "this is the location of the previous definition");
Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c (revision 214396)
+++ libcpp/directives.c (working copy)
@@ -608,10 +608,15 @@ do_undef (cpp_reader *pfile)
       if (node->type == NT_MACRO)
        {
          if (node->flags & NODE_WARN)
            cpp_error (pfile, CPP_DL_WARNING,
                       "undefining \"%s\"", NODE_NAME (node));
+         else if ((node->flags & NODE_BUILTIN)
+                  && CPP_OPTION (pfile, warn_builtin_macro_redefined))
+           cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
+                                  pfile->directive_line, 0,
+                                  "undefining \"%s\"", NODE_NAME (node));
 
          if (CPP_OPTION (pfile, warn_unused_macros))
            _cpp_warn_if_unused_macro (pfile, node, NULL);
 
          _cpp_free_definition (node);
Index: libcpp/init.c
===================================================================
--- libcpp/init.c       (revision 214396)
+++ libcpp/init.c       (working copy)
@@ -465,12 +465,11 @@ cpp_init_special_builtins (cpp_reader *p
   for (b = builtin_array; b < builtin_array + n; b++)
     {
       cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
       hp->type = NT_MACRO;
       hp->flags |= NODE_BUILTIN;
-      if (b->always_warn_if_redefined
-          || CPP_OPTION (pfile, warn_builtin_macro_redefined))
+      if (b->always_warn_if_redefined)
        hp->flags |= NODE_WARN;
       hp->value.builtin = (enum cpp_builtin_type) b->value;
     }
 }
 

Reply via email to