This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]