| 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