d: Fix -fonly= argument only matches when including full path [PR119758]

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.

	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.
This commit is contained in:
Iain Buclaw 2025-04-12 09:40:24 +02:00
parent 359b6128ad
commit 8a03d014ec
6 changed files with 51 additions and 26 deletions

View file

@ -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++)

View file

@ -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. */

View file

@ -0,0 +1,2 @@
// { dg-additional-options "-fonly=not-a-file" }
// { dg-error "argument is different from first input file name" "" { target *-*-* } 0 }

View file

@ -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() { }

View file

@ -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() { }

View file

@ -0,0 +1,3 @@
module b;
void fonly_test() { }