[llvm-bugs] [Bug 43629] Constexpr new: compiler crash

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Oct 10 15:43:48 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=43629

Richard Smith <richard-llvm at metafoo.co.uk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #3 from Richard Smith <richard-llvm at metafoo.co.uk> ---
Thanks, fixed in r374465. Your testcase now produces this error:


/home/zamazan4ik/OpenSource/test_llvm_lib/main.cpp:6:20: error: constexpr
variable 'res' must be initialized by a constant expression
    constexpr auto res = []
                   ^     ~~
/home/zamazan4ik/OpenSource/LLVM_build_release_clang/install/include/c++/v1/memory:1867:13:
note: construction of subobject of object outside its lifetime is not allowed
in a constant expression
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
            ^
/home/zamazan4ik/OpenSource/LLVM_build_release_clang/install/include/c++/v1/memory:1757:18:
note: in call to '&d.__list_imp::__size_alloc_->construct(&{*new
std::__1::__list_node<int, void *> [1]#0}[0].__value_, 42)'
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/home/zamazan4ik/OpenSource/LLVM_build_release_clang/install/include/c++/v1/memory:1584:14:
note: in call to '__construct({}, d.__list_imp::__size_alloc_, &{*new
std::__1::__list_node<int, void *> [1]#0}[0].__value_, 42)'
            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
             ^
/home/zamazan4ik/OpenSource/LLVM_build_release_clang/install/include/c++/v1/list:1709:5:
note: in call to 'construct(d.__list_imp::__size_alloc_, &{*new
std::__1::__list_node<int, void *> [1]#0}[0].__value_, 42)'
    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_),
_VSTD::move(__x));
    ^
/home/zamazan4ik/OpenSource/test_llvm_lib/main.cpp:9:19: note: in call to
'&d->push_back(42)'
                d.push_back(42);
                  ^
/home/zamazan4ik/OpenSource/test_llvm_lib/main.cpp:6:26: note: in call to '&[]
{
    std::list<int> d;
    d.push_back(42);
    return d.size();
}->operator()()'
    constexpr auto res = []
                         ^

... which looks like a bug in libc++'s std::list::push_back:

    __node_allocator& __na = base::__node_alloc();
    __hold_pointer __hold = __allocate_node(__na);
    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_),
_VSTD::move(__x));
    __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link());
    ++base::__sz();
    __hold.release();

Note that the lifetime of the __node object is never actually started here. (I
see you commented out the __p->__prev_ = nullptr in __allocate_node because of
this already.)

To fix this, you could make __list_node hold the _Tp in a union, and
default-construct the __list_node from __allocate_node:

template <class _Tp, class _VoidPtr>
struct __list_node
    : public __list_node_base<_Tp, _VoidPtr>
{
    _LIBCPP_CONSTEXPR_AFTER_CXX17 __list_node() {}
    _LIBCPP_CONSTEXPR_AFTER_CXX17 ~__list_node() {}

    union { _Tp __value_; };

    typedef __list_node_base<_Tp, _VoidPtr> __base;
    typedef typename __base::__link_pointer __link_pointer;

    _LIBCPP_INLINE_VISIBILITY
    _LIBCPP_CONSTEXPR_AFTER_CXX17 __link_pointer __as_link() {
        return static_cast<__link_pointer>(__base::__self());
    }
};

// ...

    _LIBCPP_INLINE_VISIBILITY
    _LIBCPP_CONSTEXPR_AFTER_CXX17 __hold_pointer
__allocate_node(__node_allocator& __na) {
      __node_pointer __p = __node_alloc_traits::allocate(__na, 1);
      __node_alloc_traits::construct(__na, __p);
      __p->__prev_ = nullptr;
      return __hold_pointer(__p, __node_destructor(__na, 1));
    }

plus making __libcpp_deallocate constexpr is sufficient to get your testcase to
work:

$ ./build/bin/clang++ -std=c++2a ~/Downloads/main-197fef.cpp -stdlib=libc++ &&
./a.out
1
$

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20191010/8297ac9a/attachment-0001.html>


More information about the llvm-bugs mailing list