[PATCH] Fix %< handling in the driver (PR driver/42442)

Jakub Jelinek jakub@redhat.com
Tue Dec 22 13:13:00 GMT 2009


Hi!

The addition of -fcompare-debug in r148271 regressed -march=native when used
with multiple files (and other %< options in that case).
check_live_switch used to ignore SWITCH_IGNORE bit, but since r148271 it
says that those options aren't live.
When we have multiple source files, do_spec containing among others
%{march=native:%<march=native %:local_cpu_detect(arch)}
is invoked for each source file.  On the first file march=native is
considered live, thus the condition is true and %<march=native sets
SWITCH_IGNORE bit on that option (and %: adds various options to
argbuf).  But on the next file check_live_switch for march=native
returns newly false because SWITCH_IGNORE bit is set, thus march=native
condition is considered false and nothing is expanded from its body.

The reason for the r148271 change in check_live_switch has been to
fix behaviour of do_self_spec when encountering %<.  do_self_spec appends
the argbuf accumulated options at the end of switches, so switches
ignored through %< in self specs really should be ignored permanently -
their replacements have been added to switches and every do_spec afterwards
will see all those switches.  But do_spec invocations can be called multiple
times and we shouldn't consider switches not being present on the command
line just because an earlier do_spec invocation saw that switch in %<.

This patch implements that, %< in do_self_spec means that the option isn't
considered by check_live_switch afterwards, %< seen in do_spec is considered
like it used to be before r148271.

Ok for trunk?

2009-12-22  Jakub Jelinek  <jakub@redhat.com>

	PR driver/42442
	* gcc.c (SWITCH_IGNORE_PERMANENTLY): Define.
	(do_self_spec): For switches with SWITCH_IGNORE set set also
	SWITCH_IGNORE_PERMANENTLY.
	(check_live_switch): Check SWITCH_IGNORE_PERMANENTLY instead
	of SWITCH_IGNORE.

--- gcc/gcc.c.jj	2009-12-22 09:44:23.000000000 +0100
+++ gcc/gcc.c	2009-12-22 10:44:21.000000000 +0100
@@ -3229,12 +3229,15 @@ See %s for instructions.",
    SWITCH_LIVE to indicate this switch is true in a conditional spec.
    SWITCH_FALSE to indicate this switch is overridden by a later switch.
    SWITCH_IGNORE to indicate this switch should be ignored (used in %<S).
+   SWITCH_IGNORE_PERMANENTLY to indicate this switch should be ignored
+   in all do_spec calls afterwards.  Used for %<S from self specs.
    The `validated' field is nonzero if any spec has looked at this switch;
    if it remains zero at the end of the run, it must be meaningless.  */
 
-#define SWITCH_LIVE    0x1
-#define SWITCH_FALSE   0x2
-#define SWITCH_IGNORE  0x4
+#define SWITCH_LIVE    			0x1
+#define SWITCH_FALSE   			0x2
+#define SWITCH_IGNORE			0x4
+#define SWITCH_IGNORE_PERMANENTLY	0x8
 
 struct switchstr
 {
@@ -4924,13 +4927,20 @@ do_option_spec (const char *name, const 
 static void
 do_self_spec (const char *spec)
 {
+  int i;
+
   do_spec_2 (spec);
   do_spec_1 (" ", 0, NULL);
 
+  /* Mark %<S switches processed by do_self_spec to be ignored permanently.
+     do_self_specs adds the replacements to switches array, so it shouldn't
+     be processed afterwards.  */
+  for (i = 0; i < n_switches; i++)
+    if ((switches[i].live_cond & SWITCH_IGNORE))
+      switches[i].live_cond |= SWITCH_IGNORE_PERMANENTLY;
+
   if (argbuf_index > 0)
     {
-      int i;
-
       switches = XRESIZEVEC (struct switchstr, switches,
 			     n_switches + argbuf_index + 1);
 
@@ -6444,7 +6454,8 @@ check_live_switch (int switchnum, int pr
   if (switches[switchnum].live_cond != 0)
     return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
 	    && (switches[switchnum].live_cond & SWITCH_FALSE) == 0
-	    && (switches[switchnum].live_cond & SWITCH_IGNORE) == 0);
+	    && (switches[switchnum].live_cond & SWITCH_IGNORE_PERMANENTLY)
+	       == 0);
 
   /* In the common case of {<at-most-one-letter>*}, a negating
      switch would always match, so ignore that case.  We will just

	Jakub



More information about the Gcc-patches mailing list