https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63810
Lawrence Velázquez <larryv at macports dot org> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #33975|updated trunk patch that |patch against trunk for description|satisfies |handling deployment targets |-Werror=sign-compare |correctly --- Comment #9 from Lawrence Velázquez <larryv at macports dot org> --- Comment on attachment 33975 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33975 patch against trunk for handling deployment targets correctly >diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c >index ffefa37..311cdd4 100644 >--- a/gcc/config/darwin-c.c >+++ b/gcc/config/darwin-c.c >@@ -590,42 +590,167 @@ 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 a version string, return the version as a statically-allocated >+ array of three non-negative integers. If the version string is >+ invalid, return null. >+ >+ Version strings 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 >+ integer. Omitted tokens are treated as 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} */ >+ >+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 a three-component 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 the 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"). Versions containing numbers greater >+ than 99 are 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 = version[MAJOR]; >+ unsigned long minor = version[MINOR]; >+ unsigned long tiny = version[TINY]; >+ static char result[sizeof "9999"]; > >- if (strncmp (darwin_macosx_version_min, "10.", 3) != 0) >+ 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; >+} >+ >+/* Given a three-component 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 the >+ 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"). Versions >+ containing numbers greater than 99 are rejected. */ >+ >+static const char * >+version_as_modern_macro (const unsigned long *version) >+{ >+ unsigned long major = version[MAJOR]; >+ unsigned long minor = version[MINOR]; >+ unsigned long tiny = version[TINY]; >+ static char result[sizeof "999999"]; >+ >+ if (major > 99 || minor > 99 || tiny > 99) >+ return NULL; >+ >+ /* NOTE: 'sizeof "foo"' returns size of char array, but >+ 'sizeof ((x > y) ? "foo" : "bar")' returns size of char pointer. */ >+ /* 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. (For >+ example, "10.9" produces "1090", and "10.10.1" produces "101001".) >+ If its value 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])) >+ >+ /* Do not assume that the major number will always be exactly 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"; > } > >@@ -647,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..1f1eafa >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-10.c >@@ -0,0 +1,16 @@ >+/* PR 63810: Test that a version with a zero-padded minor number < 10 >+ and a zero-padded tiny number < 10 produces the correct >+ four-character macro. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..39cf0b5 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-11.c >@@ -0,0 +1,15 @@ >+/* PR 63810: Test that a version with outrageous zero-padding and >+ a minor number > 9 still produces a six-character macro. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..ea52d30 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-12.c >@@ -0,0 +1,15 @@ >+/* PR 63810: Test that a version with outrageous zero-padding and >+ a minor number < 10 still produces a four-character macro. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..4a67f85 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 < 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..ace739e 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 > 9 produce a 6-digit 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..31b5c3d >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-5.c >@@ -0,0 +1,15 @@ >+/* PR 63810: Test that a version with minor number < 10 and tiny number > 9 >+ produces a four-character macro with the tiny number clamped to 9. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..1455237 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-6.c >@@ -0,0 +1,14 @@ >+/* PR 63810: Test that tiny numbers are preserved in six-character macros. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..c4d6986 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-7.c >@@ -0,0 +1,15 @@ >+/* PR 63810: Test that tiny numbers < 10 are preserved in four-character >+ macros. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..fa3b614 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-8.c >@@ -0,0 +1,16 @@ >+/* PR 63810: Test that a version with minor number > 9 and no tiny >+ number produces a six-character macro with "00" as the last two >+ characters. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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..5f8990a >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/darwin-minversion-9.c >@@ -0,0 +1,15 @@ >+/* PR 63810: Test that a version with a zero-padded minor number < 10 >+ produces a four-character macro. */ >+/* Added by Lawrence Velázquez <lar...@macports.org>. */ >+ >+/* { 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; >+}