undefined reference to 'typeinfo for long double'
Multiple Boost's lexical_cast tests are failing with clang on x86_64 because of missing typeinfo.
Here's a typical error message:
../boost/lexical_cast/bad_lexical_cast.hpp:67: error: undefined reference to 'typeinfo for long double'
See error messages for
CrystaX.NET-apilevel-21-x86_64 here: http://www.boost.org/development/tests/develop/developer/lexical_cast.html
#2 Updated by Dmitry Moskalchuk over 4 years ago
Just to explain root of the bug:
x86_64 is pretty new target for Android. Android started support x86_64 less than one year ago - from 5.0 version. And there was significant change in how long double was represented on 32-bit and 64-bit platforms. 'long double' is 64-bit long on 32-bit Android (i.e. it's alias of 'double'), and 128-bit long on 64-bit Android (being another than 'double'); many functions working with 'long double' on 32-bit Android were just aliases for the same functions for 'double'. After switching to 64-bit platform, it became the problem. We've already fixed many such issues, but not all yet for clang; this is just matter of time.
#4 Updated by Dmitry Moskalchuk about 4 years ago
- Status changed from In Progress to Done
- Target version set to 10.2.0
- % Done changed from 0 to 100
Finally I've figured out why this error happens and how to fix it.
The root cause was that gcc uses special @float128@ type for 128-bit floating point ("quadruple precision":http://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format) operations for @x86@ and @x86_64@ targets, which may or may not be alias to @long double@, depending on target settings. On Android-x86_64, it is actually alias to @long double@, since all 64-bit Androids have 128-bit @long double@. However, even though @long double@ is 128-bit long for x86_64, its name mangling was wrong - it was always encoded with "g" letter (indicating @float128@), instead of "e" (indicating @long double@). Due to that bug, all references to @typeinfo for long double@ was actually mangled as @typeinfo for __float128@. It was not a problem when all components (shared libraries and executables) were built and linked with gcc; but when libsupc++ were built with gcc and executable with clang, they encoded references to @long double@ differently - libsupc++.a (built by gcc) contained "T _ZTIg" (@typeinfo for __float128@), and executable (built by clang) was referenced "U _ZTIe" (@typeinfo for long double@).
"Here":https://github.com/crystax/android-toolchain-gcc/commit/660b2a155336ecff7bafeefff962cd2052d6ecc9 is fix for that. It uses "e" to encode @long double@ for Android x86_64 target, so both gcc and clang now uses the same name mangling for @long double@.
I've added also "test case":https://github.com/crystax/android-platform-ndk/commit/b7105887dc902cada9a0f6bfbeff04146f4795f2 to catch regresssions in future.
#5 Updated by Dmitry Moskalchuk about 4 years ago
- Status changed from Done to Closed
Fix confirmed. No more linker errors on "testing results page":http://www.boost.org/development/tests/develop/developer/lexical_cast.html