About implementation of the Negative property of options.
I have been fixing a bug. It involved the Negative property of options, and I have some confusion about it. gcc/optc-gen.awk: 383 neg = opt_args("Negative", flags[i]); if (neg != "") idx = indices[neg] else { if (flag_set_p("RejectNegative", flags[i])) idx = -1; else { if (opts[i] ~ "^[Wfgm]") idx = indices[opts[i]]; else idx = -1; } } Above is the code that handles the ‘Nagetive’ property. I don't see why the 'idx' should be set -1 when 'RejectNegative'. As I understand it, ‘Negative’ and ‘RejectNegative’ are similar name, but not related in implementation. The following is my implementation about it: --- a/gcc/doc/options.texi +++ b/gcc/doc/options.texi @@ -220,11 +220,7 @@ property is used. The option will turn off another option @var{othername}, which is the option name with the leading ``-'' removed. This chain action will propagate through the @code{Negative} property of the option to be -turned off. The driver will prune options, removing those that are -turned off by some later option. This pruning is not done for options -with @code{Joined} or @code{JoinedOrMissing} properties, unless the -options have either @code{RejectNegative} property or the @code{Negative} -property mentions an option other than itself. +turned off. As a consequence, if you have a group of mutually-exclusive options, their @code{Negative} properties should form a circular chain. diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk index 880ac77..d32354c 100644 --- a/gcc/optc-gen.awk +++ b/gcc/optc-gen.awk @@ -383,7 +383,9 @@ for (i = 0; i < n_opts; i++) { if (neg != "") idx = indices[neg] else { - if (flag_set_p("RejectNegative", flags[i])) + if (flag_set_p("Joined", flags[i]) \ + || flag_set_p("JoinedOrMissing", flags[i]) \ + || flag_set_p("Separate", flags[i])) idx = -1; else { if (opts[i] ~ "^[Wfgm]") diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 5e10ede..898e8d8 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -1039,11 +1039,12 @@ cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx) if (cl_options [next_opt_idx].neg_index == opt_idx) return true; - if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx) -return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index, - orig_next_opt_idx); + if (cl_options [next_opt_idx].neg_index == orig_next_opt_idx + || cl_options [next_opt_idx].neg_index < 0) +return false; - return false; + return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index, + orig_next_opt_idx); } /* Filter out options canceled by the ones after them. */ @@ -1088,14 +1089,6 @@ prune_options (struct cl_decoded_option **decoded_options, default: gcc_assert (opt_idx < cl_options_count); option = &cl_options[opt_idx]; - if (option->neg_index < 0) - goto keep; - - /* Skip joined switches. */ - if ((option->flags & CL_JOINED) - && (!option->cl_reject_negative - || (unsigned int) option->neg_index != opt_idx)) - goto keep; for (j = i + 1; j < old_decoded_options_count; j++) { @@ -1104,13 +1097,6 @@ prune_options (struct cl_decoded_option **decoded_options, next_opt_idx = old_decoded_options[j].opt_index; if (next_opt_idx >= cl_options_count) continue; - if (cl_options[next_opt_idx].neg_index < 0) - continue; - if ((cl_options[next_opt_idx].flags & CL_JOINED) - && (!cl_options[next_opt_idx].cl_reject_negative - || ((unsigned int) cl_options[next_opt_idx].neg_index - != next_opt_idx))) - continue; if (cancel_option (opt_idx, next_opt_idx, next_opt_idx)) break; } -- 2.7.4
回复:About implementation of the Negative property of options.
Thanks for your replies. On Thurs, Apr 29, 2021, utc+8 PM Joseph Myers wrote: Could you please explain the bug at the *user-visible* level? That is, the particular options passed to the compiler, how those options behave, and how you think they should behave instead. This is the real bug I met: https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568974.html On Thurs, Apr 29, 2021, utc+8 Joseph Myers wrote: Note that only in the -mfoo6= case are the duplicate options removed from the command line. So pruning options requires that you have both RejectNegative and Negative pointing at yourself, which is not what the documentation says. I also noticed a description error in the documentation: https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568977.html The patch above can fix the bug I met, but the same modification may not work in older versions because a key commit “aebe10d48ccc217273ee8a4e2c3805ed1e173a78” is needed. In my view, when I give the Negative property for '-march=' just like my patch do, --> march= --> -Target RejectNegative Joined --> +Target RejectNegative Joined Negative(march=) there should be enough information for the Driver to prune the extra '-march=' options, and this behavior should work well without the code added to gcc/opts-common.c from commit “aebe10d48ccc217273ee8a4e2c3805ed1e173a78" . On the other hand, as Joseph Myers tested: mfoo3= Target Joined Var(riscv_isa_foo) Negative(mfoo3=) mfoo4= Target Joined Var(riscv_isa_foo) Negative(mfoo5=) mfoo5= Target Joined Var(riscv_isa_foo) Negative(mfoo4=) mfoo6= Target Joined Var(riscv_isa_foo) Negative(mfoo6=) RejectNegative mfoo7= Target Joined Var(riscv_isa_foo) Negative(mfoo8=) RejectNegative mfoo8= Target Joined Var(riscv_isa_foo) Negative(mfoo7=) RejectNegative I think -mfoo3=,-mfoo4,-mfoo5 should be pruned, and -mfoo6=,-mfoo7,-mfoo8 should also be pruned. Compare -mfoo3=,-mfoo4,-mfoo5 with -mfoo6=,-mfoo7,-mfoo8, I think the RejectNegative may shouldn't bother with the Negative. This is why I wrote on Wed Apr 28 12:36:11 GMT 2021 gcc/optc-gen.awk: 383 neg = opt_args("Negative", flags[i]); if (neg != "") idx = indices[neg] else { if (flag_set_p("RejectNegative", flags[i])) idx = -1; else { if (opts[i] ~ "^[Wfgm]") idx = indices[opts[i]]; else idx = -1; } } Above is the code that handles the ‘Nagetive’ property. I don't see why the 'idx' should be set -1 when 'RejectNegative'. As I understand it, ‘Negative’ and ‘RejectNegative’ are similar name, but not related in implementation. -- 发件人:Jim Wilson 发送时间:2021年4月30日(星期五) 10:02 收件人:Joseph Myers 抄 送:gengqi-linux ; gcc-patches 主 题:Re: About implementation of the Negative property of options. On Wed, Apr 28, 2021 at 1:11 PM Joseph Myers wrote: Could you please explain the bug at the *user-visible* level? That is, the particular options passed to the compiler, how those options behave, and how you think they should behave instead. I added this to the riscv.opt file to create some new options for demonstration purposes. The same changes probably work for other targets too. mfoo1=Target Joined Var(riscv_isa_foo) mfoo2= Target Joined Var(riscv_isa_foo) RejectNegative mfoo3= Target Joined Var(riscv_isa_foo) Negative(mfoo3=) mfoo4= Target Joined Var(riscv_isa_foo) Negative(mfoo5=) mfoo5= Target Joined Var(riscv_isa_foo) Negative(mfoo4=) mfoo6= Target Joined Var(riscv_isa_foo) Negative(mfoo6=) RejectNegative mfoo7= Target Joined Var(riscv_isa_foo) Negative(mfoo8=) RejectNegative mfoo8= Target Joined Var(riscv_isa_foo) Negative(mfoo7=) RejectNegative TargetVariable int riscv_isa_foo = 0 Then I ran some commands to look at the cc1 option list. rohan:2754$ ./xgcc -B./ -mfoo1=10 -mfoo1=20 tmp.c -v -S |& grep cc1 ./cc1 -quiet -v -imultilib rv64imafdc/lp64d -iprefix /home/jimw/FOSS/GCC/X-9-riscv64-elf/gcc/../lib/gcc/riscv64-unknown-elf/9.3.1/ -isystem ./include -isystem ./include-fixed tmp.c -quiet -dumpbase tmp.c -mfoo1=10 -mfoo1=20 -march=rv64gc -mabi=lp64d -auxbase tmp -version -o tmp.s rohan:2755$ ./xgcc -B./ -mfoo2=10 -mfoo2=20 tmp.c -v -S |& grep cc1 ./cc1 -quiet -v -imultilib rv64imafdc/lp64d -iprefix /home/jimw/FOSS/GCC/X-9-riscv64-elf/gcc/../lib/gcc/riscv64-unknown-elf/9.3.1/ -isystem ./include -isystem ./include-fixed tmp.c -quiet -dumpbase tmp.c -mfoo2=10 -mfoo2=20 -march=rv64gc -mabi=lp64d -auxbase tmp -version -o tmp.s rohan:2756$ ./xgcc -B./ -mfoo3=10 -mfoo3=20 tmp.c -v -S |& grep cc1 ./cc1 -quiet -v -imultilib rv64imafdc/lp64d -iprefix /home/jimw/FOSS/GCC/X-9-riscv64-elf/gcc/../lib/gcc/riscv64-unknown-elf/9.3.1/ -isystem ./include -isystem ./include-fixed tmp.c -quiet -dumpbase tmp.c -mfoo3=10 -mfoo3=20 -march=rv64gc -mabi=lp64d -auxbase tmp -version -o tmp.s rohan:2757$ ./xgcc -B./ -mfoo4=10 -mfoo4=20 tmp.c -v -S |& grep cc1 ./cc1 -quiet -v -imultilib rv64imafdc/lp64d -iprefix /home/jimw/FOSS/GCC/X-9-riscv64-elf/gcc