https://537826.bugs.gentoo.org/attachment.cgi?id=394896
https://bugs.gentoo.org/show_bug.cgi?id=537826
Michael Weiser

Backport of https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=218873 (as
per https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61407) to correctly encode Mac
OS X versions >10.9 into __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__.
Extended to also encode patch level the way clang and Apple GCC 4.2.1 do.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63810 has a much more generic
patch. But it's not yet in-tree pending legal paperwork. Once that's done, we
can backport that.

--- gcc/libgcov.c
+++ gcc/libgcov.c
@@ -34,6 +34,14 @@
 #include "coretypes.h"
 #include "tm.h"
 
+/* to deal with XBC headers from 10.10 */
+#ifndef __has_extension
+#define __has_extension(x) 0
+#endif
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
 /* APPLE LOCAL begin instant off 6414141 */
 #if defined(__APPLE__) && !defined(__STATIC__) && !defined(__ppc__) && !defined(__ppc64__) && !defined(__arm__)
 #include <vproc.h>
--- gcc/config/darwin-driver.c.orig	2010-10-14 22:27:53.000000000 +0200
+++ gcc/config/darwin-driver.c	2015-01-25 21:15:09.000000000 +0100
@@ -174,8 +174,6 @@
   version_p = osversion + 1;
   if (ISDIGIT (*version_p))
     major_vers = major_vers * 10 + (*version_p++ - '0');
-  if (major_vers > 4 + 9)
-    goto parse_failed;
   if (*version_p++ != '.')
     goto parse_failed;
   version_pend = strchr(version_p, '.');
--- gcc/config/darwin-c.c.orig	2015-01-25 19:44:40.000000000 +0100
+++ gcc/config/darwin-c.c	2015-01-25 21:05:47.000000000 +0100
@@ -930,31 +930,91 @@
 
 /* Return the value of darwin_macosx_version_min suitable for the
    __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro,
-   so '10.4.2' becomes 1042.
+   so '10.4.2' becomes 1042 and '10.10.2' becomes 101002.
+   Cap patch level to 9 in the old format.
    Print a warning if the version number is not known.  */
 static const char *
 /* APPLE LOCAL ARM 5683689 */
 macosx_version_as_macro (void)
 {
-  static char result[] = "1000";
+  static char result[7] = "1000";
+  int inputindex = 3, outputindex = 2;
 
+  /* make sure version starts with "10." - makes sure we can safely start
+   * parsing at inputindex == 3 */
   if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
     goto fail;
+
+  /* first character of minor version needs to be digit */
   if (! ISDIGIT (darwin_macosx_version_min[3]))
     goto fail;
-  result[2] = darwin_macosx_version_min[3];
-  if (darwin_macosx_version_min[4] != '\0')
+
+  result[outputindex++] = darwin_macosx_version_min[inputindex++];
+
+  if (ISDIGIT (darwin_macosx_version_min[inputindex])) {
+    /* Starting with OS X 10.10, the macro ends '00' rather than '0',
+       i.e. 10.10.x becomes 101000 rather than 10100.  */
+    result[outputindex++] = darwin_macosx_version_min[inputindex++];
+    result[4] = '0';
+    result[5] = '0';
+    result[6] = '\0';
+  }
+
+  /* if we're out of input, leave patch level at 0 or 00 and finish */
+  if (darwin_macosx_version_min[inputindex] == '\0')
+    return result;
+
+  /* a dot *must* follow now */
+  if (darwin_macosx_version_min[inputindex++] != '.')
+     goto fail;
+
+  /* a digit must follow after the dot */
+  if (! ISDIGIT (darwin_macosx_version_min[inputindex]))
+     goto fail;
+
+  /* old-style macro */
+  if (outputindex == 3)
+  {
+    /* one-digit patch level */
+    if (darwin_macosx_version_min[inputindex + 1] == '\0')
     {
-      if (darwin_macosx_version_min[4] != '.')
-	goto fail;
-      if (! ISDIGIT (darwin_macosx_version_min[5]))
-	goto fail;
-      if (darwin_macosx_version_min[6] != '\0')
-	goto fail;
-      result[3] = darwin_macosx_version_min[5];
+      result[outputindex] = darwin_macosx_version_min[inputindex];
+      return result;
     }
-  else
-    result[3] = '0';
+
+    inputindex++;
+    if (! ISDIGIT (darwin_macosx_version_min[inputindex++]))
+      goto fail;
+
+    /* three digits? */
+    if (darwin_macosx_version_min[inputindex] != '\0')
+      goto fail;
+
+    /* no room for another digit. Traditional Apple GCC 4.2.1 doesn't accept
+     * it but current clang caps it to 9. We choose to be in line with clang. */
+    result[outputindex] = '9';
+    return result;
+  }
+
+  /* new-style macro */
+
+  /* leave a leading zero if only one digit is following */
+  if (darwin_macosx_version_min[inputindex + 1] == '\0') {
+    result[outputindex + 1] = darwin_macosx_version_min[inputindex];
+    return result;
+  }
+
+  result[outputindex++] = darwin_macosx_version_min[inputindex++];
+
+  /* a digit must follow now */
+  if (! ISDIGIT (darwin_macosx_version_min[inputindex]))
+     goto fail;
+
+  result[outputindex] = darwin_macosx_version_min[inputindex++];
+
+  /* no more input allowed */
+  if (darwin_macosx_version_min[inputindex] != '\0')
+    goto fail;
 
   return result;
 
