Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#12577 closed Bugs (fixed)

Null reference in pair.hpp triggers runtime warning with -fsanitize=undefined

Reported by: antoinep92@… Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: container
Version: Boost 1.62.0 Severity: Problem
Keywords: Cc:

Description

I tagged 1.62 which is where I discovered the issue, but master at github seems affected as well.

Consider this minimal file:

#include <boost/container/flat_map.hpp>
int main() { return 0; }

When built with gcc 6.2 and undefined sanitizers, g++ -fsanitize=address, the resulting executable triggers the following warning at runtime during static initialization:

/usr/include/boost/container/detail/pair.hpp:85:30: runtime error: reference binding to null pointer of type 'const struct piecewise_construct_t'

This doesn't happen with clang 3.9, so it *might* be a bug in gcc, but when looking at the boost code, I'd say gcc is right. Indeed, in container/detail/pair.hpp (line 85 in 1.62 and master), the static global variable boost::container::piecewise_construct is defined, of type const std::piecewise_construct_t &, and value *boost::container::std_piecewise_construct_holder<0>::dummy, defined in the same file, but (as far as I can tell), uninitialized.

I'm not well positioned to assess the bug severity: either the null/uninitialized reference is never used, and the gcc warning can be ignored (although it's annoying); or there are situations the reference's address is dereferenced, and this can lead to crashes.

Change History (2)

comment:1 by Ion Gaztañaga, 6 years ago

Resolution: fixed
Status: newclosed

Thanks for the report.

The null value is never used, but sanitizers should work. A workaround was pushed and I confirmed it with GCC 6.2 and -fsanitize=address:

https://github.com/boostorg/container/commit/77f5d7218da42db37b4fecc97f7c389a9e6b9cd4

comment:2 by Eric Niebler, 6 years ago

This code requires global constructors, which causes a warning on some compilers. Why isn't this simply:

template <class T>
struct static_constexpr {
    static constexpr T const value {};
};
template <class T>
constexpr T const static_constexpr<T>::value;

using piecewise_construct_t = std::piecewise_construct_t const &;

namespace {
  piecewise_construct_t piecewise_construct =
    static_constexpr<std::piecewise_construct_t>::value;
}

??

Last edited 6 years ago by Eric Niebler (previous) (diff)
Note: See TracTickets for help on using tickets.