chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.94k stars 1.22k forks source link

error: constexpr variable 'static_query_v in prefer_only.hpp #860

Open tpgxyz opened 3 years ago

tpgxyz commented 3 years ago

Hi,

i'm trying to compile boost-1.76.0 on aarch64 with LLVM/clang-12.x. and it due to this error:

clang-linux.compile.c++.without-pch bin.v2/libs/log/build/clang-linux-12.0.1/release/debug-symbols-on/pch-off/threadapi-pthread/threading-multi/visibility-hidden/syslog_backend.o
  "clang++" -c -x c++ -fvisibility-inlines-hidden -std=c++14 -fPIC -fPIC -pthread -Wall -g -fvisibility=hidden -Wno-inline -Os -fomit-frame-pointer -g3 -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector-all --param=ssp-buffer-size=4 -O3 -fno-strict-aliasing -I/usr/include/libunwind  -DBOOST_ALL_NO_LIB=1 -DBOOST_ATOMIC_DYN_LINK=1 -DBOOST_CHRONO_DYN_LINK=1 -DBOOST_FILESYSTEM_DYN_LINK=1 -DBOOST_HAS_ICU=1 -DBOOST_LOG_BUILDING_THE_LIB=1 -DBOOST_LOG_DLL -DBOOST_LOG_HAS_PTHREAD_MUTEX_ROBUST -DBOOST_LOG_USE_NATIVE_SYSLOG -DBOOST_LOG_WITHOUT_DEBUG_OUTPUT -DBOOST_LOG_WITHOUT_EVENT_LOG -DBOOST_SPIRIT_USE_PHOENIX_V3=1 -DBOOST_THREAD_BUILD_DLL=1 -DBOOST_THREAD_DONT_USE_CHRONO=1 -DBOOST_THREAD_POSIX -DBOOST_THREAD_USE_DLL=1 -DNDEBUG -D_XOPEN_SOURCE=600 -D__STDC_CONSTANT_MACROS -I"." -I"/usr/lib64/include" -I"libs/log/src"  -o "bin.v2/libs/log/build/clang-linux-12.0.1/release/debug-symbols-on/pch-off/threadapi-pthread/threading-multi/visibility-hidden/syslog_backend.o" "libs/log/src/syslog_backend.cpp"
In file included from libs/log/src/syslog_backend.cpp:32:
In file included from ./boost/asio/io_context.hpp:23:
In file included from ./boost/asio/detail/wrapped_handler.hpp:18:
In file included from ./boost/asio/detail/bind_handler.hpp:20:
In file included from ./boost/asio/associated_executor.hpp:22:
In file included from ./boost/asio/system_executor.hpp:20:
In file included from ./boost/asio/execution.hpp:35:
./boost/asio/execution/prefer_only.hpp:213:39: error: constexpr variable 'static_query_v<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0>, const boost::asio::execution::detail::outstanding_work_t<0>>' must be initialized by a constant expression
  static BOOST_ASIO_CONSTEXPR const T static_query_v
                                      ^
./boost/asio/traits/static_query.hpp:72:46: note: in instantiation of static data member 'boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>::static_query_v<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0>, const boost::asio::execution::detail::outstanding_work_t<0>>' requested here
    decltype(decay<Property>::type::template static_query_v<T>)

More build logs can be found here: https://abf.openmandriva.org/build_lists/55053

Our boost sources are here: https://github.com/OpenMandrivaAssociation/boost

berolinux commented 3 years ago

The problem here is that asio makes some assumptions about the compiler based on GNUC versioning. clang configured to set GNUC / __GNUC_MINOR__ to something >= 8.4 will fail.

In particular, BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES gets set, which breaks the build with clang.

This isn't showing for most other systems because clang by default sets GNUC and friends to 4.2.1 -- but doing that disables all sorts of optimizations (just look at boost-asio configs for examples of what gets disabled for "gcc 4.2.1" even though modern versions of clang can handle it easily). To reproduce on unpatched clang, add -fgnuc-version=11.1 to the compiler flags.

The attached patch fixes the problem, but isn't a very nice solution (because it just makes the assumption that HAS_SFINAE_VARIABLE_TEMPLATES should never be set for clang, which may be wrong once clang 13 or 14 is released). The best solution would be a check to see if SFINAE_VARIABLE_TEMPLATES will work.

boost-asio-clang.patch.txt

andreyv commented 2 years ago

Clang bug report with reduced sample: https://github.com/llvm/llvm-project/issues/57894

A workaround is to compile with -std=c++17 or later.

Another workaround is to make the out-of-class member definitions constexpr.