I found a (the?) overall smoking gun: for powerpc64-gcc FreeBSD's /projects/clang380-import/contrib/libc++/include/__config is doing (for example):
#define _LIBCPP_HAS_NO_RVALUE_REFERENCES (and other out of date classifications) for gcc5 vintages, and possibly for gcc49 and others as well. This in turn means that other parts of libc++ are not providing modern definitions that modern enough gcc5 variations handle fine. Instead libc++ provides old definitions that are incorrect/incomplete for c++11 and later (despite use of -std=c++11 on the command line). clang++ gets the modern definitions from libc++. So: Not a gcc problem, a libc++ problem. In the code that got the initial error report that I showed /projects/clang380-import/contrib/libc++/include/__config was using old definitions of std::begin(. . .) and std::end(. . .) for powerpc64-gcc and when the modern definitions are used instead under powerpc64-gcc the matching error report disappears. Part of this may be that __config is still always expecting for g++ that __GXX_EXPERIMENTAL_CXX0X__ is defined if nearly any of the modern c++11 or later features exist at all. At this point various things are not experimental any more and -std=c++11 features likely are not considered experimental any more in more recent gcc5 and later vintages. This __GXX_EXPERIMENTAL_CXX0X__ use is still true of __config at llvm's /libcxx/tags/RELEASE_380/rc1/include/__config and at llvm's /libcxx/trunk/include/__config too (head of trunk for the file). Looking at the most recent content of FreeBSD's /projects/clang380-import/contrib/libc++/include/__config shows: . . . #elif defined(__GNUC__) . . . . . . // GCC 5 will support variable templates #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES . . . #ifndef __GXX_EXPERIMENTAL_CXX0X__ . . . #define _LIBCPP_HAS_NO_RVALUE_REFERENCES . . . #else // __GXX_EXPERIMENTAL_CXX0X__ . . . #if _GNUC_VER < 403 #define _LIBCPP_HAS_NO_RVALUE_REFERENCES #endif . . . _LIBCPP_HAS_NO_RVALUE_REFERENCES being defined in turn causes /projects/clang380-import/contrib/libc++/include/iterator to define things like std::begin(. . .) in an old way, such as the following that was involved in the initial error report that I got: > #else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && > !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::iterator > begin(_Cp& __c) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::const_iterator > begin(const _Cp& __c) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::iterator > end(_Cp& __c) > { > return __c.end(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::const_iterator > end(const _Cp& __c) > { > return __c.end(); > } Manually forced replacement with modern source: > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > begin(_Cp& __c) -> decltype(__c.begin()) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > begin(const _Cp& __c) -> decltype(__c.begin()) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > end(_Cp& __c) -> decltype(__c.end()) > { > return __c.end(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > end(const _Cp& __c) -> decltype(__c.end()) > { > return __c.end(); > } eliminated the specific initial error report. (It is not a sufficient workaround to build clang as far as I know.) The following code extracted from libc++ and simplified from the llvm code that got the initial error that I showed can be used to experiment with the definitions of std::begin(. . .) and std:end(. . .) for powerpc64-gcc vs. clang++ via commands like: > /usr/local/bin/powerpc64-portbld-freebsd11.0-g++ -std=c++11 > -I/usr/include/c++/v1/ func.cpp vs. > clang++ -std=c++11 -stdlib=libc++ func.cpp with func.cpp being . . . (llvm's head-of-trunk iterator still has the same #if . . . #else . . . #endif structure) > #include <__config> > > _LIBCPP_BEGIN_NAMESPACE_STD > > #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && > !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > begin(_Cp& __c) -> decltype(__c.begin()) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > begin(const _Cp& __c) -> decltype(__c.begin()) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > end(_Cp& __c) -> decltype(__c.end()) > { > return __c.end(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > auto > end(const _Cp& __c) -> decltype(__c.end()) > { > return __c.end(); > } > > #else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && > !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::iterator > begin(_Cp& __c) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::const_iterator > begin(const _Cp& __c) > { > return __c.begin(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::iterator > end(_Cp& __c) > { > return __c.end(); > } > > template <class _Cp> > inline _LIBCPP_INLINE_VISIBILITY > typename _Cp::const_iterator > end(const _Cp& __c) > { > return __c.end(); > } > > #endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && > !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) > > _LIBCPP_END_NAMESPACE_STD > > namespace ns { > template <typename IteratorT> > class iterator_range { > IteratorT begin_iterator, end_iterator; > > public: > iterator_range(IteratorT begin_iterator, IteratorT end_iterator) > : begin_iterator(begin_iterator), > end_iterator(end_iterator) {} > > IteratorT begin() const { return begin_iterator; } > IteratorT end() const { return end_iterator; } > }; > > template <class T> iterator_range<T> make_range(T x, T y) { > return iterator_range<T>(x, y); > } > > template <typename ContainerTy> > auto test( ContainerTy &&C > ) -> decltype(make_range(std::begin(C), > std::end(C))) { > return make_range(std::begin(C), > std::end(C)); > } > }; > > typedef int *const init_const_ptr; > typedef int *const *init_const_iterator; > > int v; > init_const_ptr cvp = &v; > init_const_iterator pcpv = &cvp; > > typedef ns::iterator_range<init_const_iterator> init_const_range; > > void f(void) { > for (auto *I : ns::test(init_const_range(pcpv,pcpv+1))) { > } > } > > int main(void) > { return 0; } Commenting out inside one branch of the #if . . . #else . . . #endif makes very clear if that part was in use or the other part. Switching compilers switches which part is used in my testing. It also appears that /projects/clang380-import/contrib/libc++/include/__config has not been tracking various 3.8.0 changes. For example llvm's Log of /libcxx/tags/RELEASE_380/rc1/include/__config shows that its 2015-Dec-14 -r255585 version changed the _LIBCPP_HAS_NO_VARIABLE_TEMPLATES source that I quoted earlier to instead be: > // GCC 5 will support variable templates > #if !defined(__cpp_variable_templates) || __cpp_variable_templates < 201304L > #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES > #endif (increasing the support for modern g++'s a little bit). llvm's /libcxx/tags/RELEASE_380/rc1/include/__config is currently at -r258234 (2016-Jan-19) with about 8 checkins between the 2 versions. Looking up /projects/clang380-import/contrib/libc++/include/iterator and others show they date back being copies made on 2015-Dec-30 of vintages from FreeBSD's 2015-Oct 3.7.0 materials as well. (For some files that may well be current for all I know.) For all I know this status is deliberate for some reason. But it would seem that to expect modern gcc vintages to be supported well for modern libc++ uses probably has a necessary (but not sufficient) aspect of tracking llvm's updates that add handling of more modern gcc vintages. Side note: One revision in llvm's /libcxx/tags/RELEASE_380/rc1/include/ that I ran into that might be of note: -r257716 from 2016-Jan-13 says > Fix PR#25973 : 'basic_string::assign(InputIt, InputIt) doesn't provide the > strong exception safety guarantee'. This turned out to be a pervasive problem > in <string>, which required a fair amount of rework. Add in an optimization > for when iterators provide noexcept > increment/comparison/assignment/dereference (which covers many of the > iterators in libc++). === Mark Millard markmi at dsl-only.net On 2016-Jan-23, at 7:08 AM, Dimitry Andric <d...@freebsd.org> wrote: On 23 Jan 2016, at 12:25, Mark Millard <mar...@dsl-only.net> wrote: > > I tried a buildworld that included building clang and lldb based on using > powerpc64-xtoolchain-gcc/powerpc64-gcc as a cross compiler. It failed, see > below. This might indicate a more general gcc 5.x vs. clang 3.8.0 source code > mismatch. This was my first try. This could have been true for some time. > > --- CFG.o --- > /usr/local/bin/powerpc64-portbld-freebsd11.0-g++ -isystem > /usr/obj/xtoolchain/powerpc.powerpc64/usr/src/tmp/usr/include > -L/usr/obj/xtoolchain/powerpc.powerpc64/usr/src/tmp/usr/lib > --sysroot=/usr/obj/xtoolchain/powerpc.po > werpc64/usr/src/tmp -B/usr/local/powerpc64-freebsd/bin/ > -I/usr/obj/xtoolchain/powerpc.powerpc64/usr/src/tmp/usr/include/c++/v1 > -std=gnu++11 > -L/usr/obj/xtoolchain/powerpc.powerpc64/usr/src/tmp/../lib/libc++ > --sysroot=/usr > /obj/xtoolchain/powerpc.powerpc64/usr/src/tmp > -B/usr/local/powerpc64-freebsd/bin/ -O2 -pipe > -I/usr/src/lib/clang/libclanganalysis/../../../contrib/llvm/include > -I/usr/src/lib/clang/libclanganalysis/../../../contrib/llvm > /tools/clang/include > -I/usr/src/lib/clang/libclanganalysis/../../../contrib/llvm/tools/clang/lib/Analysis > -I. > -I/usr/src/lib/clang/libclanganalysis/../../../contrib/llvm/../../lib/clang/include > -DLLVM_ON_UNIX -DLLVM_ON_FREEBSD -D__STDC_LIMIT_MACROS > -D__STDC_CONSTANT_MACROS -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_STATIC_ANALYZER > -fno-strict-aliasing > -DLLVM_DEFAULT_TARGET_TRIPLE=\"powerpc64-unknown-freebsd11.0\" > -DLLVM_HOST_TRIPLE=\"powerpc64 > -unknown-freebsd11.0\" -DDEFAULT_SYSROOT=\"\" -MD -MP -MF.depend.CFG.o > -MTCFG.o -fstack-protector-strong -Wno-error=unused-function > -Wno-error=enum-compare -Wno-error=logical-not-parentheses > -Wno-error=bool-compare -Wno- > error=uninitialized -Wno-error=array-bounds -Wno-error=clobbered > -Wno-error=cast-align -Wno-error=extra -Wno-error=attributes > -Wno-error=inline -Wno-error=unused-but-set-variable -Wno-error=unused-value > -Wno-error=strict > -aliasing -Wno-error=address -std=c++11 -fno-exceptions -fno-rtti -c > /usr/src/lib/clang/libclanganalysis/../../../contrib/llvm/tools/clang/lib/Analysis/CFG.cpp > -o CFG.o > . . . > --- all_subdir_libclanganalysis --- > /usr/src/lib/clang/libclanganalysis/../../../contrib/llvm/tools/clang/lib/Analysis/CFG.cpp: > In member function 'std::__1::unique_ptr<clang::CFG> > {anonymous}::CFGBuilder::buildCFG(const clang::Decl*, clang::Stmt*)': > /usr/src/lib/clang/libclanganalysis/../../../contrib/llvm/tools/clang/lib/Analysis/CFG.cpp:1046:45: > error: no matching function for call to > 'reverse(clang::CXXConstructorDecl::init_const_range)' > for (auto *I : llvm::reverse(CD->inits())) { > ^ I just tried building clang 3.8.0 with gcc 5.3.0, but that went fine. However, by default gcc uses its own copy of libstdc++. The above error is most likely something caused by libc++ and gcc not playing well together. This kind of error is always hard to report upstream, since the gcc maintainers obviously do not care that much about libc++, while the libc++ maintainers do not care that much about gcc. :-) -Dimitry _______________________________________________ freebsd-toolchain@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain To unsubscribe, send any mail to "freebsd-toolchain-unsubscr...@freebsd.org"