About implementation of the Negative property of options.

gengqi-linux gengqi@linux.alibaba.com
Wed Apr 28 12:36:11 GMT 2021


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


More information about the Gcc-patches mailing list