diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-04-24 07:30:51 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-04-24 07:30:51 +0200 |
commit | 430d1036e57ac7ce502079e245a01e3969c9e300 (patch) | |
tree | 0a1696cae1dc65d0d97218789e715d76bb448a14 | |
parent | 1e653e1b10f19454cd2dac621fd5bb1f19a7aeac (diff) |
Reimplement has_lt_operator check without full instantiation
The full instantiation caused a segfault in certain cases with GCC 11.4.0
from Ubuntu 22.04 (but not from Debian).
-rw-r--r-- | odb/odb/odb.cxx | 33 | ||||
-rw-r--r-- | odb/odb/validator.cxx | 5 |
2 files changed, 32 insertions, 6 deletions
diff --git a/odb/odb/odb.cxx b/odb/odb/odb.cxx index 701f6e1..39079ea 100644 --- a/odb/odb/odb.cxx +++ b/odb/odb/odb.cxx @@ -981,13 +981,34 @@ main (int argc, char* argv[]) // operator< test, used in validator. // + // Note that typeof() cannot be used in the function signature + // directly so we have to go though lt_operator_type. This means + // we get diagnostics from the compiler (followed by ours) but + // it's doesn't look bad plus C++98 support is on its way out. + // os << "template <typename T>" << endl - << "bool" << endl - << "has_lt_operator (const T& x, const T& y)" << endl - << "{" << endl - << "bool r (x < y);" << endl - << "return r;" << endl - << "}" << endl; + << "const T&" << endl + << "instance ();" << endl + << endl; + + if (ops.std () == cxx_version::cxx98) + { + os << "template <typename T>" << endl + << "struct lt_operator_type" << endl + << "{" << endl + << "typedef __typeof__ (instance<T> () < instance<T> ()) R;" << endl + << "};" << endl + << endl + << "template <typename T>" << endl + << "typename lt_operator_type<T>::R" << endl + << "has_lt_operator ();" << endl; + } + else + { + os << "template <typename T>" << endl + << "decltype (instance<T> () < instance<T> ())" << endl + << "has_lt_operator ();" << endl; + } os << "}" << endl << "}" << endl; diff --git a/odb/odb/validator.cxx b/odb/odb/validator.cxx index bf9aa6b..aa45294 100644 --- a/odb/odb/validator.cxx +++ b/odb/odb/validator.cxx @@ -1644,6 +1644,10 @@ namespace bool v (inst != error_mark_node); + // Old version of has_lt_operator() relied on full instantiation + // while the new one is based on SFINAE. + // +#if 0 if (v && DECL_TEMPLATE_INSTANTIATION (inst) && !DECL_TEMPLATE_INSTANTIATED (inst)) @@ -1667,6 +1671,7 @@ namespace global_dc->printer->buffer->stream = s; v = (ec == errorcount); } +#endif if (!v) { |