Opened 5 years ago
Closed 5 years ago
#13479 closed Bugs (fixed)
GCC-warning: break strict-aliasing rules in <boost/type_traits/integral_constant.hpp>
| Reported by: | Owned by: | John Maddock | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | type_traits |
| Version: | Boost 1.65.0 | Severity: | Problem |
| Keywords: | GCC | Cc: |
Description
Currently, I receive the GCC-warning 'warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]' about the (indirect included) header-file <boost/boost/type_traits/integral_constant.hpp> (e.g. line 93), if:
- I compile with GCC 4.6.4 or 6.4.0, and
- boost 1.60.0 or 1.65.1, and
- the option -Wstrict-aliasing=2 is used; not with on level 1 or 3
- and optimization-level -O2 or -Os (or above), not with -O0,-O1 (or -Og on GCC 6)
IMHO, the reinterpret_cast from &data (I.e.g casting from const char*) causes this issue (and not using the dereference-helper afterwards, which comment shows that this is a GCC-work-around).
As work-around I'm using an additional const void* - helper-variable (ptr) instead of using &data directly, which seems to satisfy the compiler:
operator const mpl::bool_<val>& ()const
{
static const char data = 0;
void const* ptr = &data;
return dereference(reinterpret_cast<const mpl::bool_<val>*>(ptr));
}
... similar code-snippet also for 'operator const mpl::integral_c<T, val>& ()const' on line 65 ... [Note: using 'void const* const ptr =&data;' does not fix it]
As alternative, an additional cast '(uintptr_t)&data' within reinterpret_cast seems to fix/inhibit this compiler-warning also.
At least, is my fix/work-around a feasible solution (without any side-effects)?
Best regards from Salzburg, Markus
Change History (2)
comment:1 by , 5 years ago
comment:2 by , 5 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Apologies for not getting to this sooner, fixed in https://github.com/boostorg/type_traits/commit/4c3706113a5a130dcc66a13da6134e5ede122e33 Not sure if it will make the next release or not as it's already in beta.

Additional information - I.e., tested with "official" MinGW-GCC 6.3.0
Source-file "test.cpp":
Compile will result in following warning:
> gcc -I /Temp/SDK/boost -O2 -Wstrict-aliasing=2 -c test.cpp In file included from test.cpp:2:0: /Temp/SDK/boost/boost/type_traits/integral_constant.hpp: In instantiation of 'boost::integral_constant<bool, val>::operator const mpl_::bool_<val>&() const [with bool val = true]': test.cpp:6:38: required from here /Temp/SDK/boost/boost/type_traits/integral_constant.hpp:93:29: warning: type-punning to incomplete type might break strict-aliasing rules [-Wstrict-aliasing] return dereference(reinterpret_cast<const mpl::bool_<val>*>(&data)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This will not occur, if I do apply following patch (as unified diff); I.e., using an helper-variable (ptr) and removing dereference-helper, which is (IMHO) no longer needed ...
Index: boost/type_traits/integral_constant.hpp =================================================================== --- boost/type_traits/integral_constant.hpp +++ boost/type_traits/integral_constant.hpp @@ -55,17 +55,12 @@ typedef T value_type; typedef integral_constant<T, val> type; static const T value = val; - // - // This helper function is just to disable type-punning - // warnings from GCC: - // - template <class U> - static U& dereference(U* p) { return *p; } operator const mpl::integral_c<T, val>& ()const { - static const char data[sizeof(long)] = { 0 }; - return dereference(reinterpret_cast<const mpl::integral_c<T, val>*>(&data)); + static const long data = 0; + const void* ptr = &data; + return *(reinterpret_cast<const mpl::integral_c<T, val>*>(ptr)); } BOOST_CONSTEXPR operator T()const { return val; } }; @@ -80,17 +75,12 @@ typedef bool value_type; typedef integral_constant<bool, val> type; static const bool value = val; - // - // This helper function is just to disable type-punning - // warnings from GCC: - // - template <class T> - static T& dereference(T* p) { return *p; } operator const mpl::bool_<val>& ()const { static const char data = 0; - return dereference(reinterpret_cast<const mpl::bool_<val>*>(&data)); + const void* ptr = &data; + return *(reinterpret_cast<const mpl::bool_<val>*>(ptr)); } BOOST_CONSTEXPR operator bool()const { return val; } };Is my suggested patch a suitable fix and does replace the the dereference-helper (which does not work for me on -Wstrict-aliasing=2)?
Best regards from Salzburg, Markus