The argument to EnabledBy() must be one or more options with the Common flag, otherwise the setting is silently ignored. This patch detects this case when generating the options.c file and gives an appropriate error. There were two options suffering from this: -Wchkp is fixed by using LangEnabledBy instead, but -Wnull-dereference cannot be enabled by -Wall or -Wextra because it triggers false positives (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16351#c35)
Bootstrapped and regression tested on x86_64-linux-gnu. OK? gcc/ChangeLog: 2015-08-08 Manuel López-Ibáñez <m...@gcc.gnu.org> * doc/invoke.texi (Wnull-dereference): Move after Wnonnull. Not enabled by -Wall. * optc-gen.awk: Give nicer error messages. Detect if the argument of EnabledBy is not a Common option. * common.opt (Wnull-dereference): Not enabled by -Wall. * opt-functions.awk (lang_enabled_by): Nicer error messages. gcc/c-family/ChangeLog: 2015-08-08 Manuel López-Ibáñez <m...@gcc.gnu.org> * c.opt (Wchkp): Use LangEnabledBy instead of EnabledBy.
Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 226719) +++ gcc/doc/invoke.texi (working copy) @@ -3720,10 +3720,19 @@ Warn about passing a null pointer for ar requiring a non-null value by the @code{nonnull} function attribute. @option{-Wnonnull} is included in @option{-Wall} and @option{-Wformat}. It can be disabled with the @option{-Wno-nonnull} option. +@item -Wnull-dereference +@opindex Wnull-dereference +@opindex Wno-null-dereference +Warn if the compiler detects paths that trigger erroneous or +undefined behavior due to dereferencing a null pointer. This option +is only active when @option{-fdelete-null-pointer-checks} is active, +which is enabled by optimizations in most targets. The precision of +the warnings depends on the optimization options used. + @item -Winit-self @r{(C, C++, Objective-C and Objective-C++ only)} @opindex Winit-self @opindex Wno-init-self Warn about uninitialized variables that are initialized with themselves. Note this option can only be used with the @option{-Wuninitialized} option. @@ -4156,20 +4165,10 @@ All the above @option{-Wunused} options In order to get a warning about an unused function parameter, you must either specify @option{-Wextra -Wunused} (note that @option{-Wall} implies @option{-Wunused}), or separately specify @option{-Wunused-parameter}. -@item -Wnull-dereference -@opindex Wnull-dereference -@opindex Wno-null-dereference -Warn if the compiler detects paths that trigger erroneous or -undefined behavior due to dereferencing a null pointer. This option -is only active when @option{-fdelete-null-pointer-checks} is active, -which is enabled by optimizations in most targets. The precision of -the warnings depends on the optimization options used. This option is -enabled by @option{-Wall}. - @item -Wuninitialized @opindex Wuninitialized @opindex Wno-uninitialized Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a @code{setjmp} call. In C++, Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 226719) +++ gcc/c-family/c.opt (working copy) @@ -333,11 +333,11 @@ Warn about casts which discard qualifier Wchar-subscripts C ObjC C++ ObjC++ Var(warn_char_subscripts) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn about subscripts whose type is \"char\" Wchkp -C ObjC C++ ObjC++ Var(warn_chkp) Warning EnabledBy(Wall) +C ObjC C++ ObjC++ Var(warn_chkp) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn about memory access errors found by Pointer Bounds Checker Wclobbered C ObjC C++ ObjC++ Var(warn_clobbered) Warning EnabledBy(Wextra) Warn about variables that might be changed by \"longjmp\" or \"vfork\" Index: gcc/optc-gen.awk =================================================================== --- gcc/optc-gen.awk (revision 226719) +++ gcc/optc-gen.awk (working copy) @@ -28,11 +28,25 @@ # [-v header_name=header.h] < inputfile > options.c # Dump that array of options into a C file. END { -# Record first EnabledBy and LangEnabledBy uses. + +# Combine the flags of identical switches. Switches +# appear many times if they are handled by many front +# ends, for example. +for (i = 0; i < n_opts; i++) { + merged_flags[i] = flags[i] +} +for (i = 0; i < n_opts; i++) { + while(i + 1 != n_opts && opts[i] == opts[i + 1] ) { + merged_flags[i + 1] = merged_flags[i] " " merged_flags[i + 1]; + i++; + } +} + +# Record EnabledBy and LangEnabledBy uses. n_enabledby = 0; for (i = 0; i < n_langs; i++) { n_enabledby_lang[i] = 0; } for (i = 0; i < n_opts; i++) { @@ -46,19 +60,23 @@ for (i = 0; i < n_opts; i++) { # EnabledBy(arg) or EnabledBy(arg1 || arg2 || arg3) split_sep = " \\|\\| "; } n_enabledby_names = split(enabledby_arg, enabledby_names, split_sep); if (logical_and != 0 && n_enabledby_names > 2) { - print "#error EnabledBy (Wfoo && Wbar && Wbaz) not currently supported" + print "#error " opts[i] " EnabledBy(Wfoo && Wbar && Wbaz) currently not supported" } for (j = 1; j <= n_enabledby_names; j++) { enabledby_name = enabledby_names[j]; enabledby_index = opt_numbers[enabledby_name]; if (enabledby_index == "") { - print "#error Enabledby: " enabledby_name - } else { - condition = ""; + print "#error " opts[i] " Enabledby(" enabledby_name "), unknown option '" enabledby_name "'" + } else if (!flag_set_p("Common", merged_flags[enabledby_index])) { + print "#error " opts[i] " Enabledby(" enabledby_name "), '" \ + enabledby_name "' must have flag 'Common'" \ + " to use Enabledby(), otherwise use LangEnabledBy()" + } else { + condition = ""; if (logical_and != 0) { opt_var_name_1 = search_var_name(enabledby_names[1], opt_numbers, opts, flags, n_opts); opt_var_name_2 = search_var_name(enabledby_names[2], opt_numbers, opts, flags, n_opts); if (opt_var_name_1 == "") { print "#error " enabledby_names[1] " does not have a Var() flag" Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 226719) +++ gcc/common.opt (working copy) @@ -591,11 +591,11 @@ Common RejectNegative Joined Warning Und Wlarger-than= Common RejectNegative Joined UInteger Warning -Wlarger-than=<number> Warn if an object is larger than <number> bytes Wnull-dereference -Common Var(warn_null_dereference) Warning EnabledBy(Wall) +Common Var(warn_null_dereference) Warning Warn if dereferencing a NULL pointer may lead to erroneous or undefined behavior Wunsafe-loop-optimizations Common Var(warn_unsafe_loop_optimizations) Warning Warn if the loop cannot be optimized due to nontrivial assumptions. Index: gcc/opt-functions.awk =================================================================== --- gcc/opt-functions.awk (revision 226719) +++ gcc/opt-functions.awk (working copy) @@ -322,21 +322,21 @@ function lang_enabled_by(enabledby_langs if (enabledby_posarg != "" && enabledby_negarg != "") { with_args = "," enabledby_posarg "," enabledby_negarg } else if (enabledby_posarg == "" && enabledby_negarg == "") { with_args = "" } else { - print "#error LangEnabledBy("enabledby_langs","enabledby_name", " \ + print "#error " opts[i] " LangEnabledBy("enabledby_langs","enabledby_name", " \ enabledby_posarg", " enabledby_negargs \ ") with three arguments, it should have either 2 or 4" } n_enabledby_array = split(enabledby_name, enabledby_array, " \\|\\| "); for (k = 1; k <= n_enabledby_array; k++) { enabledby_index = opt_numbers[enabledby_array[k]]; if (enabledby_index == "") { - print "#error LangEnabledBy("enabledby_langs","enabledby_name", " \ - enabledby_posarg", " enabledby_negargs") has invalid ENABLEDBY_NAME" + print "#error " opts[i] " LangEnabledBy("enabledby_langs","enabledby_name", " \ + enabledby_posarg", " enabledby_negargs"), unknown option '" enabledby_name "'" } else { for (j = 1; j <= n_enabledby_arg_langs; j++) { lang_name = lang_sanitized_name(enabledby_arg_langs[j]); lang_index = lang_numbers[enabledby_arg_langs[j]]; if (enables[lang_name,enabledby_array[k]] == "") {