Opened 6 years ago

Last modified 5 years ago

#12773 assigned Bugs

WINDOWS- Boost thread 1.63.0 strict aliasing warnings

Reported by: alexandre.nunes@… Owned by: viboes
Milestone: To Be Determined Component: thread
Version: Boost 1.63.0 Severity: Problem
Keywords: Cc:

Description

I'm cross-compiling boost on Linux, having 32-bit mingw64 as a target.

I'm still seeing strict aliasing complaints on boost 1.63.0 thread/win32/shared_mutex.hpp.

As gcc 6 has even stricter aliasing rules, I'm afraid that these may be harmful, so I came up with the attached patch - which is ugly, but works.

Attachments (2)

win32_shared_mutex.patch (1.3 KB ) - added by Alexandre Pereira Nunes <alexandre.nunes@…> 6 years ago.
Path fixing the warning/potential misbehavior
win32_shared_mutex_punning.patch (1.2 KB ) - added by Alexandre Pereira Nunes <alexandre.nunes@…> 6 years ago.
Newer patch, uses type punning union.

Download all attachments as: .zip

Change History (10)

by Alexandre Pereira Nunes <alexandre.nunes@…>, 6 years ago

Attachment: win32_shared_mutex.patch added

Path fixing the warning/potential misbehavior

by Alexandre Pereira Nunes <alexandre.nunes@…>, 6 years ago

Newer patch, uses type punning union.

comment:1 by Alexandre Pereira Nunes <alexandre.nunes@…>, 6 years ago

The win32_shared_mutex.patch didn't work with gcc 6.3.0. I came up with a type-punning union instead, but I'm unsure the anonymous union is portable. One can come up with a better idea for that case. Works for me™

comment:2 by viboes, 6 years ago

Summary: Boost thread 1.63.0 strict aliasing warningsWINDOWS- Boost thread 1.63.0 strict aliasing warnings

comment:3 by viboes, 6 years ago

Could you report explicitly the strict aliasing complaints?

comment:4 by viboes, 6 years ago

Ok, I see from the patch where the strict aliasing problem could come from. I don't think the union should solve the issue as we introduce then UB.

The safe way is to check each one of the bit fields.

Please, add here the report you got.

comment:5 by alexandre.nunes@…, 6 years ago

You're absolutely right that type-punning leads to UB, and so does current implementation. It seems to me that other than checking member-by-member, the other option would be to - providing the structure is sufficiently sane - use std::memcmp() to check the data. Most compilers can optimize the call away, when that's safe.

Here's the compiler report:

    gcc.compile.c++ bin.v2/libs/type_erasure/build/gcc-mingw-6.3/release/link-static/runtime-link-static/target-os-windows/threadapi-win32/threading-multi/dynamic_binding.o
    In file included from ./boost/thread/shared_mutex.hpp:18:0,
                     from libs/type_erasure/src/dynamic_binding.cpp:14:
    ./boost/thread/win32/shared_mutex.hpp: In instantiation of 'T boost::shared_mutex::interlocked_compare_exchange(T*, T, T) [with T = boost::shared_mutex::state_data]':
    ./boost/thread/win32/shared_mutex.hpp:130:103:   required from here
    ./boost/thread/win32/shared_mutex.hpp:51:63: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
                                                               *reinterpret_cast<long*>(&new_value),
                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ./boost/thread/win32/shared_mutex.hpp:52:63: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
                                                               *reinterpret_cast<long*>(&comparand));
                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ./boost/thread/win32/shared_mutex.hpp:53:20: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
             return *reinterpret_cast<T const*>(&res);
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ./boost/thread/win32/shared_mutex.hpp:53:52: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
             return *reinterpret_cast<T const*>(&res);
                                                    ^
    cc1plus: some warnings being treated as errors

comment:6 by anonymous, 6 years ago

IIRC there was also other similar reports in this code (line 39):

friend bool operator==(state_data const& lhs,state_data const& rhs)
            {
                return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
            }

But these happened further down the road, after "fixing" the other errors.

comment:7 by viboes, 6 years ago

Thanks for the reported errors.

comment:8 by viboes, 5 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned
Note: See TracTickets for help on using tickets.