[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