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: ibiatiroler@… 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 ibiatiroler@…, 5 years ago

Additional information - I.e., tested with "official" MinGW-GCC 6.3.0

Source-file "test.cpp":

#include <boost/type_traits/integral_constant.hpp>

extern bool test(boost::mpl::bool_<true> const&);
bool result = test(boost::true_type());

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

comment:2 by John Maddock, 5 years ago

Resolution: fixed
Status: newclosed

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.

Note: See TracTickets for help on using tickets.