This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFC] Fix -I ""
- From: Jie Zhang <jie at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 15 Dec 2010 22:22:19 +0800
- Subject: [RFC] Fix -I ""
Currently gcc behaves weirdly when an empty string argument passed to -I
option.
On x86_64-linux-gnu, the latest gcc from trunk:
$ gcc -I "" -c -o t.o t.c
cc1: warning: t.c: not a directory [enabled by default]
[hang]
$ gcc-4.5 -I "" -c -o t.o t.c
[hang]
$ gcc-4.4 -I "" -c -o t.o t.c
cc1: error: t.c: not a directory
[hang]
$ gcc-4.3 -I "" -c -o t.o t.c
cc1: error: t.c: not a directory
For cross compiler from latest trunk:
$ arm-none-linux-gnueabi-gcc -I "" -c t.c -o t.o
cc1: fatal error:
/scratch/jie/fsf-arm-linux-gnueabi/install/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.0/:
No such file or directory
compilation terminated.
This issue occurs because do_spec_1 drops the empty string argument.
The attached patch changes do_spec_1 not to drop empty string argument
and change other places to print "" for such argument when verbose.
Another way to fix this issue might change gcc to error out for -I "".
But I think accepting it and passing it down is better. If empty string
argument is an error, subcommands should report it. In this case, the
compiler don't think it's an error
Bootstrapped on x86_64-linux-gnu and regression tested with c,c++,lto.
Is it OK?
Regards,
--
Jie Zhang
* opts-common.c (decode_cmdline_option): Print empty string
argument as "" in decoded->orig_option_with_args_text.
* gcc.c (execute): Print empty string argument as ""
in the verbose output.
(do_spec_1): Keep empty string argument.
testsuite/
* gcc.dg/cpp/include7.c: New test.
Index: opts-common.c
===================================================================
--- opts-common.c (revision 167855)
+++ opts-common.c (working copy)
@@ -637,7 +637,14 @@ decode_cmdline_option (const char **argv
{
size_t len = strlen (argv[i]);
- memcpy (p, argv[i], len);
+ /* Print the empty string verbally. */
+ if (len == 0)
+ {
+ *p++ = '"';
+ *p++ = '"';
+ }
+ else
+ memcpy (p, argv[i], len);
p += len;
if (i == result - 1)
*p++ = 0;
Index: gcc.c
===================================================================
--- gcc.c (revision 167855)
+++ gcc.c (working copy)
@@ -2521,13 +2521,20 @@ execute (void)
}
fputc ('"', stderr);
}
+ /* If it's empty, print "". */
+ else if (!**j)
+ fprintf (stderr, " \"\"");
else
fprintf (stderr, " %s", *j);
}
}
else
for (j = commands[i].argv; *j; j++)
- fprintf (stderr, " %s", *j);
+ /* If it's empty, print "". */
+ if (!**j)
+ fprintf (stderr, " \"\"");
+ else
+ fprintf (stderr, " %s", *j);
/* Print a pipe symbol after all but the last command. */
if (i + 1 != n_commands)
@@ -4398,6 +4405,10 @@ do_spec_1 (const char *spec, int inswitc
int i;
int value;
+ /* If it's an empty string argument to a switch, keep it as is. */
+ if (inswitch && !*p)
+ arg_going = 1;
+
while ((c = *p++))
/* If substituting a switch, treat all chars like letters.
Otherwise, NL, SPC, TAB and % are special. */
@@ -5117,7 +5128,8 @@ do_spec_1 (const char *spec, int inswitc
case '*':
if (soft_matched_part)
{
- do_spec_1 (soft_matched_part, 1, NULL);
+ if (soft_matched_part[0])
+ do_spec_1 (soft_matched_part, 1, NULL);
do_spec_1 (" ", 0, NULL);
}
else
Index: testsuite/gcc.dg/cpp/include7.c
===================================================================
--- testsuite/gcc.dg/cpp/include7.c (revision 0)
+++ testsuite/gcc.dg/cpp/include7.c (revision 0)
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-I \"\"" } */
+