aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcc.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
committerIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
commite252b51ccde010cbd2a146485d8045103cd99533 (patch)
treee060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/gcc.c
parentf10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff)
parent104c05c5284b7822d770ee51a7d91946c7e56d50 (diff)
downloadgcc-e252b51ccde010cbd2a146485d8045103cd99533.zip
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz
gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r--gcc/gcc.c194
1 files changed, 149 insertions, 45 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 7837553..3e98bc7 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -319,6 +319,12 @@ static const char *spec_host_machine = DEFAULT_REAL_TARGET_MACHINE;
static char *offload_targets = NULL;
+#if OFFLOAD_DEFAULTED
+/* Set to true if -foffload has not been used and offload_targets
+ is set to the configured in default. */
+static bool offload_targets_default;
+#endif
+
/* Nonzero if cross-compiling.
When -b is used, the value comes from the `specs' file. */
@@ -910,7 +916,7 @@ proper position among the other output files. */
than in ASM_DEBUG_SPEC, so that it applies to both .s and .c etc.
compilations. */
# define ASM_DEBUG_DWARF_OPTION ""
-# elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG)
+# elif defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && !defined(HAVE_LD_BROKEN_PE_DWARF5)
# define ASM_DEBUG_DWARF_OPTION "%{%:dwarf-version-gt(4):--gdwarf-5;" \
"%:dwarf-version-gt(3):--gdwarf-4;" \
"%:dwarf-version-gt(2):--gdwarf-3;" \
@@ -1900,7 +1906,7 @@ init_spec (void)
when given the proper command line arguments. */
while (*p)
{
- if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
+ if (in_sep && *p == '-' && startswith (p, "-lgcc"))
{
init_gcc_specs (&obstack,
"-lgcc_s"
@@ -1923,7 +1929,7 @@ init_spec (void)
p += 5;
in_sep = 0;
}
- else if (in_sep && *p == 'l' && strncmp (p, "libgcc.a%s", 10) == 0)
+ else if (in_sep && *p == 'l' && startswith (p, "libgcc.a%s"))
{
/* Ug. We don't know shared library extensions. Hope that
systems that use this form don't do shared libraries. */
@@ -2236,7 +2242,7 @@ close_at_file (void)
if (n_args == 0)
return;
- char **argv = (char **) alloca (sizeof (char *) * (n_args + 1));
+ char **argv = XALLOCAVEC (char *, n_args + 1);
char *temp_file = make_at_file ();
char *at_argument = concat ("@", temp_file, NULL);
FILE *f = fopen (temp_file, "w");
@@ -2378,7 +2384,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
/* Skip '\n'. */
p++;
- if (!strncmp (p1, "%include", sizeof ("%include") - 1)
+ if (startswith (p1, "%include")
&& (p1[sizeof "%include" - 1] == ' '
|| p1[sizeof "%include" - 1] == '\t'))
{
@@ -2399,7 +2405,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
read_specs (new_filename ? new_filename : p1, false, user_p);
continue;
}
- else if (!strncmp (p1, "%include_noerr", sizeof "%include_noerr" - 1)
+ else if (startswith (p1, "%include_noerr")
&& (p1[sizeof "%include_noerr" - 1] == ' '
|| p1[sizeof "%include_noerr" - 1] == '\t'))
{
@@ -2423,7 +2429,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
fnotice (stderr, "could not find specs file %s\n", p1);
continue;
}
- else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
+ else if (startswith (p1, "%rename")
&& (p1[sizeof "%rename" - 1] == ' '
|| p1[sizeof "%rename" - 1] == '\t'))
{
@@ -3056,6 +3062,11 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
return xstrdup (DEFAULT_LINKER);
#endif
+#ifdef DEFAULT_DSYMUTIL
+ if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, mode) == 0)
+ return xstrdup (DEFAULT_DSYMUTIL);
+#endif
+
/* Determine the filename to execute (special case for absolute paths). */
if (IS_ABSOLUTE_PATH (name))
@@ -3245,7 +3256,7 @@ execute (void)
n_commands++;
/* Get storage for each command. */
- commands = (struct command *) alloca (n_commands * sizeof (struct command));
+ commands = XALLOCAVEC (struct command, n_commands);
/* Split argbuf into its separate piped processes,
and record info about each one.
@@ -3424,13 +3435,13 @@ execute (void)
struct pex_time *times = NULL;
int ret_code = 0;
- statuses = (int *) alloca (n_commands * sizeof (int));
+ statuses = XALLOCAVEC (int, n_commands);
if (!pex_get_status (pex, n_commands, statuses))
fatal_error (input_location, "failed to get exit status: %m");
if (report_times || report_times_to_file)
{
- times = (struct pex_time *) alloca (n_commands * sizeof (struct pex_time));
+ times = XALLOCAVEC (struct pex_time, n_commands);
if (!pex_get_times (pex, n_commands, times))
fatal_error (input_location, "failed to get process times: %m");
}
@@ -3496,7 +3507,7 @@ execute (void)
&& WEXITSTATUS (status) == ICE_EXIT_CODE
&& i == 0
&& (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
- && ! strncmp (p + 1, "cc1", 3))
+ && startswith (p + 1, "cc1"))
try_generate_repro (commands[0].argv);
if (WEXITSTATUS (status) > greatest_status)
greatest_status = WEXITSTATUS (status);
@@ -3746,6 +3757,7 @@ display_help (void)
fputs (_(" -dumpspecs Display all of the built in spec strings.\n"), stdout);
fputs (_(" -dumpversion Display the version of the compiler.\n"), stdout);
fputs (_(" -dumpmachine Display the compiler's target processor.\n"), stdout);
+ fputs (_(" -foffload=<targets> Specify offloading targets.\n"), stdout);
fputs (_(" -print-search-dirs Display the directories in the compiler's search path.\n"), stdout);
fputs (_(" -print-libgcc-file-name Display the name of the compiler's companion library.\n"), stdout);
fputs (_(" -print-file-name=<lib> Display the full path to library <lib>.\n"), stdout);
@@ -3971,6 +3983,87 @@ driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
static const char *spec_lang = 0;
static int last_language_n_infiles;
+
+/* Check that GCC is configured to support the offload target. */
+
+static bool
+check_offload_target_name (const char *target, ptrdiff_t len)
+{
+ const char *n, *c = OFFLOAD_TARGETS;
+ while (c)
+ {
+ n = strchr (c, ',');
+ if (n == NULL)
+ n = strchr (c, '\0');
+ if (len == n - c && strncmp (target, c, n - c) == 0)
+ break;
+ c = *n ? n + 1 : NULL;
+ }
+ if (!c)
+ {
+ auto_vec<const char*> candidates;
+ size_t olen = strlen (OFFLOAD_TARGETS) + 1;
+ char *cand = XALLOCAVEC (char, olen);
+ memcpy (cand, OFFLOAD_TARGETS, olen);
+ for (c = strtok (cand, ","); c; c = strtok (NULL, ","))
+ candidates.safe_push (c);
+
+ char *target2 = XALLOCAVEC (char, len + 1);
+ memcpy (target2, target, len);
+ target2[len] = '\0';
+
+ error ("GCC is not configured to support %qs as offload target", target2);
+
+ if (candidates.is_empty ())
+ inform (UNKNOWN_LOCATION, "no offloading targets configured");
+ else
+ {
+ char *s;
+ const char *hint = candidates_list_and_hint (target2, s, candidates);
+ if (hint)
+ inform (UNKNOWN_LOCATION,
+ "valid offload targets are: %s; did you mean %qs?", s, hint);
+ else
+ inform (UNKNOWN_LOCATION, "valid offload targets are: %s", s);
+ XDELETEVEC (s);
+ }
+ return false;
+ }
+ return true;
+}
+
+/* Sanity check for -foffload-options. */
+
+static void
+check_foffload_target_names (const char *arg)
+{
+ const char *cur, *next, *end;
+ /* If option argument starts with '-' then no target is specified and we
+ do not need to parse it. */
+ if (arg[0] == '-')
+ return;
+ end = strchr (arg, '=');
+ if (end == NULL)
+ {
+ error ("%<=%>options missing after %<-foffload-options=%>target");
+ return;
+ }
+
+ cur = arg;
+ while (cur < end)
+ {
+ next = strchr (cur, ',');
+ if (next == NULL)
+ next = end;
+ next = (next > end) ? end : next;
+
+ /* Retain non-supported targets after printing an error as those will not
+ be processed; each enabled target only processes its triplet. */
+ check_offload_target_name (cur, next - cur);
+ cur = next + 1;
+ }
+}
+
/* Parse -foffload option argument. */
static void
@@ -4000,34 +4093,25 @@ handle_foffload_option (const char *arg)
memcpy (target, cur, next - cur);
target[next - cur] = '\0';
- /* If 'disable' is passed to the option, stop parsing the option and clean
- the list of offload targets. */
- if (strcmp (target, "disable") == 0)
+ /* Reset offloading list and continue. */
+ if (strcmp (target, "default") == 0)
{
free (offload_targets);
- offload_targets = xstrdup ("");
- break;
+ offload_targets = NULL;
+ goto next_item;
}
- /* Check that GCC is configured to support the offload target. */
- c = OFFLOAD_TARGETS;
- while (c)
+ /* If 'disable' is passed to the option, clean the list of
+ offload targets and return, even if more targets follow.
+ Likewise if GCC is not configured to support that offload target. */
+ if (strcmp (target, "disable") == 0
+ || !check_offload_target_name (target, next - cur))
{
- n = strchr (c, ',');
- if (n == NULL)
- n = strchr (c, '\0');
-
- if (next - cur == n - c && strncmp (target, c, n - c) == 0)
- break;
-
- c = *n ? n + 1 : NULL;
+ free (offload_targets);
+ offload_targets = xstrdup ("");
+ return;
}
- if (!c)
- fatal_error (input_location,
- "GCC is not configured to support %s as offload target",
- target);
-
if (!offload_targets)
{
offload_targets = target;
@@ -4061,7 +4145,7 @@ handle_foffload_option (const char *arg)
memcpy (offload_targets + offload_targets_len, target, next - cur + 1);
}
}
-
+next_item:
cur = next + 1;
XDELETEVEC (target);
}
@@ -4493,8 +4577,16 @@ driver_handle_option (struct gcc_options *opts,
flag_wpa = "";
break;
+ case OPT_foffload_options_:
+ check_foffload_target_names (arg);
+ break;
+
case OPT_foffload_:
handle_foffload_option (arg);
+ if (arg[0] == '-' || NULL != strchr (arg, '='))
+ save_switch (concat ("-foffload-options=", arg, NULL),
+ 0, NULL, validated, true);
+ do_save = false;
break;
default:
@@ -4828,7 +4920,22 @@ process_command (unsigned int decoded_options_count,
/* If the user didn't specify any, default to all configured offload
targets. */
if (ENABLE_OFFLOADING && offload_targets == NULL)
- handle_foffload_option (OFFLOAD_TARGETS);
+ {
+ handle_foffload_option (OFFLOAD_TARGETS);
+#if OFFLOAD_DEFAULTED
+ offload_targets_default = true;
+#endif
+ }
+
+ /* Handle -gtoggle as it would later in toplev.c:process_options to
+ make the debug-level-gt spec function work as expected. */
+ if (flag_gtoggle)
+ {
+ if (debug_info_level == DINFO_LEVEL_NONE)
+ debug_info_level = DINFO_LEVEL_NORMAL;
+ else
+ debug_info_level = DINFO_LEVEL_NONE;
+ }
if (output_file
&& strcmp (output_file, "-") != 0
@@ -5827,10 +5934,7 @@ compile_input_file_p (struct infile *infile)
static void
do_specs_vec (vec<char_p> vec)
{
- unsigned ix;
- char *opt;
-
- FOR_EACH_VEC_ELT (vec, ix, opt)
+ for (char *opt : vec)
{
do_spec_1 (opt, 1, NULL);
/* Make each accumulated option a separate argument. */
@@ -6425,8 +6529,6 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
{
const char *p1 = p;
char *string;
- char *opt;
- unsigned ix;
/* Skip past the option value and make a copy. */
if (*p != '{')
@@ -6437,7 +6539,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
string = save_string (p1 + 1, p - p1 - 2);
/* See if we already recorded this option. */
- FOR_EACH_VEC_ELT (linker_options, ix, opt)
+ for (const char *opt : linker_options)
if (! strcmp (string, opt))
{
free (string);
@@ -7324,7 +7426,7 @@ check_live_switch (int switchnum, int prefix_length)
break;
case 'W': case 'f': case 'm': case 'g':
- if (! strncmp (name + 1, "no-", 3))
+ if (startswith (name + 1, "no-"))
{
/* We have Xno-YYY, search for XYYY. */
for (i = switchnum + 1; i < n_switches; i++)
@@ -8305,9 +8407,7 @@ driver::set_up_specs () const
&& do_spec_2 (startfile_prefix_spec, NULL) == 0
&& do_spec_1 (" ", 0, NULL) == 0)
{
- const char *arg;
- int ndx;
- FOR_EACH_VEC_ELT (argbuf, ndx, arg)
+ for (const char *arg : argbuf)
add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS",
PREFIX_PRIORITY_LAST, 0, 1);
}
@@ -8484,6 +8584,10 @@ driver::maybe_putenv_OFFLOAD_TARGETS () const
obstack_grow (&collect_obstack, offload_targets,
strlen (offload_targets) + 1);
xputenv (XOBFINISH (&collect_obstack, char *));
+#if OFFLOAD_DEFAULTED
+ if (offload_targets_default)
+ xputenv ("OFFLOAD_TARGET_DEFAULT=1");
+#endif
}
free (offload_targets);