re PR target/63810 (gcc sets incorrect macro for OS X deployment targets)
authorLawrence Velázquez <vq@larryv.me>
Thu, 28 May 2015 12:27:05 +0000 (14:27 +0200)
committerMike Stump <mrs@gcc.gnu.org>
Thu, 28 May 2015 12:27:05 +0000 (12:27 +0000)
2015-05-28  Lawrence Velázquez  <vq@larryv.me>

PR target/63810
* config/darwin-c.c (version_components): New global enum.
(parse_version, version_as_legacy_macro)
(version_as_modern_macro, macosx_version_as_macro): New functions.
(version_as_macro): Remove.
(darwin_cpp_builtins): Use new function.

testsuite:
PR target/63810
* gcc.dg/darwin-minversion-3.c: Update testcase.
* gcc.dg/darwin-minversion-4.c: Ditto.
* gcc.dg/darwin-minversion-5.c: New testcase.
* gcc.dg/darwin-minversion-6.c: Ditto.
* gcc.dg/darwin-minversion-7.c: Ditto.
* gcc.dg/darwin-minversion-8.c: Ditto.
* gcc.dg/darwin-minversion-9.c: Ditto.
* gcc.dg/darwin-minversion-10.c: Ditto.
* gcc.dg/darwin-minversion-11.c: Ditto.
* gcc.dg/darwin-minversion-12.c: Ditto.

From-SVN: r223808

13 files changed:
gcc/ChangeLog
gcc/config/darwin-c.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/darwin-minversion-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-3.c
gcc/testsuite/gcc.dg/darwin-minversion-4.c
gcc/testsuite/gcc.dg/darwin-minversion-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/darwin-minversion-9.c [new file with mode: 0644]

index 0b8efebfeff76d4632e8ee9cc7667af5b3d54dcb..0603918fddc88bffef6d243173c1c9ca30b5934f 100644 (file)
@@ -1,3 +1,12 @@
+2015-05-28  Lawrence Velázquez  <vq@larryv.me>
+
+       PR target/63810
+       * config/darwin-c.c (version_components): New global enum.
+       (parse_version, version_as_legacy_macro)
+       (version_as_modern_macro, macosx_version_as_macro): New functions.
+       (version_as_macro): Remove.
+       (darwin_cpp_builtins): Use new function.
+
 2015-05-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        * builtins.c (expand_builtin_acc_on_device): Mark parameters
index 3803e75fb76494b144f6d2912b384fcc3e8755d1..6d49f05b0dbc25de820b45f7de003763b822560a 100644 (file)
@@ -599,42 +599,158 @@ find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
   return 0;
 }
 
-/* Return the value of darwin_macosx_version_min suitable for the
-   __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro, so '10.4.2'
-   becomes 1040 and '10.10.0' becomes 101000.  The lowest digit is
-   always zero, as is the second lowest for '10.10.x' and above.
-   Print a warning if the version number can't be understood.  */
+/* Given an OS X version VERSION_STR, return it as a statically-allocated array
+   of three integers. If VERSION_STR is invalid, return NULL.
+
+   VERSION_STR must consist of one, two, or three tokens, each separated by
+   a single period.  Each token must contain only the characters '0' through
+   '9' and is converted to an equivalent non-negative decimal integer. Omitted
+   tokens become zeros.  For example:
+
+        "10"              becomes       {10,0,0}
+        "10.10"           becomes       {10,10,0}
+        "10.10.1"         becomes       {10,10,1}
+        "10.000010.1"     becomes       {10,10,1}
+        "10.010.001"      becomes       {10,10,1}
+        "000010.10.00001" becomes       {10,10,1}
+        ".9.1"            is invalid
+        "10..9"           is invalid
+        "10.10."          is invalid  */
+
+enum version_components { MAJOR, MINOR, TINY };
+
+static const unsigned long *
+parse_version (const char *version_str)
+{
+  size_t version_len;
+  char *end;
+  static unsigned long version_array[3];
+
+  version_len = strlen (version_str);
+  if (version_len < 1)
+    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;
+
+  version_array[MAJOR] = strtoul (version_str, &end, 10);
+  version_str = end + ((*end == '.') ? 1 : 0);
+
+  /* Version string must not contain adjacent periods.  */
+  if (*version_str == '.')
+    return NULL;
+
+  version_array[MINOR] = strtoul (version_str, &end, 10);
+  version_str = end + ((*end == '.') ? 1 : 0);
+
+  version_array[TINY] = strtoul (version_str, &end, 10);
+
+  /* Version string must contain no more than three tokens.  */
+  if (*end != '\0')
+    return NULL;
+
+  return version_array;
+}
+
+/* Given VERSION -- a three-component OS X version represented as an array of
+   non-negative integers -- return a statically-allocated string suitable for
+   the legacy __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.  If VERSION
+   is invalid and cannot be coerced into a valid form, return NULL.
+
+   The legacy format is a four-character string -- two chars for the major
+   number and one each for the minor and tiny numbers.  Minor and tiny numbers
+   from 10 through 99 are permitted but are clamped to 9 (for example, {10,9,10}
+   produces "1099").  If VERSION contains numbers greater than 99, it is
+   rejected.  */
+
+static const char *
+version_as_legacy_macro (const unsigned long *version)
+{
+  unsigned long major, minor, tiny;
+  static char result[5];
+
+  major = version[MAJOR];
+  minor = version[MINOR];
+  tiny = version[TINY];
+
+  if (major > 99 || minor > 99 || tiny > 99)
+    return NULL;
+
+  minor = ((minor > 9) ? 9 : minor);
+  tiny = ((tiny > 9) ? 9 : tiny);
+
+  if (sprintf (result, "%lu%lu%lu", major, minor, tiny) != 4)
+    return NULL;
+
+  return result;
+}
+
+/* Given VERSION -- a three-component OS X version represented as an array of
+   non-negative integers -- return a statically-allocated string suitable for
+   the modern __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.  If VERSION
+   is invalid, return NULL.
+
+   The modern format is a six-character string -- two chars for each component,
+   with zero-padding if necessary (for example, {10,10,1} produces "101001"). If
+   VERSION contains numbers greater than 99, it is rejected.  */
+
 static const char *
-version_as_macro (void)
+version_as_modern_macro (const unsigned long *version)
 {
-  static char result[7] = "1000";
-  int minorDigitIdx;
+  unsigned long major, minor, tiny;
+  static char result[7];
+
+  major = version[MAJOR];
+  minor = version[MINOR];
+  tiny = version[TINY];
+
+  if (major > 99 || minor > 99 || tiny > 99)
+    return NULL;
+
+  if (sprintf (result, "%02lu%02lu%02lu", major, minor, tiny) != 6)
+    return NULL;
+
+  return result;
+}
 
-  if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
+/* Return the value of darwin_macosx_version_min, suitably formatted for the
+   __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.  Values representing
+   OS X 10.9 and earlier are encoded using the legacy four-character format,
+   while 10.10 and later use a modern six-character format.  (For example,
+   "10.9" produces "1090", and "10.10.1" produces "101001".)  If
+   darwin_macosx_version_min is invalid and cannot be coerced into a valid
+   form, print a warning and return "1000".  */
+
+static const char *
+macosx_version_as_macro (void)
+{
+  const unsigned long *version_array;
+  const char *version_macro;
+
+  version_array = parse_version (darwin_macosx_version_min);
+  if (!version_array)
     goto fail;
-  if (! ISDIGIT (darwin_macosx_version_min[3]))
+
+  if (version_array[MAJOR] != 10)
     goto fail;
 
-  minorDigitIdx = 3;
-  result[2] = darwin_macosx_version_min[minorDigitIdx++];
-  if (ISDIGIT (darwin_macosx_version_min[minorDigitIdx]))
-  {
-    /* Starting with OS X 10.10, the macro ends '00' rather than '0',
-       i.e. 10.10.x becomes 101000 rather than 10100.  */
-    result[3] = darwin_macosx_version_min[minorDigitIdx++];
-    result[4] = '0';
-    result[5] = '0';
-    result[6] = '\0';
-  }
-  if (darwin_macosx_version_min[minorDigitIdx] != '\0'
-      && darwin_macosx_version_min[minorDigitIdx] != '.')
+  if (version_array[MINOR] < 10)
+    version_macro = version_as_legacy_macro (version_array);
+  else
+    version_macro = version_as_modern_macro (version_array);
+
+  if (!version_macro)
     goto fail;
 
-  return result;
+  return version_macro;
 
  fail:
   error ("unknown value %qs of -mmacosx-version-min",
-        darwin_macosx_version_min);
+         darwin_macosx_version_min);
   return "1000";
 }
 
@@ -656,7 +772,7 @@ darwin_cpp_builtins (cpp_reader *pfile)
     builtin_define ("__CONSTANT_CFSTRINGS__");
 
   builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
-                            version_as_macro(), false);
+                            macosx_version_as_macro(), false);
 
   /* Since we do not (at 4.6) support ObjC gc for the NeXT runtime, the
      following will cause a syntax error if one tries to compile gc attributed
index 84b9fab017e957aafef22402bd8de63701c733ca..22e6021fb685f6811778fca2baa91e142cb6b45e 100644 (file)
@@ -1,3 +1,17 @@
+2015-05-28  Lawrence Velázquez  <vq@larryv.me>
+
+       PR target/63810
+       * gcc.dg/darwin-minversion-3.c: Update testcase.
+       * gcc.dg/darwin-minversion-4.c: Ditto.
+       * gcc.dg/darwin-minversion-5.c: New testcase.
+       * gcc.dg/darwin-minversion-6.c: Ditto.
+       * gcc.dg/darwin-minversion-7.c: Ditto.
+       * gcc.dg/darwin-minversion-8.c: Ditto.
+       * gcc.dg/darwin-minversion-9.c: Ditto.
+       * gcc.dg/darwin-minversion-10.c: Ditto.
+       * gcc.dg/darwin-minversion-11.c: Ditto.
+       * gcc.dg/darwin-minversion-12.c: Ditto.
+
 2015-05-28  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        PR rtl-optimization/66168
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-10.c b/gcc/testsuite/gcc.dg/darwin-minversion-10.c
new file mode 100644 (file)
index 0000000..bf95d46
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/63810: Test that an OS X minimum version with zero-padded
+   minor and tiny numbers less than 10 produces the correct
+   four-character macro.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=10.07.02" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1072
+  fail me;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-11.c b/gcc/testsuite/gcc.dg/darwin-minversion-11.c
new file mode 100644 (file)
index 0000000..a03e707
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/63810: Test that an OS X minimum version with outrageous
+   zero-padding and a minor number greater than 9 still produces
+   a six-character macro.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=00010.010.0000098" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101098
+  fail me;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-12.c b/gcc/testsuite/gcc.dg/darwin-minversion-12.c
new file mode 100644 (file)
index 0000000..4c2ce38
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/63810: Test that an OS X minimum version with outrageous
+   zero-padding and a minor number less than 10 still produces
+   a four-character macro.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=010.008.000031" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1089
+  fail me;
+#endif
+  return 0;
+}
index 4fcb9693cd4888a4e0795ce1506c45659c47cd15..d1795e74a692410db42266c1ba2bb7fbcc950102 100644 (file)
@@ -1,11 +1,11 @@
-/* Test that most-minor versions greater than 9 work.  */
-/* { dg-options "-mmacosx-version-min=10.4.10" } */
+/* Test that most minor versions less than 10 work.  */
+/* { dg-options "-mmacosx-version-min=10.4.1" } */
 /* { dg-do compile { target *-*-darwin* } } */
 
 int
 main ()
 {
-#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1040
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1041
   fail me;
 #endif
   return 0;
index 1cb42ebe3e9eb8692cc326d120405d159d387082..1481aa53dc755f442a2cb2446732343f3afc7508 100644 (file)
@@ -1,11 +1,11 @@
-/* Test that major versions greater than 9 work and have the additional 0.  */
-/* { dg-options "-mmacosx-version-min=10.10.0" } */
+/* Test that minor versions greater than 9 produce a six-character macro.  */
+/* { dg-options "-mmacosx-version-min=10.10.1" } */
 /* { dg-do compile { target *-*-darwin* } } */
 
 int
 main ()
 {
-#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101000
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101001
   fail me;
 #endif
   return 0;
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-5.c b/gcc/testsuite/gcc.dg/darwin-minversion-5.c
new file mode 100644 (file)
index 0000000..09a9d72
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/63810: Test that an OS X minimum version with minor number
+   less than 10 and tiny number greater than 9 produces a four-character
+   macro with the tiny number clamped to 9.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=10.9.10" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1099
+  fail me;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-6.c b/gcc/testsuite/gcc.dg/darwin-minversion-6.c
new file mode 100644 (file)
index 0000000..e01fa72
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/63810: Test that tiny numbers are preserved in
+   six-character macros.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=10.10.11" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101011
+  fail me;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-7.c b/gcc/testsuite/gcc.dg/darwin-minversion-7.c
new file mode 100644 (file)
index 0000000..72f495b
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/63810: Test that tiny numbers less than 10 are preserved in
+   four-character macros.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=10.9.1" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1091
+  fail me;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-8.c b/gcc/testsuite/gcc.dg/darwin-minversion-8.c
new file mode 100644 (file)
index 0000000..5982df5
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/63810: Test that an OS X minimum version with minor number
+   greater than 9 and no tiny number produces a six-character macro
+   ending in "00".  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=10.11" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101100
+  fail me;
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-9.c b/gcc/testsuite/gcc.dg/darwin-minversion-9.c
new file mode 100644 (file)
index 0000000..d781783
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/63810: Test that an OS X minimum version with a zero-padded
+   minor number less than 10 produces a four-character macro.  */
+/* Added by Lawrence Velázquez <vq@larryv.me>.  */
+
+/* { dg-options "-mmacosx-version-min=10.08.4" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+int
+main ()
+{
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1084
+  fail me;
+#endif
+  return 0;
+}