View | Details | Return to bug 63810 | Differences between
and this patch

Collapse All | Expand All

(-)a/gcc/config/darwin-c.c (-26 / +164 lines)
Lines 570-611 find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp) Link Here
570
  return 0;
570
  return 0;
571
}
571
}
572
572
573
/* Return the value of darwin_macosx_version_min suitable for the
573
/*  Given a version string, return the version as a statically-allocated
574
   __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro, so '10.4.2'
574
    array of three non-negative integers.  If the version string is
575
   becomes 1040 and '10.10.0' becomes 101000.  The lowest digit is
575
    invalid, return null.
576
   always zero, as is the second lowest for '10.10.x' and above.
576
577
   Print a warning if the version number can't be understood.  */
577
    Version strings must consist of one, two, or three tokens, each
578
    separated by a single period.  Each token must contain only the
579
    characters '0' through '9' and is converted to an equivalent
580
    integer.  Omitted tokens are treated as zeros.  For example:
581
582
        "10"              becomes   {10,0,0}
583
        "10.10"           becomes   {10,10,0}
584
        "10.10.1"         becomes   {10,10,1}
585
        "10.000010.1"     becomes   {10,10,1}
586
        "10.010.001"      becomes   {10,10,1}
587
        "000010.10.00001" becomes   {10,10,1}  */
588
589
enum version_components { MAJOR, MINOR, TINY };
590
591
static const unsigned long *
592
parse_version (const char *version_str)
593
{
594
  size_t version_len;
595
  char *end;
596
  static unsigned long version_array[3];
597
598
  if (! version_str)
599
    return NULL;
600
601
  version_len = strlen (version_str);
602
  if (version_len < 1)
603
    return NULL;
604
605
  /* Version string must consist of digits and periods only.  */
606
  if (strspn (version_str, "0123456789.") != version_len)
607
    return NULL;
608
609
  if (! ISDIGIT (version_str[0]) || ! ISDIGIT (version_str[version_len - 1]))
610
    return NULL;
611
612
  version_array[MAJOR] = strtoul (version_str, &end, 10);
613
  version_str = end + ((*end == '.') ? 1 : 0);
614
615
  /* Version string must not contain adjacent periods.  */
616
  if (*version_str == '.')
617
    return NULL;
618
619
  version_array[MINOR] = strtoul (version_str, &end, 10);
620
  version_str = end + ((*end == '.') ? 1 : 0);
621
622
  version_array[TINY] = strtoul (version_str, &end, 10);
623
624
  /* Version string must contain no more than three tokens.  */
625
  if (*end != '\0')
626
    return NULL;
627
628
  return version_array;
629
}
630
631
/*  Given a three-component version represented as an array of
632
    non-negative integers, return a statically-allocated string suitable
633
    for the legacy __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.
634
    If the version is invalid and cannot be coerced into a valid form,
635
    return null.
636
637
    The legacy format is a four-character string -- two chars for the
638
    major number and one each for the minor and tiny numbers.  Major
639
    numbers are zero-padded if necessary.  Minor and tiny numbers from
640
    10 through 99 are permitted but are clamped to 9 (for example,
641
    {10,9,10} produces "1099").  Versions containing numbers greater
642
    than 99 are rejected.  */
643
578
static const char *
644
static const char *
579
version_as_macro (void)
645
version_as_legacy_macro (const unsigned long *version)
580
{
646
{
581
  static char result[7] = "1000";
647
  unsigned long major, minor, tiny;
582
  int minorDigitIdx;
648
  static char result[sizeof "9999"];
649
650
  if (! version)
651
    return NULL;
652
653
  major = version[MAJOR];
654
  minor = version[MINOR];
655
  tiny = version[TINY];
656
657
  if (major > 99 || minor > 99 || tiny > 99)
658
    return NULL;
659
660
  minor = ((minor > 9) ? 9 : minor);
661
  tiny = ((tiny > 9) ? 9 : tiny);
662
663
  /* NOTE: Cast result of sizeof so that result of sprintf is not
664
     converted to an unsigned type.  */
665
  if (sprintf (result, "%02lu%lu%lu", major, minor, tiny)
666
      != (int) sizeof "9999" - 1)
667
    return NULL;
668
669
  return result;
670
}
583
671
584
  if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
672
/*  Given a three-component version represented as an array of
673
    non-negative integers, return a statically-allocated string suitable
674
    for the modern __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro
675
    or the __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ macro.  If the
676
    version is invalid, return null.
677
678
    The modern format is a five- or six-character string -- one or two
679
    chars for the major number and two each for the minor and tiny
680
    numbers, which are zero-padded if necessary (for example, {8,1,0}
681
    produces "80100", and {10,10,1} produces "101001").  Versions
682
    containing numbers greater than 99 are rejected.  */
683
684
static const char *
685
version_as_modern_macro (const unsigned long *version)
686
{
687
  unsigned long major, minor, tiny;
688
  static char result[sizeof "999999"];
689
690
  if (! version)
691
    return NULL;
692
693
  major = version[MAJOR];
694
  minor = version[MINOR];
695
  tiny = version[TINY];
696
697
  if (major > 99 || minor > 99 || tiny > 99)
698
    return NULL;
699
700
  /* NOTE: 'sizeof ((x > y) ? "foo" : "bar")' returns size of char
701
     pointer instead of char array, so use
702
     '(x > y) ? sizeof "foo" : sizeof "bar"' instead.  */
703
  /* NOTE: Cast result of sizeof so that result of sprintf is not
704
     converted to an unsigned type.  */
705
  if (sprintf (result, "%lu%02lu%02lu", major, minor, tiny)
706
      != (int) ((major > 9) ? sizeof "999999" : sizeof "99999") - 1)
707
    return NULL;
708
709
  return result;
710
}
711
712
/*  Return the value of darwin_macosx_version_min, suitably formatted
713
    for the __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ macro.  Values
714
    representing OS X 10.9 and earlier are encoded using the legacy
715
    four-character format, while 10.10 and later use a modern
716
    six-character format.  (For example, "10.9" produces "1090", and
717
    "10.10.1" produces "101001".)  If the value is invalid and cannot be
718
    coerced into a valid form, print a warning and return "1000".  */
719
720
static const char *
721
macosx_version_as_macro (void)
722
{
723
  const unsigned long *version_array;
724
  const char *version_macro;
725
726
  version_array = parse_version (darwin_macosx_version_min);
727
  if (! version_array)
585
    goto fail;
728
    goto fail;
586
  if (! ISDIGIT (darwin_macosx_version_min[3]))
729
730
  /* Do not assume that the major number will always be exactly 10.  */
731
  if (version_array[MAJOR] < 10 || version_array[MAJOR] > 10)
587
    goto fail;
732
    goto fail;
588
733
589
  minorDigitIdx = 3;
734
  if (version_array[MAJOR] == 10 && version_array[MINOR] < 10)
590
  result[2] = darwin_macosx_version_min[minorDigitIdx++];
735
    version_macro = version_as_legacy_macro (version_array);
591
  if (ISDIGIT (darwin_macosx_version_min[minorDigitIdx]))
736
  else
592
  {
737
    version_macro = version_as_modern_macro (version_array);
593
    /* Starting with OS X 10.10, the macro ends '00' rather than '0',
738
594
       i.e. 10.10.x becomes 101000 rather than 10100.  */
739
  if (! version_macro)
595
    result[3] = darwin_macosx_version_min[minorDigitIdx++];
596
    result[4] = '0';
597
    result[5] = '0';
598
    result[6] = '\0';
599
  }
600
  if (darwin_macosx_version_min[minorDigitIdx] != '\0'
601
      && darwin_macosx_version_min[minorDigitIdx] != '.')
602
    goto fail;
740
    goto fail;
603
741
604
  return result;
742
  return version_macro;
605
743
606
 fail:
744
 fail:
607
  error ("unknown value %qs of -mmacosx-version-min",
745
  error ("unknown value %qs of -mmacosx-version-min",
608
	 darwin_macosx_version_min);
746
         darwin_macosx_version_min);
609
  return "1000";
747
  return "1000";
610
}
748
}
611
749
Lines 627-633 darwin_cpp_builtins (cpp_reader *pfile) Link Here
627
    builtin_define ("__CONSTANT_CFSTRINGS__");
765
    builtin_define ("__CONSTANT_CFSTRINGS__");
628
766
629
  builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
767
  builtin_define_with_value ("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__",
630
			     version_as_macro(), false);
768
			     macosx_version_as_macro(), false);
631
769
632
  /* Since we do not (at 4.6) support ObjC gc for the NeXT runtime, the
770
  /* Since we do not (at 4.6) support ObjC gc for the NeXT runtime, the
633
     following will cause a syntax error if one tries to compile gc attributed
771
     following will cause a syntax error if one tries to compile gc attributed
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-10.c (+16 lines)
Line 0 Link Here
1
/* PR target/63810: Test that a version with a zero-padded minor
2
   number < 10 and a zero-padded tiny number < 10 produces the correct
3
   four-character macro.  */
4
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
5
6
/* { dg-options "-mmacosx-version-min=10.07.02" } */
7
/* { dg-do compile { target *-*-darwin* } } */
8
9
int
10
main ()
11
{
12
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1072
13
  fail me;
14
#endif
15
  return 0;
16
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-11.c (+15 lines)
Line 0 Link Here
1
/* PR target/63810: Test that a version with outrageous zero-padding and
2
   a minor number > 9 still produces a six-character macro.  */
3
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
4
5
/* { dg-options "-mmacosx-version-min=00010.010.0000098" } */
6
/* { dg-do compile { target *-*-darwin* } } */
7
8
int
9
main ()
10
{
11
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101098
12
  fail me;
13
#endif
14
  return 0;
15
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-12.c (+15 lines)
Line 0 Link Here
1
/* PR target/63810: Test that a version with outrageous zero-padding and
2
   a minor number < 10 still produces a four-character macro.  */
3
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
4
5
/* { dg-options "-mmacosx-version-min=010.008.000031" } */
6
/* { dg-do compile { target *-*-darwin* } } */
7
8
int
9
main ()
10
{
11
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1089
12
  fail me;
13
#endif
14
  return 0;
15
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-3.c (-3 / +3 lines)
Lines 1-11 Link Here
1
/* Test that most-minor versions greater than 9 work.  */
1
/* Test that most minor versions < 10 work.  */
2
/* { dg-options "-mmacosx-version-min=10.4.10" } */
2
/* { dg-options "-mmacosx-version-min=10.4.1" } */
3
/* { dg-do compile { target *-*-darwin* } } */
3
/* { dg-do compile { target *-*-darwin* } } */
4
4
5
int
5
int
6
main ()
6
main ()
7
{
7
{
8
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1040
8
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1041
9
  fail me;
9
  fail me;
10
#endif
10
#endif
11
  return 0;
11
  return 0;
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-4.c (-3 / +3 lines)
Lines 1-11 Link Here
1
/* Test that major versions greater than 9 work and have the additional 0.  */
1
/* Test that minor versions > 9 produce a six-character macro.  */
2
/* { dg-options "-mmacosx-version-min=10.10.0" } */
2
/* { dg-options "-mmacosx-version-min=10.10.1" } */
3
/* { dg-do compile { target *-*-darwin* } } */
3
/* { dg-do compile { target *-*-darwin* } } */
4
4
5
int
5
int
6
main ()
6
main ()
7
{
7
{
8
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101000
8
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101001
9
  fail me;
9
  fail me;
10
#endif
10
#endif
11
  return 0;
11
  return 0;
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-5.c (+16 lines)
Line 0 Link Here
1
/* PR target/63810: Test that a version with minor number < 10 and tiny
2
   number > 9 produces a four-character macro with the tiny number
3
   clamped to 9.  */
4
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
5
6
/* { dg-options "-mmacosx-version-min=10.9.10" } */
7
/* { dg-do compile { target *-*-darwin* } } */
8
9
int
10
main ()
11
{
12
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1099
13
  fail me;
14
#endif
15
  return 0;
16
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-6.c (+15 lines)
Line 0 Link Here
1
/* PR target/63810: Test that tiny numbers are preserved in
2
   six-character macros.  */
3
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
4
5
/* { dg-options "-mmacosx-version-min=10.10.11" } */
6
/* { dg-do compile { target *-*-darwin* } } */
7
8
int
9
main ()
10
{
11
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101011
12
  fail me;
13
#endif
14
  return 0;
15
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-7.c (+15 lines)
Line 0 Link Here
1
/* PR target/63810: Test that tiny numbers < 10 are preserved in
2
   four-character macros.  */
3
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
4
5
/* { dg-options "-mmacosx-version-min=10.9.1" } */
6
/* { dg-do compile { target *-*-darwin* } } */
7
8
int
9
main ()
10
{
11
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1091
12
  fail me;
13
#endif
14
  return 0;
15
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-8.c (+15 lines)
Line 0 Link Here
1
/* PR target/63810: Test that a version with minor number > 9 and no
2
   tiny number produces a six-character macro ending in "00".  */
3
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
4
5
/* { dg-options "-mmacosx-version-min=10.11" } */
6
/* { dg-do compile { target *-*-darwin* } } */
7
8
int
9
main ()
10
{
11
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 101100
12
  fail me;
13
#endif
14
  return 0;
15
}
(-)a/gcc/testsuite/gcc.dg/darwin-minversion-9.c (+15 lines)
Line 0 Link Here
1
/* PR target/63810: Test that a version with a zero-padded minor
2
   number < 10 produces a four-character macro.  */
3
/* Added by Lawrence Velázquez <larryv@macports.org>.  */
4
5
/* { dg-options "-mmacosx-version-min=10.08.4" } */
6
/* { dg-do compile { target *-*-darwin* } } */
7
8
int
9
main ()
10
{
11
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ != 1084
12
  fail me;
13
#endif
14
  return 0;
15
}

Return to bug 63810