Patchwork [RFC] Fix -I ""

login
register
mail settings
Submitter Jie Zhang
Date Dec. 15, 2010, 2:22 p.m.
Message ID <4D08CF1B.4050803@codesourcery.com>
Download mbox | patch
Permalink /patch/75648/
State New
Headers show

Comments

Jie Zhang - Dec. 15, 2010, 2:22 p.m.
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,
Joseph S. Myers - Dec. 16, 2010, 8:37 p.m.
The gcc.c changes in this patch are OK if there are no objections within 
48 hours.

The opts-common.c changes aren't correct by themselves; if you increase 
the amount of text going in orig_option_with_args_text then you also need 
to update the earlier loop computing how much memory to allocate for that 
string.  (Note also I can't approve changes to opts-common.c.)

Have you confirmed the testcase actually tests what you want it to test - 
that is, that it fails before the rest of the patch is applied and passes 
afterwards?  I don't know if passing empty arguments through DejaGnu is 
reliable.

Patch


	* 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 \"\"" } */
+