Bug 17473 - Build error on OSX when building with Clang 6.0
Summary: Build error on OSX when building with Clang 6.0
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.23
: P2 critical
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-09 20:17 UTC by Thomas Veerman
Modified: 2015-12-17 00:37 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Patch to fix build error (689 bytes, application/mbox)
2014-10-09 20:17 UTC, Thomas Veerman
Details
Second version of the patch fixing the build error (719 bytes, patch)
2014-10-10 10:28 UTC, Thomas Veerman
Details | Diff
Requested saved temp version of binary.cc (198.18 KB, text/plain)
2014-10-10 10:29 UTC, Thomas Veerman
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Veerman 2014-10-09 20:17:54 UTC
Created attachment 7821 [details]
Patch to fix build error

Minix3 builds Gold as part of its build process. When cross compiling on OSX10.9, it fails to build Gold with the following error:

In file included from /Users/thomas/minix/tools/binutils/../../external/gpl3/binutils/dist/gold/binary.cc:31:
In file included from /Users/thomas/minix/tools/binutils/../../external/gpl3/binutils/dist/gold/stringpool.h:23:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:438:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cwchar:107:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cwctype:54:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cctype:51:72: error: use of undeclared identifier 'do_not_use_isalnum_with_safe_ctype'
inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return isalnum(__c);}

This is fixed by #include'ing <sstream>.
Comment 1 Cary Coutant 2014-10-09 23:11:58 UTC
> Minix3 builds Gold as part of its build process. When cross compiling on
> OSX10.9, it fails to build Gold with the following error:
>
> In file included from
> /Users/thomas/minix/tools/binutils/../../external/gpl3/binutils/dist/gold/binary.cc:31:
> In file included from
> /Users/thomas/minix/tools/binutils/../../external/gpl3/binutils/dist/gold/stringpool.h:23:
> In file included from
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:438:
> In file included from
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cwchar:107:
> In file included from
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cwctype:54:
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cctype:51:72:
> error: use of undeclared identifier 'do_not_use_isalnum_with_safe_ctype'
> inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return
> isalnum(__c);}
>
> This is fixed by #include'ing <sstream>.

How does including <sstream> fix the problem?

Neither binary.cc nor stringpool.h use any API from <sstream>, so I
don't see how this is an appropriate fix. Even if it does fix it
somehow, I don't see how that would be anything but an accident that
might break again at any point in the future.

Libiberty's safe-ctype.h is clearly doing something very dangerous
here, so it seems to me that there's a portability issue that needs to
be fixed there, not in gold.

Can you compile binary.cc (without your patch) with --save-temps, and
send me the .ii file?

-cary
Comment 2 Thomas Veerman 2014-10-10 10:27:51 UTC
I was inspired by a thread [0] on the GCC mailing list where a similar error message was produced, and it was suggested to move the include of <sstream> higher up in the file. That 'fix' was actually meant to fix something entirely else [1].

Now, why does this work? <sstream> includes <string>, which includes <cwchar>, which in turn includes <cwctype> that finally includes <cctype>. cctype in the OSX toolchain does among other things:

#ifdef isalnum
inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return isalnum(__c);}
#undef isalnum
inline _LIBCPP_INLINE_VISIBILITY int isalnum(int __c) {return __libcpp_isalnum(__c);}
#else  // isalnum
using ::isalnum;
#endif  // isalnum

By including <sstream> before "safe-ctype.h", isalnum is not yet #defined and so the #undef branch is taken. If safe-ctype is included it will redefine isalnum to 'do_not_use_isalnum_with_safe_ctype'. However, safe-ctype first includes <ctype.h> which includes <cctype>, so that shouldn't be a problem. But the latter is only true for the GNU toolchain and I'm using OSX's toolchain which doesn't have <ctype.h> (or I'm not looking in the right place). This should normally fail, but I think the Gold build system when invoked from Minix' build system picks up a <ctype.h> that's included by GCC (which is also built by Minix). This <ctype.h> includes a <cctype> which has a different header guard than the cctype in OSX toolchain.

binary.cc includes "stringpool.h" a few lines down of "safe-ctype.h", which eventually  includes <string> -> <cwchar> -> <cwctype> -> <cctype> from the OSX toolchain. Due to the inclusion of "safe-ctype.h" earlier, isalnum has now been defined to 'do_not_use_isalnum_with_safe_ctype', and <cctype> while now take the #ifdef branch and cause a compilation error. <cctype> is included twice due to the difference in header guards.

Now, I didn't realize all of this when I made the patch, but since you asked why it fixed the problem I investigated it. I agree it's dirty to include a header that has nothing to do with the file. It appears that moving the inclusion of "stringpool.h" above "safe-ctype.h" does the job as well.

[0] https://gcc.gnu.org/ml/gcc/2014-05/msg00006.html
[1] PR 61026 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61026
Comment 3 Thomas Veerman 2014-10-10 10:28:53 UTC
Created attachment 7823 [details]
Second version of the patch fixing the build error
Comment 4 Thomas Veerman 2014-10-10 10:29:39 UTC
Created attachment 7824 [details]
Requested saved temp version of binary.cc
Comment 5 Sourceware Commits 2015-12-17 00:37:11 UTC
The binutils-2_25-branch branch has been updated by Roland McGrath <roland@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=aae60b2c1f276263ad100952e3c3364c7baa6a2b

commit aae60b2c1f276263ad100952e3c3364c7baa6a2b
Author: Roland McGrath <mcgrathr@chromium.org>
Date:   Wed Dec 16 16:35:43 2015 -0800

    PR gold/17473: Fix gold build with system C++ headers that use <ctype.h>.
    
    gold/
    	PR gold/17473
    	* binary.cc: Move #include "safe-ctype.h" to be last #include.
    
    (cherry picked from commit 95c29a83ebadd0038fd304539a83c5e90798c1b9)
Comment 6 Sourceware Commits 2015-12-17 00:37:17 UTC
The binutils-2_26-branch branch has been updated by Roland McGrath <roland@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=03f87942b6a216bc5cd07c5cfbb5ce5ad8185133

commit 03f87942b6a216bc5cd07c5cfbb5ce5ad8185133
Author: Roland McGrath <mcgrathr@chromium.org>
Date:   Wed Dec 16 16:35:59 2015 -0800

    PR gold/17473: Fix gold build with system C++ headers that use <ctype.h>.
    
    gold/
    	PR gold/17473
    	* binary.cc: Move #include "safe-ctype.h" to be last #include.
    
    (cherry picked from commit 95c29a83ebadd0038fd304539a83c5e90798c1b9)
Comment 7 Sourceware Commits 2015-12-17 00:37:22 UTC
The master branch has been updated by Roland McGrath <roland@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=95c29a83ebadd0038fd304539a83c5e90798c1b9

commit 95c29a83ebadd0038fd304539a83c5e90798c1b9
Author: Roland McGrath <mcgrathr@chromium.org>
Date:   Wed Dec 16 16:35:27 2015 -0800

    PR gold/17473: Fix gold build with system C++ headers that use <ctype.h>.
    
    gold/
    	PR gold/17473
    	* binary.cc: Move #include "safe-ctype.h" to be last #include.