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; } }