Tests fail with gcc 7.0.1 due to new aliasing warnings
Opened this issue · 6 comments
Running make test
with gcc 7.0.1 fails due to new aliasing warnings, promoted to errors by the -Werror
switch in the makefile:
g++ -c -o out/binary_visitor_1.o test/t/binary_visitor_1.cpp -Iinclude -isystem test/include -std=c++11 -Werror -Wall -Wextra -pedantic -Wformat=2 -Wsign-conversion -Wshadow -Wunused-parameter -O3 -DNDEBUG -march=native -DSINGLE_THREADED -fvisibility-inlines-hidden -fvisibility=hidden -I/usr/include/catch -pthread
In file included from test/t/binary_visitor_1.cpp:2:0:
include/mapbox/variant.hpp: In instantiation of ‘T& mapbox::util::variant<Types>::get() [with T = int; typename std::enable_if<(mapbox::util::detail::direct_type<T, Types ...>::index != mapbox::util::detail::invalid_value)>::type* <anonymous> = 0; Types = {int, double}]’:
test/t/binary_visitor_impl.hpp:180:9: required from here
include/mapbox/variant.hpp:724:20: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *reinterpret_cast<T*>(&data);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/mapbox/variant.hpp: In instantiation of ‘T& mapbox::util::variant<Types>::get() [with T = double; typename std::enable_if<(mapbox::util::detail::direct_type<T, Types ...>::index != mapbox::util::detail::invalid_value)>::type* <anonymous> = 0; Types = {int, double}]’:
test/t/binary_visitor_impl.hpp:187:9: required from here
include/mapbox/variant.hpp:724:20: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
include/mapbox/variant.hpp: In instantiation of ‘const T& mapbox::util::variant<Types>::get_unchecked() const [with T = int; typename std::enable_if<(mapbox::util::detail::direct_type<T, Types ...>::index != mapbox::util::detail::invalid_value)>::type* <anonymous> = 0; Types = {int, double}]’:
include/mapbox/variant.hpp:472:51: required from ‘static R mapbox::util::detail::binary_dispatcher<F, V, R, T, Types ...>::apply_const(const V&, const V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; T = int; Types = {double}]’
include/mapbox/variant.hpp:893:73: required from ‘static decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply_const(v0, v1, forward<F>(f))) mapbox::util::variant<Types>::binary_visit(const V&, const V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; Types = {int, double}; decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply_const(v0, v1, forward<F>(f))) = double]’
include/mapbox/variant.hpp:987:27: required from ‘decltype (V:: binary_visit(v0, v1, forward<F>(f))) mapbox::util::apply_visitor(F&&, const V&, const V&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; decltype (V:: binary_visit(v0, v1, forward<F>(f))) = double]’
test/t/binary_visitor_impl.hpp:28:5: required from here
include/mapbox/variant.hpp:737:16: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *reinterpret_cast<T const*>(&data);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/mapbox/variant.hpp: In instantiation of ‘T& mapbox::util::variant<Types>::get_unchecked() [with T = int; typename std::enable_if<(mapbox::util::detail::direct_type<T, Types ...>::index != mapbox::util::detail::invalid_value)>::type* <anonymous> = 0; Types = {int, double}]’:
include/mapbox/variant.hpp:493:45: required from ‘static R mapbox::util::detail::binary_dispatcher<F, V, R, T, Types ...>::apply(V&, V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; T = int; Types = {double}]’
include/mapbox/variant.hpp:900:67: required from ‘static decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply(v0, v1, forward<F>(f))) mapbox::util::variant<Types>::binary_visit(V&, V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; Types = {int, double}; decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply(v0, v1, forward<F>(f))) = double]’
include/mapbox/variant.hpp:994:27: required from ‘decltype (V:: binary_visit(v0, v1, forward<F>(f))) mapbox::util::apply_visitor(F&&, V&, V&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; decltype (V:: binary_visit(v0, v1, forward<F>(f))) = double]’
test/t/binary_visitor_impl.hpp:68:5: required from here
include/mapbox/variant.hpp:713:16: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *reinterpret_cast<T*>(&data);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/mapbox/variant.hpp: In instantiation of ‘const T& mapbox::util::variant<Types>::get_unchecked() const [with T = double; typename std::enable_if<(mapbox::util::detail::direct_type<T, Types ...>::index != mapbox::util::detail::invalid_value)>::type* <anonymous> = 0; Types = {int, double}]’:
include/mapbox/variant.hpp:401:44: required from ‘static R mapbox::util::detail::binary_dispatcher_rhs<F, V, R, T0, T1>::apply_const(const V&, const V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; T0 = int; T1 = double]’
include/mapbox/variant.hpp:477:80: required from ‘static R mapbox::util::detail::binary_dispatcher<F, V, R, T, Types ...>::apply_const(const V&, const V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; T = int; Types = {double}]’
include/mapbox/variant.hpp:893:73: required from ‘static decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply_const(v0, v1, forward<F>(f))) mapbox::util::variant<Types>::binary_visit(const V&, const V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; Types = {int, double}; decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply_const(v0, v1, forward<F>(f))) = double]’
include/mapbox/variant.hpp:987:27: required from ‘decltype (V:: binary_visit(v0, v1, forward<F>(f))) mapbox::util::apply_visitor(F&&, const V&, const V&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; decltype (V:: binary_visit(v0, v1, forward<F>(f))) = double]’
test/t/binary_visitor_impl.hpp:28:5: required from here
include/mapbox/variant.hpp:737:16: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *reinterpret_cast<T const*>(&data);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/mapbox/variant.hpp: In instantiation of ‘T& mapbox::util::variant<Types>::get_unchecked() [with T = double; typename std::enable_if<(mapbox::util::detail::direct_type<T, Types ...>::index != mapbox::util::detail::invalid_value)>::type* <anonymous> = 0; Types = {int, double}]’:
include/mapbox/variant.hpp:407:38: required from ‘static R mapbox::util::detail::binary_dispatcher_rhs<F, V, R, T0, T1>::apply(V&, V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; T0 = int; T1 = double]’
include/mapbox/variant.hpp:498:74: required from ‘static R mapbox::util::detail::binary_dispatcher<F, V, R, T, Types ...>::apply(V&, V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; T = int; Types = {double}]’
include/mapbox/variant.hpp:900:67: required from ‘static decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply(v0, v1, forward<F>(f))) mapbox::util::variant<Types>::binary_visit(V&, V&, F&&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; R = double; Types = {int, double}; decltype (mapbox::util::detail::binary_dispatcher<F, V, R, Types ...>::apply(v0, v1, forward<F>(f))) = double]’
include/mapbox/variant.hpp:994:27: required from ‘decltype (V:: binary_visit(v0, v1, forward<F>(f))) mapbox::util::apply_visitor(F&&, V&, V&) [with F = const add_visitor&; V = mapbox::util::variant<int, double>; decltype (V:: binary_visit(v0, v1, forward<F>(f))) = double]’
test/t/binary_visitor_impl.hpp:68:5: required from here
include/mapbox/variant.hpp:713:16: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
return *reinterpret_cast<T*>(&data);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
make: *** [Makefile:100: out/binary_visitor_1.o] Error 1
std::variant
gets away without casts because it uses at its core a recursively(!) templated union so that it can write a static accessor that recursively goes through the nested union to access the correct data member by index. Since it uses union
, it doesn't need to cast and can rely on the compiler to perform the correct alignment.
Oops. So that's a regression that came from a fix for an ARM code generation bug I reported with mapnik ;-)
See https://bugzilla.redhat.com/show_bug.cgi?id=1422456 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671 for the somewhat horrifying/incomprehensible history of the original bug...
Upstream fix landed and GCC 7.2 just got released: https://gcc.gnu.org/ml/gcc/2017-08/msg00129.html
I was also having this issue with GCC 7.2. I tried to downgrade to gcc6 (using upgrade-alternatives) and I'm somehow still getting this error. Should gcc 6.4 be able to compile this? If not, what version of gcc do I need?