#include "opts.h"
#include "diagnostic-core.h"
+/* Validate a version string (either given on the command line or, perhaps
+ as MACOSX_DEPLOYMENT_TARGET).
+
+ The specs %version-compare() function doesn't accept leading '0' on
+ numbers so strip them out. Do sanity checking here too.
+
+ Return:
+ * original string means it was OK and we didn't want to change it.
+ * new string means it was OK but we rewrote it to avoid possible format
+ problems.
+ * NULL means we didn't like what we saw.
+*/
+
+static const char *
+validate_macosx_version_min (const char *version_str)
+{
+ size_t version_len;
+ unsigned long major, minor, tiny = 0;
+ char *end;
+ const char *old_version = version_str;
+ bool need_rewrite = false;
+
+ version_len = strlen (version_str);
+ if (version_len < 4) /* The minimum would be 10.x */
+ return NULL;
+
+ /* Version string must consist of digits and periods only. */
+ if (strspn (version_str, "0123456789.") != version_len)
+ return NULL;
+
+ if (!ISDIGIT (version_str[0]) || !ISDIGIT (version_str[version_len - 1]))
+ return NULL;
+
+ if (version_str[0] == '0')
+ need_rewrite = true;
+
+ major = strtoul (version_str, &end, 10);
+ version_str = end + ((*end == '.') ? 1 : 0);
+
+ if (major != 10) /* So far .. all MacOS 10 ... */
+ return NULL;
+
+ /* Version string components must be present and numeric. */
+ if (!ISDIGIT (version_str[0]))
+ return NULL;
+
+ /* If we have one or more leading zeros on a component, then rewrite the
+ version string. */
+ if (version_str[0] == '0' && version_str[1] != '\0'
+ && version_str[1] != '.')
+ need_rewrite = true;
+
+ minor = strtoul (version_str, &end, 10);
+ version_str = end + ((*end == '.') ? 1 : 0);
+ if (minor > 99)
+ return NULL;
+
+ /* If 'tiny' is present it must be numeric. */
+ if (*end != '\0' && !ISDIGIT (version_str[0]))
+ return NULL;
+
+ /* If we have one or more leading zeros on a component, then rewrite the
+ version string. */
+ if (*end != '\0' && version_str[0] == '0'
+ && version_str[1] != '\0')
+ need_rewrite = true;
+
+ tiny = strtoul (version_str, &end, 10);
+ if (tiny > 99)
+ return NULL;
+
+ /* Version string must contain no more than three tokens. */
+ if (*end != '\0')
+ return NULL;
+
+ if (need_rewrite)
+ {
+ char *new_version;
+ asprintf (&new_version, "10.%lu.%lu", minor, tiny);
+ return new_version;
+ }
+
+ return old_version;
+}
+
#ifndef CROSS_DIRECTORY_STRUCTURE
#include <sys/sysctl.h>
#include "xregex.h"
if (new_flag != NULL)
{
- size_t len = strlen (new_flag);
- if (len > 128) { /* Arbitrary limit, number should be like xx.yy.zz */
- warning (0, "couldn%'t understand version %s\n", new_flag);
- return NULL;
- }
- new_flag = xstrndup (new_flag, len);
+ const char *checked = validate_macosx_version_min (new_flag);
+ if (checked == NULL)
+ {
+ warning (0, "couldn%'t understand version %s\n", new_flag);
+ return NULL;
+ }
+ new_flag = xstrndup (checked, strlen (checked));
}
return new_flag;
}
case OPT_mmacosx_version_min_:
seen_version_min = true;
- vers_string = xstrndup ((*decoded_options)[i].arg, 32);
+ vers_string =
+ validate_macosx_version_min ((*decoded_options)[i].arg);
+ if (vers_string == NULL)
+ warning (0, "%qs is not valid for %<mmacosx-version-min%>\n",
+ (*decoded_options)[i].arg);
+ else if (vers_string == (*decoded_options)[i].arg)
+ vers_string = xstrndup ((*decoded_options)[i].arg, 32);
+ /* Now we've examined it, and verified/re-written, put it to
+ one side and append later. */
+ if (*decoded_options_count > i) {
+ memmove (*decoded_options + i,
+ *decoded_options + i + 1,
+ ((*decoded_options_count - i)
+ * sizeof (struct cl_decoded_option)));
+ }
+ --i;
+ --*decoded_options_count;
+ break;
default:
break;
so that we can figure out the mechanism and source for the sysroot to
be used. */
if (! seen_version_min && *decoded_options_count > 1)
- {
- /* Not set by the User, try to figure it out. */
- vers_string = darwin_default_min_version ();
- if (vers_string != NULL)
- {
- ++*decoded_options_count;
- *decoded_options = XRESIZEVEC (struct cl_decoded_option,
- *decoded_options,
- *decoded_options_count);
- generate_option (OPT_mmacosx_version_min_, vers_string, 1, CL_DRIVER,
- &(*decoded_options)[*decoded_options_count - 1]);
- }
- }
- /* Create and push the major version for assemblers that need it. */
+ /* Not set by the User, try to figure it out. */
+ vers_string = darwin_default_min_version ();
+
+ /* Create and push a cleaned up version, plus the major version for
+ assemblers and other cases that need it. */
if (vers_string != NULL)
{
+ ++*decoded_options_count;
+ *decoded_options = XRESIZEVEC (struct cl_decoded_option,
+ *decoded_options,
+ *decoded_options_count);
+ generate_option (OPT_mmacosx_version_min_, vers_string, 1, CL_DRIVER,
+ &(*decoded_options)[*decoded_options_count - 1]);
+
char *asm_major = NULL;
const char *first_period = strchr(vers_string, '.');
if (first_period != NULL)
--- /dev/null
+/* Test that we can handle leading-zeros on mmacosx-version-min for invocations
+ including linking (so that spec processing works). To make sure that any
+ necessary target libs are present we make this specific to the target version
+ being built. */
+/* { dg-do link { target *-*-darwin* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.04.11 -DCHECK=1049" { target *-*-darwin8* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.05.08 -DCHECK=1058" { target *-*-darwin9* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.06.08 -DCHECK=1068" { target *-*-darwin10* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.07.05 -DCHECK=1075" { target *-*-darwin11* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.08.05 -DCHECK=1085" { target *-*-darwin12* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.09.05 -DCHECK=1095" { target *-*-darwin13* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.010.03 -DCHECK=101003" { target *-*-darwin14* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.011.06 -DCHECK=101106" { target *-*-darwin15* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.012.06 -DCHECK=101206" { target *-*-darwin16* } } */
+/* { dg-additional-options "-mmacosx-version-min=010.013.06 -DCHECK=101306" { target *-*-darwin17* } } */
+/* This next test covers 10.18 and (currently unreleased) 10.19 for now. */
+/* { dg-additional-options "-mmacosx-version-min=010.014.05 -DCHECK=101405" { target *-*-darwin1[89]* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != CHECK
+ fail me;
+#endif
+ return 0;
+}