Hi,

This patch fixes a couple issues with the `-fonly=' option in the
D front-end driver.

Using `strcmp' to match the `-fonly=' argument with the input source
file made the feature inflexible to use.  By mistake, the driver was
also found to omit all other modules on the command line as well, which
differed from the documentation on the flag:

    Tell the compiler to parse and run semantic analysis on all modules
    on the command line, but only generate code for the given argument.

New tests added to check the feature, which didn't exist before.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32, and
committed to mainline.

Regards,
Iain.

---
        PR d/119758

gcc/d/ChangeLog:

        * d-lang.cc (d_parse_file): Use endswith in test for -fonly= argument.
        * d-spec.cc (lang_specific_driver): Rework -fonly= and pass all input
        files to the front-end compiler when the option is seen.

gcc/testsuite/ChangeLog:

        * gdc.dg/driver_fonly1.d: New test.
        * gdc.dg/driver_fonly2.d: New test.
        * gdc.dg/driver_fonly3.d: New test.
        * gdc.dg/imports/fonly.d: New test.
---
 gcc/d/d-lang.cc                      |  6 ++--
 gcc/d/d-spec.cc                      | 50 +++++++++++++++-------------
 gcc/testsuite/gdc.dg/driver_fonly1.d |  2 ++
 gcc/testsuite/gdc.dg/driver_fonly2.d |  8 +++++
 gcc/testsuite/gdc.dg/driver_fonly3.d |  8 +++++
 gcc/testsuite/gdc.dg/imports/fonly.d |  3 ++
 6 files changed, 51 insertions(+), 26 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/driver_fonly1.d
 create mode 100644 gcc/testsuite/gdc.dg/driver_fonly2.d
 create mode 100644 gcc/testsuite/gdc.dg/driver_fonly3.d
 create mode 100644 gcc/testsuite/gdc.dg/imports/fonly.d

diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index b3786be3c90..0dab76bbfbd 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -1085,9 +1085,9 @@ d_parse_file (void)
   /* Buffer for contents of .ddoc files.  */
   OutBuffer ddocbuf;
 
-  /* In this mode, the first file name is supposed to be a duplicate
-     of one of the input files.  */
-  if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
+  /* In this mode, the main input file is supposed to be the same as the one
+     given by -fonly=.  */
+  if (d_option.fonly && !endswith (main_input_filename, d_option.fonly))
     error ("%<-fonly=%> argument is different from first input file name");
 
   for (size_t i = 0; i < num_in_fnames; i++)
diff --git a/gcc/d/d-spec.cc b/gcc/d/d-spec.cc
index 7f4a779ab72..c78804812e3 100644
--- a/gcc/d/d-spec.cc
+++ b/gcc/d/d-spec.cc
@@ -104,8 +104,8 @@ lang_specific_driver (cl_decoded_option 
**in_decoded_options,
   /* The total number of arguments with the new stuff.  */
   unsigned int num_args = 1;
 
-  /* "-fonly" if it appears on the command line.  */
-  const char *only_source_option = 0;
+  /* "-fonly=" if it appears on the command line.  */
+  const char *only_source_arg = 0;
 
   /* Whether the -o option was used.  */
   bool saw_opt_o = false;
@@ -280,13 +280,13 @@ lang_specific_driver (cl_decoded_option 
**in_decoded_options,
 
        case OPT_fonly_:
          args[i] |= SKIPOPT;
-         only_source_option = decoded_options[i].orig_option_with_args_text;
+         only_source_arg = arg;
 
          if (arg != NULL)
            {
-             const char *suffix = strrchr (only_source_option, '.');
+             const char *suffix = strrchr (only_source_arg, '.');
              if (suffix == NULL || strcmp (suffix, ".d") != 0)
-               only_source_option = concat (only_source_option, ".d", NULL);
+               only_source_arg = concat (only_source_arg, ".d", NULL);
            }
          break;
 
@@ -335,48 +335,52 @@ lang_specific_driver (cl_decoded_option 
**in_decoded_options,
     + (phobos_library != PHOBOS_NOLINK) * 4 + 2;
   new_decoded_options = XNEWVEC (cl_decoded_option, num_args);
 
-  i = 0;
   j = 0;
 
   /* Copy the 0th argument, i.e., the name of the program itself.  */
-  new_decoded_options[j++] = decoded_options[i++];
+  new_decoded_options[j++] = decoded_options[0];
 
   /* NOTE: We start at 1 now, not 0.  */
-  while (i < argc)
+  for (i = 1; i < argc; i++)
     {
       if (args[i] & SKIPOPT)
-       {
-         ++i;
-         continue;
-       }
-
-      new_decoded_options[j] = decoded_options[i];
+       continue;
 
       if (!saw_libcxx && (args[i] & WITHLIBCXX))
        {
-         --j;
          saw_libcxx = &decoded_options[i];
+         continue;
        }
 
-      if (args[i] & DSOURCE)
+      if (only_source_arg && (args[i] & DSOURCE))
        {
-         if (only_source_option)
-           --j;
+         if (!endswith (decoded_options[i].arg, only_source_arg))
+           continue;
        }
 
-      i++;
+      new_decoded_options[j] = decoded_options[i];
       j++;
     }
 
-  if (only_source_option)
+  if (only_source_arg)
     {
-      const char *only_source_arg = only_source_option + 7;
+      /* Generate -fonly= option, then copy D input sources that were initially
+        skipped in first pass over all decoded_options.  */
       generate_option (OPT_fonly_, only_source_arg, 1, CL_DRIVER,
                       &new_decoded_options[j]);
       j++;
 
-      generate_option_input_file (only_source_arg,
-                                 &new_decoded_options[j++]);
+      for (i = 1; i < argc; i++)
+       {
+         if (!(args[i] & DSOURCE))
+           continue;
+
+         if (endswith (decoded_options[i].arg, only_source_arg))
+           continue;
+
+         new_decoded_options[j] = decoded_options[i];
+         j++;
+       }
     }
 
   /* If no reason to link against libphobos library, then don't add it.  */
diff --git a/gcc/testsuite/gdc.dg/driver_fonly1.d 
b/gcc/testsuite/gdc.dg/driver_fonly1.d
new file mode 100644
index 00000000000..1af956a780c
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/driver_fonly1.d
@@ -0,0 +1,2 @@
+// { dg-additional-options "-fonly=not-a-file" }
+// { dg-error "argument is different from first input file name" "" { target 
*-*-* } 0 }
diff --git a/gcc/testsuite/gdc.dg/driver_fonly2.d 
b/gcc/testsuite/gdc.dg/driver_fonly2.d
new file mode 100644
index 00000000000..97cd93d24b6
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/driver_fonly2.d
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-additional-options "-fonly=driver_fonly2.d" }
+// { dg-additional-sources "imports/fonly.d" }
+// { dg-final { scan-assembler "_D1a10fonly_testFZv" } }
+// { dg-final { scan-assembler-not "_D1b10fonly_testFZv" } }
+module a;
+
+void fonly_test() { }
diff --git a/gcc/testsuite/gdc.dg/driver_fonly3.d 
b/gcc/testsuite/gdc.dg/driver_fonly3.d
new file mode 100644
index 00000000000..de2983f196a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/driver_fonly3.d
@@ -0,0 +1,8 @@
+// { dg-do "compile" }
+// { dg-additional-options "-fonly=imports/fonly" }
+// { dg-additional-sources "imports/fonly.d" }
+// { dg-final { scan-assembler-not "_D1a10fonly_testFZv" } }
+// { dg-final { scan-assembler "_D1b10fonly_testFZv" } }
+module a;
+
+void fonly_test() { }
diff --git a/gcc/testsuite/gdc.dg/imports/fonly.d 
b/gcc/testsuite/gdc.dg/imports/fonly.d
new file mode 100644
index 00000000000..2b7755e410c
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/imports/fonly.d
@@ -0,0 +1,3 @@
+module b;
+
+void fonly_test() { }
-- 
2.43.0

Reply via email to