This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix %< handling in the driver (PR driver/42442)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>, Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Dec 2009 05:26:52 -0500
- Subject: [PATCH] Fix %< handling in the driver (PR driver/42442)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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