public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Handle OS X deployment targets correctly
@ 2015-05-15  6:46 Lawrence Velázquez
  2015-05-15 22:54 ` Mike Stump
  2015-05-20 22:13 ` [PATCH v2] " Lawrence Velázquez
  0 siblings, 2 replies; 4+ messages in thread
From: Lawrence Velázquez @ 2015-05-15  6:46 UTC (permalink / raw)
  To: gcc-patches

As described in PR target/63810, this addresses several problems with
the validation and encoding of deployment target version strings for the
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.  There are
currently four testcases exercising inputs to -mmacosx-version-min
(gcc/testsuite/gcc.dg/darwin-minversion-*), but they provide minimal
coverage, and one is incorrect.

* The tiny number is now respected, if present.  Thus "10.9.4"
  correctly becomes "1094" instead of "1090", and "10.10.1" becomes
  "101001" instead of "101000".
* Zero padding is now ignored.  Thus "10.09" correctly becomes "1090"
  instead of "100900", and "10.00010" becomes "101000" instead of being
  treated as invalid.
* Deployment targets that are missing minor and tiny numbers are no
  longer considered invalid.  Thus "10" is treated as "10.0.0", which
  becomes "1000" without causing an error.

With this change, trunk matches the behavior of Apple LLVM Compiler
6.1.0 on 8,451 of 8,464 generated test inputs.  (The discrepancies are
due to a bug in Clang.)  I don't notice any testsuite regressions on
OS X 10.10 Yosemite x86-64.

2015-05-15  Lawrence Velázquez  <vq@larryv.me>

	PR target/63810
	* gcc/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.
	* gcc/testsuite/gcc.dg/darwin-minversion-3.c: Update testcase.
	* gcc/testsuite/gcc.dg/darwin-minversion-4.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-5.c: New testcase.
	* gcc/testsuite/gcc.dg/darwin-minversion-6.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-7.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-8.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-9.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-10.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-11.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-12.c: Ditto.
---
Please Cc me in any replies, as I'm not subscribed to the list.

 gcc/config/darwin-c.c                       | 190 ++++++++++++++++++++++++----
 gcc/testsuite/gcc.dg/darwin-minversion-10.c |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-11.c |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-12.c |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-3.c  |   6 +-
 gcc/testsuite/gcc.dg/darwin-minversion-4.c  |   6 +-
 gcc/testsuite/gcc.dg/darwin-minversion-5.c  |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-6.c  |  15 +++
 gcc/testsuite/gcc.dg/darwin-minversion-7.c  |  15 +++
 gcc/testsuite/gcc.dg/darwin-minversion-8.c  |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-9.c  |  15 +++
 11 files changed, 295 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-10.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-11.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-12.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-5.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-6.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-7.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-8.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-9.c

diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index 3803e75..cf38416 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -599,42 +599,180 @@ 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];
+
+  if (!version_str)
+    return NULL;
+
+  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.  Major numbers are
+   zero-padded if necessary.  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_macro (void)
+version_as_legacy_macro (const unsigned long *version)
 {
-  static char result[7] = "1000";
-  int minorDigitIdx;
+  unsigned long major, minor, tiny;
+  static char result[sizeof "9999"];
+
+  if (!version)
+    return NULL;
+
+  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);
+
+  /* NOTE: Cast result of sizeof so that result of sprintf is not
+     converted to an unsigned type.  */
+  if (sprintf (result, "%02lu%lu%lu", major, minor, tiny)
+      != (int) sizeof "9999" - 1)
+    return NULL;
+
+  return result;
+}
 
-  if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
+/* 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 or the
+   __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ macro.  If VERSION is
+   invalid, return NULL.
+
+   The modern format is a five- or six-character string -- one or two chars for
+   the major number and two each for the minor and tiny numbers, which are
+   zero-padded if necessary (for example, {8,1,0} produces "80100", and
+   {10,10,1} produces "101001").  If VERSION contains numbers greater than 99,
+   it is rejected.  */
+
+static const char *
+version_as_modern_macro (const unsigned long *version)
+{
+  unsigned long major, minor, tiny;
+  static char result[sizeof "999999"];
+
+  if (!version)
+    return NULL;
+
+  major = version[MAJOR];
+  minor = version[MINOR];
+  tiny = version[TINY];
+
+  if (major > 99 || minor > 99 || tiny > 99)
+    return NULL;
+
+  /* NOTE: Cannot use 'sizeof ((x > y) ? "foo" : "bar")' because that
+     returns the size of a char pointer instead of the size of the
+     chosen char array.  */
+  /* NOTE: Cast result of sizeof so that result of sprintf is not
+     converted to an unsigned type.  */
+  if (sprintf (result, "%lu%02lu%02lu", major, minor, tiny)
+      != (int) ((major > 9) ? sizeof "999999" : sizeof "99999") - 1)
+    return NULL;
+
+  return result;
+}
+
+/* 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]))
+
+  /* Allow for future major numbers greater than 10.  */
+  if (version_array[MAJOR] < 10 || 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[MAJOR] == 10 && 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 +794,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
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-10.c b/gcc/testsuite/gcc.dg/darwin-minversion-10.c
new file mode 100644
index 0000000..bf95d46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-10.c
@@ -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
index 0000000..a03e707
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-11.c
@@ -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
index 0000000..4c2ce38
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-12.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-3.c b/gcc/testsuite/gcc.dg/darwin-minversion-3.c
index 4fcb969..d1795e7 100644
--- a/gcc/testsuite/gcc.dg/darwin-minversion-3.c
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-3.c
@@ -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;
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-4.c b/gcc/testsuite/gcc.dg/darwin-minversion-4.c
index 1cb42eb..1481aa5 100644
--- a/gcc/testsuite/gcc.dg/darwin-minversion-4.c
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-4.c
@@ -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
index 0000000..09a9d72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-5.c
@@ -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
index 0000000..e01fa72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-6.c
@@ -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
index 0000000..72f495b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-7.c
@@ -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
index 0000000..5982df5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-8.c
@@ -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
index 0000000..d781783
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-9.c
@@ -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;
+}
-- 
2.4.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Handle OS X deployment targets correctly
  2015-05-15  6:46 [PATCH] Handle OS X deployment targets correctly Lawrence Velázquez
@ 2015-05-15 22:54 ` Mike Stump
  2015-05-20 22:13 ` [PATCH v2] " Lawrence Velázquez
  1 sibling, 0 replies; 4+ messages in thread
From: Mike Stump @ 2015-05-15 22:54 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: gcc-patches

On May 14, 2015, at 11:42 PM, Lawrence Velázquez <vq@larryv.me> wrote:
> As described in PR target/63810, this addresses several problems

> With this change, trunk matches the behavior of Apple LLVM Compiler
> 6.1.0 on 8,451 of 8,464 generated test inputs.  (The discrepancies are
> due to a bug in Clang.)  I don't notice any testsuite regressions on
> OS X 10.10 Yosemite x86-64.

Ok.

You will need to repost as an attachment, as Apple never quite figured out how to send email.  Hopes springs eternal that one day, they might wake up and figure out how to send email.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2] Handle OS X deployment targets correctly
  2015-05-15  6:46 [PATCH] Handle OS X deployment targets correctly Lawrence Velázquez
  2015-05-15 22:54 ` Mike Stump
@ 2015-05-20 22:13 ` Lawrence Velázquez
  2015-05-28 12:33   ` Mike Stump
  1 sibling, 1 reply; 4+ messages in thread
From: Lawrence Velázquez @ 2015-05-20 22:13 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3373 bytes --]


As described in PR target/63810, this addresses several problems with
the validation and encoding of deployment target version strings for the
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.  There are
currently four testcases exercising inputs to -mmacosx-version-min
(gcc/testsuite/gcc.dg/darwin-minversion-*), but they provide minimal
coverage, and one is incorrect.

* The tiny number is now respected, if present.  Thus "10.9.4"
  correctly becomes "1094" instead of "1090", and "10.10.1" becomes
  "101001" instead of "101000".
* Zero padding is now ignored.  Thus "10.09" correctly becomes "1090"
  instead of "100900", and "10.00010" becomes "101000" instead of being
  treated as invalid.
* Deployment targets that are missing minor and tiny numbers are no
  longer considered invalid.  Thus "10" is treated as "10.0.0", which
  becomes "1000" without causing an error.

With this change, trunk matches the behavior of Apple LLVM Compiler
6.1.0 on 8,451 of 8,464 generated test inputs.  (The discrepancies are
due to a bug in Clang.)  I don't notice any testsuite regressions on
OS X 10.10 Yosemite x86-64.

2015-05-15  Lawrence Velázquez  <vq@larryv.me>

	PR target/63810
	* gcc/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.
	* gcc/testsuite/gcc.dg/darwin-minversion-3.c: Update testcase.
	* gcc/testsuite/gcc.dg/darwin-minversion-4.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-5.c: New testcase.
	* gcc/testsuite/gcc.dg/darwin-minversion-6.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-7.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-8.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-9.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-10.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-11.c: Ditto.
	* gcc/testsuite/gcc.dg/darwin-minversion-12.c: Ditto.
---
Re-roll to address patch review on PR target/63810.  Provided as
text/x-patch attachment to accommodate Apple Mail wonkiness.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63810#c21

 gcc/config/darwin-c.c                       | 168 +++++++++++++++++++++++-----
 gcc/testsuite/gcc.dg/darwin-minversion-10.c |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-11.c |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-12.c |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-3.c  |   6 +-
 gcc/testsuite/gcc.dg/darwin-minversion-4.c  |   6 +-
 gcc/testsuite/gcc.dg/darwin-minversion-5.c  |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-6.c  |  15 +++
 gcc/testsuite/gcc.dg/darwin-minversion-7.c  |  15 +++
 gcc/testsuite/gcc.dg/darwin-minversion-8.c  |  16 +++
 gcc/testsuite/gcc.dg/darwin-minversion-9.c  |  15 +++
 11 files changed, 273 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-10.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-11.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-12.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-5.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-6.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-7.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-8.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-minversion-9.c


[-- Attachment #2: v2-0001-Handle-OS-X-deployment-targets-correctly.patch --]
[-- Type: text/x-patch, Size: 13479 bytes --]

diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index 3803e75..6d49f05 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -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
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-10.c b/gcc/testsuite/gcc.dg/darwin-minversion-10.c
new file mode 100644
index 0000000..bf95d46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-10.c
@@ -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
index 0000000..a03e707
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-11.c
@@ -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
index 0000000..4c2ce38
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-12.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-3.c b/gcc/testsuite/gcc.dg/darwin-minversion-3.c
index 4fcb969..d1795e7 100644
--- a/gcc/testsuite/gcc.dg/darwin-minversion-3.c
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-3.c
@@ -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;
diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-4.c b/gcc/testsuite/gcc.dg/darwin-minversion-4.c
index 1cb42eb..1481aa5 100644
--- a/gcc/testsuite/gcc.dg/darwin-minversion-4.c
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-4.c
@@ -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
index 0000000..09a9d72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-5.c
@@ -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
index 0000000..e01fa72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-6.c
@@ -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
index 0000000..72f495b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-7.c
@@ -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
index 0000000..5982df5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-8.c
@@ -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
index 0000000..d781783
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-minversion-9.c
@@ -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;
+}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] Handle OS X deployment targets correctly
  2015-05-20 22:13 ` [PATCH v2] " Lawrence Velázquez
@ 2015-05-28 12:33   ` Mike Stump
  0 siblings, 0 replies; 4+ messages in thread
From: Mike Stump @ 2015-05-28 12:33 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: gcc-patches

On May 20, 2015, at 2:57 PM, Lawrence Velázquez <vq@larryv.me> wrote:
> 2015-05-15  Lawrence Velázquez  <vq@larryv.me>
> 
> 	PR target/63810
> 	* gcc/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.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-3.c: Update testcase.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-4.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-5.c: New testcase.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-6.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-7.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-8.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-9.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-10.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-11.c: Ditto.
> 	* gcc/testsuite/gcc.dg/darwin-minversion-12.c: Ditto.

Committed revision 223808.

Thanks for all your work.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-05-28 12:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-15  6:46 [PATCH] Handle OS X deployment targets correctly Lawrence Velázquez
2015-05-15 22:54 ` Mike Stump
2015-05-20 22:13 ` [PATCH v2] " Lawrence Velázquez
2015-05-28 12:33   ` Mike Stump

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).