Summary: | gcc10 fails to build code using "constexpr" on ppc64le | ||||||
---|---|---|---|---|---|---|---|
Product: | Sisyphus | Reporter: | Николай Костригин <nickel> | ||||
Component: | gcc | Assignee: | Egor Ignatov <egori> | ||||
Status: | ASSIGNED --- | QA Contact: | qa-sisyphus | ||||
Severity: | normal | ||||||
Priority: | P5 | CC: | egori, glebfm, ilyakurdyukov, ldv, mike | ||||
Version: | unstable | ||||||
Hardware: | ppc | ||||||
OS: | Linux | ||||||
Attachments: |
|
Попробуйте так: template <class T> struct wrapper { public: static constexpr T INIT_VAL = std::numeric_limits<T>::min() + 1; wrapper(T data = INIT_VAL) : data(data) {} T data; }; template <> struct wrapper<long double> { public: static constexpr long double INIT_VAL = 1; wrapper(long double data = INIT_VAL) : data(data) {} long double data; }; Для float типов должна получаться просто единица. Так что попробуйте добавить таких специализированных темплейтов. (In reply to ilyakurdyukov from comment #1) > Для float типов должна получаться просто единица. Почему это для float типов должна быть единица? Тут проблема в том, что ppc испобльзует ibmlongdouble. С флагом -mabi=ieeelongdouble данный код компилируется, но возникают другие ошибки при сборке MySQL. Я думаю проще будет отключить этот тест для ppc: #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) using floating_point_types = ::testing::Types<float, double>; #else using floating_point_types = ::testing::Types<float, double, long double>; #endif see also: https://bugzilla.redhat.com/show_bug.cgi?id=1538817 (In reply to Egor Ignatov from comment #2) > (In reply to ilyakurdyukov from comment #1) > > Для float типов должна получаться просто единица. > Почему это для float типов должна быть единица? Понял почему :) (In reply to ilyakurdyukov from comment #1) > Попробуйте так: > > template <class T> > struct wrapper { > public: > static constexpr T INIT_VAL = std::numeric_limits<T>::min() + 1; > wrapper(T data = INIT_VAL) : data(data) {} > T data; > }; > #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) > template <> > struct wrapper<long double> { > public: > static constexpr long double INIT_VAL = 1; > wrapper(long double data = INIT_VAL) : data(data) {} > long double data; > }; #endif Хотя такое решение возможно будет лучше, сейчас пробую. > Попробуйте так:
>
> template <class T>
> struct wrapper {
> public:
> static constexpr T INIT_VAL = std::numeric_limits<T>::min() + 1;
> wrapper(T data = INIT_VAL) : data(data) {}
> T data;
> };
>
> template <>
> struct wrapper<long double> {
> public:
> static constexpr long double INIT_VAL = 1;
> wrapper(long double data = INIT_VAL) : data(data) {}
> long double data;
> };
ld: CMakeFiles/merge_innodb_tests-t.dir/ut0new-t.cc.o:(.toc+0x108): undefined reference to `innodb_ut0new_unittest::wrapper<__float128>::INIT_VAL'
Возможно так нужно добавить: template <class T> struct wrapper { public: static constexpr T INIT_VAL = std::numeric_limits<T>::min() + 1; wrapper(T data = INIT_VAL) : data(data) {} T data; }; template <class T> constexpr T wrapper<T>::INIT_VAL; #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) template <> struct wrapper<long double> { public: static constexpr long double INIT_VAL = 1; wrapper(long double data = INIT_VAL) : data(data) {} long double data; }; constexpr long double wrapper<long double>::INIT_VAL; #endif (In reply to ilyakurdyukov from comment #6) > Возможно так нужно добавить: > > template <class T> > struct wrapper { > public: > static constexpr T INIT_VAL = std::numeric_limits<T>::min() + 1; > wrapper(T data = INIT_VAL) : data(data) {} > T data; > }; > > template <class T> > constexpr T wrapper<T>::INIT_VAL; > > #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) > > template <> > struct wrapper<long double> { > public: > static constexpr long double INIT_VAL = 1; > wrapper(long double data = INIT_VAL) : data(data) {} > long double data; > }; > > constexpr long double wrapper<long double>::INIT_VAL; > > #endif Все собралось, спасибо! |
Created attachment 9551 [details] build MySQL-8.0.26-alt1 with gcc 10.3.1-alt2 on ppc64le log rpmi: gcc10-c++-10.3.1-alt2 sisyphus+277353.100.2.1 1625527709 installed [00:08:06] /usr/src/RPM/BUILD/MySQL-8.0.26/unittest/gunit/innodb/ut0new-t.cc:58:63: error: '(2.00416836000897277799610805135016e-292l + 1.0e+0l)' is not a constant expression [00:08:06] 58 | static constexpr T INIT_VAL = std::numeric_limits<T>::min() + 1; [00:08:06] | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ [00:08:06] gmake[2]: *** [unittest/gunit/innodb/CMakeFiles/merge_innodb_tests-t.dir/build.make:233: unittest/gunit/innodb/CMakeFiles/merge_innodb_tests-t.dir/ut0new-t.cc.o] Error 1 More details in the attached build log file and in task #281108