Catch2 icon indicating copy to clipboard operation
Catch2 copied to clipboard

riscv: build failure due to Werror=cast-align

Open skeuchel opened this issue 1 year ago • 2 comments

Describe the bug When building for the riscv64 architecture, a build failure occurs in the test suite due to treating warnings as errors.

build log snippet
36.07 [ 85%] Building CXX object tests/CMakeFiles/SelfTest.dir/SelfTest/UsageTests/Benchmark.tests.cpp.o
36.35 In file included from /catch2/tests/SelfTest/UsageTests/Benchmark.tests.cpp:12:
36.35 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp: In instantiation of 'T& Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::stored_object() [with T = std::__cxx11::basic_string<char>; bool Destruct = false]':
36.35 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp:46:34:   required from 'std::enable_if_t<AllowManualDestruction> Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::destruct() [with bool AllowManualDestruction = true; T = std::__cxx11::basic_string<char>; bool Destruct = false; std::enable_if_t<AllowManualDestruction> = void]'
36.35 /catch2/tests/SelfTest/UsageTests/Benchmark.tests.cpp:153:59:   required from here
36.35 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp:61:46: error: cast from 'unsigned char*' to 'std::__cxx11::basic_string<char>*' increases required alignment of target type [-Werror=cast-align]
36.35    61 |                 T& stored_object() { return *reinterpret_cast<T*>( data ); }
36.35       |                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
36.39 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp: In instantiation of 'T& Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::stored_object() [with T = std::__cxx11::basic_string<char>; bool Destruct = true]':
36.39 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp:46:34:   required from 'std::enable_if_t<AllowManualDestruction> Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::destruct() [with bool AllowManualDestruction = true; T = std::__cxx11::basic_string<char>; bool Destruct = true; std::enable_if_t<AllowManualDestruction> = void]'
36.39 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp:52:97:   required from 'void Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::destruct_on_exit(std::enable_if_t<Destruct, U>*) [with U = std::__cxx11::basic_string<char>; T = std::__cxx11::basic_string<char>; bool Destruct = true; std::enable_if_t<Destruct, U> = std::__cxx11::basic_string<char>]'
36.39 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp:35:55:   required from 'Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::~ObjectStorage() [with T = std::__cxx11::basic_string<char>; bool Destruct = true]'
36.39 /usr/riscv64-linux-gnu/include/c++/13/bits/stl_construct.h:151:22:   required from 'constexpr void std::_Destroy(_Tp*) [with _Tp = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>]'
36.39 /usr/riscv64-linux-gnu/include/c++/13/bits/stl_construct.h:163:19:   required from 'static void std::_Destroy_aux<<anonymous> >::__destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = Catch::Benchmark::Detail::ObjectStorage<std::__cxx11::basic_string<char>, true>*; bool <anonymous> = false]'
36.39 /usr/riscv64-linux-gnu/include/c++/13/bits/stl_construct.h:196:11:   required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>*]'
36.39 /usr/riscv64-linux-gnu/include/c++/13/bits/alloc_traits.h:948:20:   required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator, allocator<_T2>&) [with _ForwardIterator = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>*; _Tp = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>]'
36.39 /usr/riscv64-linux-gnu/include/c++/13/bits/stl_vector.h:732:15:   required from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp = Catch::Benchmark::Detail::ObjectStorage<std::__cxx11::basic_string<char>, true>; _Alloc = std::allocator<Catch::Benchmark::Detail::ObjectStorage<std::__cxx11::basic_string<char>, true> >]'
36.39 /catch2/tests/SelfTest/UsageTests/Benchmark.tests.cpp:145:89:   required from here
36.39 /catch2/src/catch2/../catch2/benchmark/catch_constructor.hpp:61:46: error: cast from 'unsigned char*' to 'std::__cxx11::basic_string<char>*' increases required alignment of target type [-Werror=cast-align]
36.69 cc1plus: all warnings being treated as errors

Expected behavior A successful build.

Reproduction steps It is possible to reproduce the build failure by cross-compiling, so no risc-v hardware is needed. You can build the following docker file on a x64 host to reproduce the build failure.

Dockerfile
FROM debian:trixie
RUN apt-get update && apt-get install -yq cmake g++-riscv64-linux-gnu git python3
RUN git clone --depth=1 https://github.com/catchorg/Catch2.git /catch2

ENV AR="riscv64-linux-gnu-ar"
ENV AS="riscv64-linux-gnu-as"
ENV CC="riscv64-linux-gnu-gcc"
ENV CXX="riscv64-linux-gnu-g++"
ENV LD="riscv64-linux-gnu-ld"
ENV NM="riscv64-linux-gnu-nm"
ENV OBJCOPY="riscv64-linux-gnu-objcopy"
ENV OBJDUMP="riscv64-linux-gnu-objdump"
ENV RANLIB="riscv64-linux-gnu-ranlib"
ENV READELF="riscv64-linux-gnu-readelf"
ENV SIZE="riscv64-linux-gnu-size"
ENV STRINGS="riscv64-linux-gnu-strings"
ENV STRIP="riscv64-linux-gnu-strip"

WORKDIR /build
RUN cmake -DCATCH_DEVELOPMENT_BUILD=ON -DCATCH_BUILD_TESTING=ON \
  -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=riscv64 \
  -DCMAKE_HOST_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_PROCESSOR=x86_64 \
  ../catch2
RUN make -j$(nproc)

Platform information:

  • OS: NixOS 24.05
  • Compiler+version: GCC v13.2.0
  • Catch version: v3.5.2

Additional context Not sure if catch or gcc is to blame.

skeuchel avatar Feb 03 '24 16:02 skeuchel

I've the same issue on armv7l-linux

catch2> [ 85%] Building CXX object tests/CMakeFiles/SelfTest.dir/SelfTest/UsageTests/Benchmark.tests.cpp.o
catch2> In file included from /build/source/tests/SelfTest/UsageTests/Benchmark.tests.cpp:12:
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp: In instantiation of 'T& Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::stored_object() [with T = std::__cxx11::basic_string<char>; bool Destruct = false]':
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp:46:34:   required from 'std::enable_if_t<AllowManualDestruction> Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::destruct() [with bool AllowManualDestruction = true; T = std::__cxx11::basic_string<char>; bool Destruct = false; std::enable_if_t<AllowManualDestruction> = void]'
catch2> /build/source/tests/SelfTest/UsageTests/Benchmark.tests.cpp:153:59:   required from here
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp:61:46: error: cast from 'unsigned char*' to 'std::__cxx11::basic_string<char>*' increases required alignment of target type [8;;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wcast-align-Werror=cast-align8;;]
catch2>    61 |                 T& stored_object() { return *reinterpret_cast<T*>( data ); }
catch2>       |                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp: In instantiation of 'T& Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::stored_object() [with T = std::__cxx11::basic_string<char>; bool Destruct = true]':
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp:46:34:   required from 'std::enable_if_t<AllowManualDestruction> Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::destruct() [with bool AllowManualDestruction = true; T = std::__cxx11::basic_string<char>; bool Destruct = true; std::enable_if_t<AllowManualDestruction> = void]'
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp:52:97:   required from 'void Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::destruct_on_exit(std::enable_if_t<Destruct, U>*) [with U = std::__cxx11::basic_string<char>; T = std::__cxx11::basic_string<char>; bool Destruct = true; std::enable_if_t<Destruct, U> = std::__cxx11::basic_string<char>]'
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp:35:55:   required from 'Catch::Benchmark::Detail::ObjectStorage<T, Destruct>::~ObjectStorage() [with T = std::__cxx11::basic_string<char>; bool Destruct = true]'
catch2> /nix/store/spipxxlrlpxn3981gjv7mkxjabwdw4z7-gcc-13.2.0/include/c++/13.2.0/bits/stl_construct.h:151:22:   required from 'constexpr void std::_Destroy(_Tp*) [with _Tp = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>]'
catch2> /nix/store/spipxxlrlpxn3981gjv7mkxjabwdw4z7-gcc-13.2.0/include/c++/13.2.0/bits/stl_construct.h:163:19:   required from 'static void std::_Destroy_aux<<anonymous> >::__destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = Catch::Benchmark::Detail::ObjectStorage<std::__cxx11::basic_string<char>, true>*; bool <anonymous> = false]'
catch2> /nix/store/spipxxlrlpxn3981gjv7mkxjabwdw4z7-gcc-13.2.0/include/c++/13.2.0/bits/stl_construct.h:196:11:   required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>*]'
catch2> /nix/store/spipxxlrlpxn3981gjv7mkxjabwdw4z7-gcc-13.2.0/include/c++/13.2.0/bits/alloc_traits.h:947:20:   required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator, allocator<_T2>&) [with _ForwardIterator = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>*; _Tp = Catch::Benchmark::Detail::ObjectStorage<__cxx11::basic_string<char>, true>]'
catch2> /nix/store/spipxxlrlpxn3981gjv7mkxjabwdw4z7-gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:732:15:   required from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp = Catch::Benchmark::Detail::ObjectStorage<std::__cxx11::basic_string<char>, true>; _Alloc = std::allocator<Catch::Benchmark::Detail::ObjectStorage<std::__cxx11::basic_string<char>, true> >]'
catch2> /build/source/tests/SelfTest/UsageTests/Benchmark.tests.cpp:145:89:   required from here
catch2> /build/source/src/catch2/../catch2/benchmark/catch_constructor.hpp:61:46: error: cast from 'unsigned char*' to 'std::__cxx11::basic_string<char>*' increases required alignment of target type [8;;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wcast-align-Werror=cast-align8;;]
``

misuzu avatar Mar 14 '24 10:03 misuzu

I think this could be fixed by setting the alignment of data to alignas(T, T*)

p4vook avatar Mar 26 '24 11:03 p4vook