diff mbox

Bug 61407 - Build errors on latest OS X 10.10 Yosemite with Xcode 6 on GCC 4.8.3

Message ID 02D530CB-20AE-44AA-8D62-658F46915ACC@gmail.com
State New
Headers show

Commit Message

Илья Михальцов June 17, 2014, 11:09 a.m. UTC
Hello.

This patch fixes gcc build problems on the latest OS X 10.10 SDK beta (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61407)

fixincludes/ChangeLog
	* inclhack.def (darwin14_has_feature): New fix
	* fixincl.x: Regenerate
	* tests/base/Availability.h: Added

gcc/ChangeLog
	* config/darwin-c.c (version_as_macro): Added compatibility with
	OS X 10.10 macro version macro and triplet
	* config/darwin-driver.c (darwin_find_version_from_kernel): Bumped 
	max kernel version

libsanitizer/ChangeLog
	* sanitizer_common/sanitizer_platform_limits_posix.cc: Fixed
	32-bit compatible dirent struct for OS X
	* sanitizer_common/sanitizer_platform_limits_posix.h: Likewise

With regards, Ilya Mikhaltsou

Comments

Bernhard Reutner-Fischer June 17, 2014, 2:06 p.m. UTC | #1
On 17 June 2014 13:10:07 Илья Михальцов <morpheby@gmail.com> wrote:

> index 892ba35..39f795f 100644
> --- a/gcc/config/darwin-c.c
> +++ b/gcc/config/darwin-c.c
> @@ -572,20 +572,31 @@ find_subframework_header (cpp_reader *pfile, const 
> char *header, cpp_dir **dirp)
>
>  /* 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.  The lowest digit is always zero.
> -   Print a warning if the version number can't be understood.  */
> +   so '10.4.2' becomes 1040 and '10.10.0' becomes 101000.  The lowest
> +   digit is always zero. Print a warning if the version number
> +   can't be understood.  */
>  static const char *
>  version_as_macro (void)
>  {
> -  static char result[] = "1000";
> +  static char result[7] = "1000";
> +  int minorDigitIdx;
>
>    if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
>      goto fail;
>    if (! ISDIGIT (darwin_macosx_version_min[3]))
>      goto fail;
> -  result[2] = darwin_macosx_version_min[3];
> -  if (darwin_macosx_version_min[4] != '\0'
> -      && darwin_macosx_version_min[4] != '.')
> +
> +  minorDigitIdx = 3;
> +  result[2] = darwin_macosx_version_min[minorDigitIdx++];
> +  if (ISDIGIT(darwin_macosx_version_min[minorDigitIdx])) {
> +    /* Starting with 10.10 numeration for mactro changed */

What does "mactro" mean? macro?
Thanks,


Sent with AquaMail for Android
http://www.aqua-mail.com
Mike Stump June 17, 2014, 9:25 p.m. UTC | #2
On Jun 17, 2014, at 4:09 AM, Илья Михальцов <morpheby@gmail.com> wrote:
> This patch fixes gcc build problems on the latest OS X 10.10 SDK beta (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61407)

fix include hack to add:

> +#ifndef __has_feature
> +#define __has_feature(x) 0
> +#endif

So, I’d like to bring this up in the larger context of autoconf, portable code what style we’d like for people to write code in.

From a darwin .h file in /usr/include:

#if defined(__has_feature) && defined(__has_attribute)
    #if __has_attribute(deprecated)
        #define DEPRECATED_ATTRIBUTE        __attribute__((deprecated))
        #if __has_feature(attribute_deprecated_with_message)
            #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated(s)))
        #else
            #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated))
        #endif
    #else
        #define DEPRECATED_ATTRIBUTE
        #define DEPRECATED_MSG_ATTRIBUTE(s)
    #endif
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
    #define DEPRECATED_ATTRIBUTE        __attribute__((deprecated))
    #if (__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))
        #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated(s)))
    #else
        #define DEPRECATED_MSG_ATTRIBUTE(s) __attribute__((deprecated))
    #endif
#else

I think this serves as a great introduction to the feature and what it is, why it exists and what it attempts to do.  In short, give code writers an ability to smell a port via #if and or if (), and write portable code without using autoconf.  Yes, for some truly hard problems, this scheme breaks down, but if gcc and other vendor compilers follow the scheme and define these as appropriate, then users can make use of this scheme instead of autoconf.  It was code like #if defined(__GNUC__) that causes clang to lie and say it is gnuc, it does this, as the code doesn’t use a fine grained check for the feature, but rather a course grained check on __GNUC__ which is wrong, as other compilers implement __attribute__ and __attribute__((deprecated)) that are not gcc.

http://clang.llvm.org/docs/LanguageExtensions.html has the names for the things that clang defines.  In gcc, we could elect to use the same names and define them as appropriate for gcc.  I think if gcc did this, then the quoted fix isn’t necessary.  Also, if gcc doesn’t want to do this, it is reasonable for the darwin port to so define features, they tend to be large scale and slow moving and monotonic in nature, so the maintenance of them should be low in general.

What do people think?
diff mbox

Patch

diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index 6a1136c..b536080 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -4751,4 +4751,33 @@  fix = {
 
     test_text = "extern char *\tsprintf();";
 };
+
+/*
+ * Fix stdio.h using C++ __has_feature built-in on OS X 10.10
+ */
+fix = {
+    hackname  = darwin14_has_feature;
+    files     = Availability.h;
+    mach      = "*-*-darwin14.0*";
+    
+    c_fix     = wrap;
+    c_fix_arg = <<- _HasFeature_
+
+/*
+ * GCC doesn't support __has_feature built-in in C mode and
+ * using defined(__has_feature) && __has_feature in the same
+ * macro expression is not valid. So, easiest way is to define
+ * for this header __has_feature as a macro, returning 0, in case
+ * it is not defined internally
+ */
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+
+_HasFeature_;
+    
+    test_text = '';
+};
+
 /*EOF*/
diff --git a/fixincludes/tests/base/Availability.h b/fixincludes/tests/base/Availability.h
new file mode 100644
index 0000000..807c40d
--- /dev/null
+++ b/fixincludes/tests/base/Availability.h
@@ -0,0 +1,29 @@ 
+/*  DO NOT EDIT THIS FILE.
+
+    It has been auto-edited by fixincludes from:
+
+	"fixinc/tests/inc/Availability.h"
+
+    This had to be done to correct non-standard usages in the
+    original, manufacturer supplied header file.  */
+
+#ifndef FIXINC_WRAP_AVAILABILITY_H_DARWIN14_HAS_FEATURE
+#define FIXINC_WRAP_AVAILABILITY_H_DARWIN14_HAS_FEATURE 1
+
+
+/* GCC doesn't support __has_feature built-in in C mode and
+ * using defined(__has_feature) && __has_feature in the same
+ * macro expression is not valid. So, easiest way is to define
+ * for this header __has_feature as a macro, returning 0, in case
+ * it is not defined internally
+ */
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+
+#if defined( DARWIN14_HAS_FEATURE_CHECK )
+
+#endif  /* DARWIN14_HAS_FEATURE_CHECK */
+
+#endif  /* FIXINC_WRAP_AVAILABILITY_H_DARWIN14_HAS_FEATURE */
diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index 892ba35..39f795f 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -572,20 +572,31 @@  find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
 
 /* 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.  The lowest digit is always zero.
-   Print a warning if the version number can't be understood.  */
+   so '10.4.2' becomes 1040 and '10.10.0' becomes 101000.  The lowest
+   digit is always zero. Print a warning if the version number
+   can't be understood.  */
 static const char *
 version_as_macro (void)
 {
-  static char result[] = "1000";
+  static char result[7] = "1000";
+  int minorDigitIdx;
 
   if (strncmp (darwin_macosx_version_min, "10.", 3) != 0)
     goto fail;
   if (! ISDIGIT (darwin_macosx_version_min[3]))
     goto fail;
-  result[2] = darwin_macosx_version_min[3];
-  if (darwin_macosx_version_min[4] != '\0'
-      && darwin_macosx_version_min[4] != '.')
+
+  minorDigitIdx = 3;
+  result[2] = darwin_macosx_version_min[minorDigitIdx++];
+  if (ISDIGIT(darwin_macosx_version_min[minorDigitIdx])) {
+    /* Starting with 10.10 numeration for mactro changed */
+    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] != '.')
     goto fail;
 
   return result;
diff --git a/gcc/config/darwin-driver.c b/gcc/config/darwin-driver.c
index 8b6ae93..a115616 100644
--- a/gcc/config/darwin-driver.c
+++ b/gcc/config/darwin-driver.c
@@ -57,7 +57,7 @@  darwin_find_version_from_kernel (char *new_flag)
   version_p = osversion + 1;
   if (ISDIGIT (*version_p))
     major_vers = major_vers * 10 + (*version_p++ - '0');
-  if (major_vers > 4 + 9)
+  if (major_vers > 4 + 10)
     goto parse_failed;
   if (*version_p++ != '.')
     goto parse_failed;
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
index a93d38d..6783108 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -940,8 +940,10 @@  CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
 
 COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
 CHECK_SIZE_AND_OFFSET(dirent, d_ino);
-#if SANITIZER_MAC
+#if SANITIZER_MAC && ( !defined(__DARWIN_64_BIT_INO_T) || __DARWIN_64_BIT_INO_T)
 CHECK_SIZE_AND_OFFSET(dirent, d_seekoff);
+#elif SANITIZER_MAC
+// There is no d_seekoff with non 64-bit ino_t
 #elif SANITIZER_FREEBSD
 // There is no 'd_off' field on FreeBSD.
 #else
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
index dece2d3..c830486 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -392,12 +392,20 @@  namespace __sanitizer {
 #endif
 
 #if SANITIZER_MAC
+# if ! defined(__DARWIN_64_BIT_INO_T) || __DARWIN_64_BIT_INO_T
   struct __sanitizer_dirent {
     unsigned long long d_ino;
     unsigned long long d_seekoff;
     unsigned short d_reclen;
     // more fields that we don't care about
   };
+# else
+  struct __sanitizer_dirent {
+    unsigned int d_ino;
+    unsigned short d_reclen;
+    // more fields that we don't care about
+  };
+# endif
 #elif SANITIZER_FREEBSD
   struct __sanitizer_dirent {
     unsigned int d_fileno;