* [committed] Fix set_uids_in_ptset (PR middle-end/89303)
@ 2019-02-13 13:34 Jakub Jelinek
2019-02-14 15:13 ` Rainer Orth
0 siblings, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2019-02-13 13:34 UTC (permalink / raw)
To: gcc-patches
Hi!
The following testcase is miscompiled on x86_64-linux (-m32 and -m64) at
-O1, as a pointer has two vars in points-to set, the first one is escaped
heap var and the second one is escaped non-heap var, and in the end the last
var that sets vars_contains_escaped won and overwrote
vars_contains_escaped_heap rather than oring into it.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
preapproved by Richard on IRC, committed to trunk.
Will test 8.x backport tonight and commit to 8.3 if that succeeds.
2019-02-13 Jakub Jelinek <jakub@redhat.com>
PR middle-end/89303
* tree-ssa-structalias.c (set_uids_in_ptset): Or in vi->is_heap_var
into pt->vars_contains_escaped_heap instead of setting
pt->vars_contains_escaped_heap to it.
2019-02-13 Jonathan Wakely <jwakely@redhat.com>
Jakub Jelinek <jakub@redhat.com>
PR middle-end/89303
* g++.dg/torture/pr89303.C: New test.
--- gcc/tree-ssa-structalias.c.jj 2019-01-01 12:37:18.738949011 +0100
+++ gcc/tree-ssa-structalias.c 2019-02-13 12:28:54.592256591 +0100
@@ -6412,7 +6412,7 @@ set_uids_in_ptset (bitmap into, bitmap f
&& bitmap_bit_p (escaped_vi->solution, i)))
{
pt->vars_contains_escaped = true;
- pt->vars_contains_escaped_heap = vi->is_heap_var;
+ pt->vars_contains_escaped_heap |= vi->is_heap_var;
}
if (vi->is_restrict_var)
--- gcc/testsuite/g++.dg/torture/pr89303.C.jj 2019-02-13 12:55:54.991400761 +0100
+++ gcc/testsuite/g++.dg/torture/pr89303.C 2019-02-13 13:05:04.278299534 +0100
@@ -0,0 +1,792 @@
+// PR middle-end/89303
+// { dg-do run }
+// { dg-additional-options "-std=c++14" }
+
+namespace std
+{
+ typedef __SIZE_TYPE__ size_t;
+ typedef decltype(nullptr) nullptr_t;
+
+ template<typename _Tp, _Tp __v>
+ struct integral_constant
+ {
+ static constexpr _Tp value = __v;
+ typedef _Tp value_type;
+ typedef integral_constant<_Tp, __v> type;
+ constexpr operator value_type() const noexcept { return value; }
+ constexpr value_type operator()() const noexcept { return value; }
+ };
+
+ template<typename _Tp, _Tp __v>
+ constexpr _Tp integral_constant<_Tp, __v>::value;
+
+ typedef integral_constant<bool, true> true_type;
+ typedef integral_constant<bool, false> false_type;
+
+ template<bool __v>
+ using __bool_constant = integral_constant<bool, __v>;
+
+ template<bool, typename, typename>
+ struct conditional;
+
+ template<typename...>
+ struct __and_;
+
+ template<>
+ struct __and_<>
+ : public true_type
+ { };
+
+ template<typename _B1>
+ struct __and_<_B1>
+ : public _B1
+ { };
+
+ template<typename _B1, typename _B2>
+ struct __and_<_B1, _B2>
+ : public conditional<_B1::value, _B2, _B1>::type
+ { };
+
+ template<typename _B1, typename _B2, typename _B3, typename... _Bn>
+ struct __and_<_B1, _B2, _B3, _Bn...>
+ : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
+ { };
+
+ template<typename>
+ struct remove_cv;
+
+ template<typename>
+ struct __is_void_helper
+ : public false_type { };
+
+ template<>
+ struct __is_void_helper<void>
+ : public true_type { };
+
+ template<typename _Tp>
+ struct is_void
+ : public __is_void_helper<typename remove_cv<_Tp>::type>::type
+ { };
+
+ template<typename _Tp, typename _Up = _Tp&&>
+ _Up
+ __declval(int);
+
+ template<typename _Tp>
+ _Tp
+ __declval(long);
+
+ template<typename _Tp>
+ auto declval() noexcept -> decltype(__declval<_Tp>(0));
+
+ template<typename, typename>
+ struct is_same
+ : public false_type { };
+
+ template<typename _Tp>
+ struct is_same<_Tp, _Tp>
+ : public true_type { };
+
+ template<typename _Tp>
+ struct remove_const
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_const<_Tp const>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_volatile
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_volatile<_Tp volatile>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_cv
+ {
+ typedef typename
+ remove_const<typename remove_volatile<_Tp>::type>::type type;
+ };
+
+ template<typename _Tp>
+ struct remove_reference
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&&>
+ { typedef _Tp type; };
+
+ template<bool, typename _Tp = void>
+ struct enable_if
+ { };
+
+ template<typename _Tp>
+ struct enable_if<true, _Tp>
+ { typedef _Tp type; };
+
+ template<typename... _Cond>
+ using _Require = typename enable_if<__and_<_Cond...>::value>::type;
+
+ template<bool _Cond, typename _Iftrue, typename _Iffalse>
+ struct conditional
+ { typedef _Iftrue type; };
+
+ template<typename _Iftrue, typename _Iffalse>
+ struct conditional<false, _Iftrue, _Iffalse>
+ { typedef _Iffalse type; };
+
+ template<typename _Tp>
+ struct __declval_protector
+ {
+ static const bool __stop = false;
+ };
+
+ template<typename _Tp>
+ auto declval() noexcept -> decltype(__declval<_Tp>(0))
+ {
+ static_assert(__declval_protector<_Tp>::__stop,
+ "declval() must not be used!");
+ return __declval<_Tp>(0);
+ }
+
+ namespace void_details {
+ template <class... >
+ struct make_void { using type = void; };
+}
+
+template <class... T> using __void_t = typename void_details ::make_void<T...>::type;
+
+ template<typename _Tp>
+ inline constexpr _Tp*
+ __addressof(_Tp& __r) noexcept
+ {
+ return reinterpret_cast<_Tp*>
+ (&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
+ }
+
+ template<typename _Tp>
+ constexpr _Tp&&
+ forward(typename std::remove_reference<_Tp>::type& __t) noexcept
+ { return static_cast<_Tp&&>(__t); }
+
+ template<typename _Tp>
+ constexpr _Tp&&
+ forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
+ {
+ return static_cast<_Tp&&>(__t);
+ }
+
+ template<typename _Tp>
+ constexpr typename std::remove_reference<_Tp>::type&&
+ move(_Tp&& __t) noexcept
+ { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
+}
+
+inline void* operator new(std::size_t, void* p) { return p; }
+
+extern "C" void* malloc(std::size_t);
+extern "C" void free(void*);
+
+namespace std
+{
+ template<typename T>
+ class allocator
+ {
+ public:
+ using value_type = T;
+
+ allocator() { }
+
+ template<typename U>
+ allocator(const allocator<U>&) { }
+
+ T* allocate(size_t n) { return (T*)malloc(n*sizeof(T)); }
+ void deallocate(T* p, size_t) { free(p); }
+
+ template<typename U, typename... Args>
+ void construct(U* p, Args&&... args)
+ { ::new((void*)p) U(args...); }
+
+ template<typename U>
+ void destroy(U* p)
+ { p->~U(); }
+ };
+
+ class __undefined;
+
+ template<typename _Tp, typename _Up>
+ struct __replace_first_arg
+ { };
+
+ template<template<typename, typename...> class _Template, typename _Up,
+ typename _Tp, typename... _Types>
+ struct __replace_first_arg<_Template<_Tp, _Types...>, _Up>
+ { using type = _Template<_Up, _Types...>; };
+
+ struct __allocator_traits_base
+ {
+ template<typename _Tp, typename _Up, typename = void>
+ struct __rebind : __replace_first_arg<_Tp, _Up> { };
+
+ template<typename _Tp, typename _Up>
+ struct __rebind<_Tp, _Up,
+ __void_t<typename _Tp::template rebind<_Up>::other>>
+ { using type = typename _Tp::template rebind<_Up>::other; };
+ };
+
+ template<typename _Alloc, typename _Up>
+ using __alloc_rebind
+ = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
+
+ template<typename _Alloc>
+ struct allocator_traits;
+
+ template<typename _Tp>
+ struct allocator_traits<allocator<_Tp>>
+ {
+ using allocator_type = allocator<_Tp>;
+ using value_type = _Tp;
+ using pointer = _Tp*;
+ using const_pointer = const _Tp*;
+ using size_type = std::size_t;
+
+ static pointer
+ allocate(allocator_type& __a, size_type __n)
+ { return __a.allocate(__n); }
+
+ static void
+ deallocate(allocator_type& __a, pointer __p, size_type __n)
+ { __a.deallocate(__p, __n); }
+
+ template<typename _Up, typename... _Args>
+ static void
+ construct(allocator_type& __a, _Up* __p, _Args&&... __args)
+ { __a.construct(__p, std::forward<_Args>(__args)...); }
+
+ template<typename _Up>
+ static void
+ destroy(allocator_type& __a, _Up* __p)
+ { __a.destroy(__p); }
+ };
+
+ template<typename _Alloc>
+ struct __allocated_ptr
+ {
+ using pointer = typename allocator_traits<_Alloc>::pointer;
+ using value_type = typename allocator_traits<_Alloc>::value_type;
+
+ __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
+ : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
+ { }
+
+ template<typename _Ptr,
+ typename _Req = _Require<is_same<_Ptr, value_type*>>>
+ __allocated_ptr(_Alloc& __a, _Ptr __ptr)
+ : _M_alloc(std::__addressof(__a)),
+ _M_ptr(__ptr)
+ { }
+
+ __allocated_ptr(__allocated_ptr&& __gd) noexcept
+ : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
+ { __gd._M_ptr = nullptr; }
+
+ ~__allocated_ptr()
+ {
+ if (_M_ptr != nullptr)
+ std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
+ }
+
+ __allocated_ptr&
+ operator=(std::nullptr_t) noexcept
+ {
+ _M_ptr = nullptr;
+ return *this;
+ }
+
+ value_type* get() { return _M_ptr; }
+
+ private:
+ _Alloc* _M_alloc;
+ pointer _M_ptr;
+ };
+
+ template<typename _Alloc>
+ __allocated_ptr<_Alloc>
+ __allocate_guarded(_Alloc& __a)
+ {
+ return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
+ }
+
+ template<typename _Tp>
+ struct __aligned_buffer
+ {
+ alignas(__alignof__(_Tp)) unsigned char _M_storage[sizeof(_Tp)];
+ __aligned_buffer() = default;
+
+ void*
+ _M_addr() noexcept
+ {
+ return static_cast<void*>(&_M_storage);
+ }
+
+ const void*
+ _M_addr() const noexcept
+ {
+ return static_cast<const void*>(&_M_storage);
+ }
+
+ _Tp*
+ _M_ptr() noexcept
+ { return static_cast<_Tp*>(_M_addr()); }
+
+ const _Tp*
+ _M_ptr() const noexcept
+ { return static_cast<const _Tp*>(_M_addr()); }
+ };
+
+ class bad_weak_ptr { };
+
+ inline void
+ __throw_bad_weak_ptr()
+ { (throw (bad_weak_ptr())); }
+
+ class _Sp_counted_base
+ {
+ public:
+ _Sp_counted_base() noexcept
+ : _M_use_count(1), _M_weak_count(1) { }
+
+ virtual
+ ~_Sp_counted_base() noexcept
+ { }
+
+ virtual void
+ _M_dispose() noexcept = 0;
+
+ virtual void
+ _M_destroy() noexcept
+ { delete this; }
+
+ void
+ _M_add_ref_copy()
+ { ++_M_use_count; }
+
+ void
+ _M_add_ref_lock()
+ {
+ if (_M_use_count == 0)
+ __throw_bad_weak_ptr();
+ ++_M_use_count;
+ }
+
+ void
+ _M_release() noexcept
+ {
+ if (--_M_use_count == 0)
+ {
+ _M_dispose();
+ if (--_M_weak_count == 0)
+ _M_destroy();
+ }
+ }
+
+ void
+ _M_weak_add_ref() noexcept
+ { ++_M_weak_count; }
+
+ void
+ _M_weak_release() noexcept
+ {
+ if (--_M_weak_count == 0)
+ _M_destroy();
+ }
+
+ long
+ _M_get_use_count() const noexcept
+ {
+ return _M_use_count;
+ }
+
+ private:
+ _Sp_counted_base(_Sp_counted_base const&) = delete;
+ _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
+
+ int _M_use_count;
+ int _M_weak_count;
+ };
+
+ template<typename _Tp>
+ class shared_ptr;
+
+ template<typename _Tp>
+ class weak_ptr;
+
+ template<typename _Tp>
+ class enable_shared_from_this;
+
+ class __weak_count;
+
+ class __shared_count;
+
+ template<typename _Alloc>
+ struct _Sp_alloc_shared_tag
+ {
+ const _Alloc& _M_a;
+ };
+
+ template<typename _Tp, typename _Alloc>
+ class _Sp_counted_ptr_inplace final : public _Sp_counted_base
+ {
+ class _Impl : _Alloc
+ {
+ public:
+ explicit _Impl(_Alloc __a) noexcept : _Alloc(__a) { }
+
+ _Alloc& _M_alloc() noexcept { return *this; }
+
+ __aligned_buffer<_Tp> _M_storage;
+ };
+
+ public:
+ using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
+
+ template<typename... _Args>
+ _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
+ : _M_impl(__a)
+ {
+ allocator_traits<_Alloc>::construct(__a, _M_ptr(),
+ std::forward<_Args>(__args)...);
+ }
+
+ ~_Sp_counted_ptr_inplace() noexcept { }
+
+ virtual void
+ _M_dispose() noexcept
+ {
+ allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
+ }
+
+ virtual void
+ _M_destroy() noexcept
+ {
+ __allocator_type __a(_M_impl._M_alloc());
+ __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
+ this->~_Sp_counted_ptr_inplace();
+ }
+
+ private:
+ friend class __shared_count;
+
+ _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
+
+ _Impl _M_impl;
+ };
+
+ class __shared_count
+ {
+ public:
+ constexpr __shared_count() noexcept : _M_pi(0)
+ { }
+
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
+ _Args&&... __args)
+ {
+ typedef _Sp_counted_ptr_inplace<_Tp, _Alloc> _Sp_cp_type;
+ typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
+ auto __guard = std::__allocate_guarded(__a2);
+ _Sp_cp_type* __mem = __guard.get();
+ auto __pi = ::new (__mem)
+ _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
+ __guard = nullptr;
+ _M_pi = __pi;
+ __p = __pi->_M_ptr();
+ }
+
+ ~__shared_count() noexcept
+ {
+ if (_M_pi != nullptr)
+ _M_pi->_M_release();
+ }
+
+ __shared_count(const __shared_count& __r) noexcept
+ : _M_pi(__r._M_pi)
+ {
+ if (_M_pi != 0)
+ _M_pi->_M_add_ref_copy();
+ }
+
+ explicit __shared_count(const __weak_count& __r);
+
+ long
+ _M_get_use_count() const noexcept
+ { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
+
+ private:
+ friend class __weak_count;
+
+ _Sp_counted_base* _M_pi;
+ };
+
+ class __weak_count
+ {
+ public:
+ constexpr __weak_count() noexcept : _M_pi(nullptr)
+ { }
+
+ __weak_count(const __shared_count& __r) noexcept
+ : _M_pi(__r._M_pi)
+ {
+ if (_M_pi != nullptr)
+ _M_pi->_M_weak_add_ref();
+ }
+
+ __weak_count(const __weak_count& __r) noexcept
+ : _M_pi(__r._M_pi)
+ {
+ if (_M_pi != nullptr)
+ _M_pi->_M_weak_add_ref();
+ }
+
+ __weak_count(__weak_count&& __r) noexcept
+ : _M_pi(__r._M_pi)
+ { __r._M_pi = nullptr; }
+
+ ~__weak_count() noexcept
+ {
+ if (_M_pi != nullptr)
+ {
+ _M_pi->_M_weak_release();
+ }
+ }
+
+ __weak_count&
+ operator=(const __shared_count& __r) noexcept
+ {
+ _Sp_counted_base* __tmp = __r._M_pi;
+ if (__tmp != nullptr)
+ __tmp->_M_weak_add_ref();
+ if (_M_pi != nullptr)
+ _M_pi->_M_weak_release();
+ _M_pi = __tmp;
+ return *this;
+ }
+
+ long
+ _M_get_use_count() const noexcept
+ { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
+
+ private:
+ friend class __shared_count;
+
+ _Sp_counted_base* _M_pi;
+ };
+
+ inline
+ __shared_count::__shared_count(const __weak_count& __r)
+ : _M_pi(__r._M_pi)
+ {
+ if (_M_pi != nullptr)
+ _M_pi->_M_add_ref_lock();
+ else
+ __throw_bad_weak_ptr();
+ }
+
+ template<typename _Tp>
+ class shared_ptr
+ {
+ public:
+ using element_type = _Tp;
+
+ constexpr shared_ptr() noexcept
+ : _M_ptr(0), _M_refcount()
+ { }
+
+ shared_ptr(const shared_ptr&) noexcept = default;
+ shared_ptr& operator=(const shared_ptr&) noexcept = default;
+ ~shared_ptr() = default;
+
+ template<typename _Yp>
+ explicit shared_ptr(const weak_ptr<_Yp>& __r)
+ : _M_refcount(__r._M_refcount) // may throw
+ {
+ // It is now safe to copy __r._M_ptr, as
+ // _M_refcount(__r._M_refcount) did not throw.
+ _M_ptr = __r._M_ptr;
+ }
+
+ long
+ use_count() const noexcept
+ { return _M_refcount._M_get_use_count(); }
+
+ element_type* operator->() const noexcept { return _M_ptr; }
+
+ protected:
+
+ template<typename _Alloc, typename... _Args>
+ shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
+ : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
+ { _M_enable_shared_from_this_with(_M_ptr); }
+
+ template<typename _Tp1, typename _Alloc,
+ typename... _Args>
+ friend shared_ptr<_Tp1>
+ allocate_shared(const _Alloc& __a, _Args&&... __args);
+
+ friend class weak_ptr<_Tp>;
+
+ private:
+
+ template<typename _Yp>
+ using __esft_base_t = decltype(__enable_shared_from_this_base(
+ std::declval<const __shared_count&>(),
+ std::declval<_Yp*>()));
+
+ template<typename _Yp, typename = void>
+ struct __has_esft_base
+ : false_type { };
+
+ template<typename _Yp>
+ struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
+ : true_type { };
+
+ template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
+ typename enable_if<__has_esft_base<_Yp2>::value>::type
+ _M_enable_shared_from_this_with(_Yp* __p) noexcept
+ {
+ if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
+ __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
+ }
+
+ template<typename _Tp1> friend class shared_ptr;
+ template<typename _Tp1> friend class weak_ptr;
+
+ element_type* _M_ptr;
+ __shared_count _M_refcount;
+ };
+
+ template<typename _Tp>
+ class weak_ptr
+ {
+ public:
+ using element_type = _Tp;
+
+ constexpr weak_ptr() noexcept
+ : _M_ptr(nullptr), _M_refcount()
+ { }
+
+ weak_ptr(const weak_ptr&) noexcept = default;
+
+ ~weak_ptr() = default;
+
+ weak_ptr&
+ operator=(const weak_ptr& __r) noexcept = default;
+
+ long
+ use_count() const noexcept
+ { return _M_refcount._M_get_use_count(); }
+
+ private:
+
+ void
+ _M_assign(_Tp* __ptr, const __shared_count& __refcount) noexcept
+ {
+ if (use_count() == 0)
+ {
+ _M_ptr = __ptr;
+ _M_refcount = __refcount;
+ }
+ }
+
+ template<typename _Tp1> friend class shared_ptr;
+ template<typename _Tp1> friend class weak_ptr;
+ friend class enable_shared_from_this<_Tp>;
+
+ element_type* _M_ptr;
+ __weak_count _M_refcount;
+ };
+
+ template<typename _Tp>
+ class enable_shared_from_this
+ {
+ protected:
+ constexpr enable_shared_from_this() noexcept { }
+
+ enable_shared_from_this(const enable_shared_from_this&) noexcept { }
+
+ enable_shared_from_this&
+ operator=(const enable_shared_from_this&) noexcept
+ { return *this; }
+
+ ~enable_shared_from_this() { }
+
+ public:
+ shared_ptr<_Tp>
+ shared_from_this()
+ { return shared_ptr<_Tp>(this->_M_weak_this); }
+
+ shared_ptr<const _Tp>
+ shared_from_this() const
+ { return shared_ptr<const _Tp>(this->_M_weak_this); }
+
+ private:
+ template<typename _Tp1>
+ void
+ _M_weak_assign(_Tp1* __p, const __shared_count& __n) const noexcept
+ { _M_weak_this._M_assign(__p, __n); }
+
+ friend const enable_shared_from_this*
+ __enable_shared_from_this_base(const __shared_count&,
+ const enable_shared_from_this* __p)
+ { return __p; }
+
+ template<typename>
+ friend class shared_ptr;
+
+ mutable weak_ptr<_Tp> _M_weak_this;
+ };
+
+ template<typename _Tp, typename _Alloc, typename... _Args>
+ inline shared_ptr<_Tp>
+ allocate_shared(const _Alloc& __a, _Args&&... __args)
+ {
+ return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
+ std::forward<_Args>(__args)...);
+ }
+
+ template<typename _Tp, typename... _Args>
+ inline shared_ptr<_Tp>
+ make_shared(_Args&&... __args)
+ {
+ typedef typename std::remove_const<_Tp>::type _Tp_nc;
+ return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
+ std::forward<_Args>(__args)...);
+ }
+}
+
+class blob final: public std::enable_shared_from_this<blob>
+{
+ int* data;
+
+public:
+ blob() { data = new int; }
+ ~blob() { delete data; }
+};
+
+static int
+bar(std::shared_ptr<blob>)
+{
+ return 0;
+}
+
+int main()
+{
+ std::shared_ptr<blob> tg = std::make_shared<blob>();
+ return tg->shared_from_this().use_count() - 2;
+}
Jakub
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [committed] Fix set_uids_in_ptset (PR middle-end/89303)
2019-02-13 13:34 [committed] Fix set_uids_in_ptset (PR middle-end/89303) Jakub Jelinek
@ 2019-02-14 15:13 ` Rainer Orth
2019-02-18 20:15 ` Rainer Orth
0 siblings, 1 reply; 6+ messages in thread
From: Rainer Orth @ 2019-02-14 15:13 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
Hi Jakub,
> The following testcase is miscompiled on x86_64-linux (-m32 and -m64) at
> -O1, as a pointer has two vars in points-to set, the first one is escaped
> heap var and the second one is escaped non-heap var, and in the end the last
> var that sets vars_contains_escaped won and overwrote
> vars_contains_escaped_heap rather than oring into it.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
> preapproved by Richard on IRC, committed to trunk.
> Will test 8.x backport tonight and commit to 8.3 if that succeeds.
>
> 2019-02-13 Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/89303
> * tree-ssa-structalias.c (set_uids_in_ptset): Or in vi->is_heap_var
> into pt->vars_contains_escaped_heap instead of setting
> pt->vars_contains_escaped_heap to it.
>
> 2019-02-13 Jonathan Wakely <jwakely@redhat.com>
> Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/89303
> * g++.dg/torture/pr89303.C: New test.
the new testcase FAILs on Solaris:
+FAIL: g++.dg/torture/pr89303.C -O0 (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -O1 (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -O2 (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -O2 -flto (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -O2 -flto -flto-partition=none (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -O3 -g (test for excess errors)
+FAIL: g++.dg/torture/pr89303.C -Os (test for excess errors)
Excess errors:
ld: warning: symbol 'typeinfo for std::bad_weak_ptr' has differing sizes:
(file /var/tmp//ccB1o8Ya.o value=0x8; file /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/./libstdc++-v3/src/.libs/libstdc++.so value=0xc);
/var/tmp//ccB1o8Ya.o definition taken
I suspect the class can just be renamed in pr89303.C to avoid the
conflict with include/bits/shared_ptr_base.h?
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [committed] Fix set_uids_in_ptset (PR middle-end/89303)
2019-02-14 15:13 ` Rainer Orth
@ 2019-02-18 20:15 ` Rainer Orth
2019-02-18 20:22 ` Jakub Jelinek
0 siblings, 1 reply; 6+ messages in thread
From: Rainer Orth @ 2019-02-18 20:15 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2576 bytes --]
Hi Jakub,
>> The following testcase is miscompiled on x86_64-linux (-m32 and -m64) at
>> -O1, as a pointer has two vars in points-to set, the first one is escaped
>> heap var and the second one is escaped non-heap var, and in the end the last
>> var that sets vars_contains_escaped won and overwrote
>> vars_contains_escaped_heap rather than oring into it.
>>
>> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
>> preapproved by Richard on IRC, committed to trunk.
>> Will test 8.x backport tonight and commit to 8.3 if that succeeds.
>>
>> 2019-02-13 Jakub Jelinek <jakub@redhat.com>
>>
>> PR middle-end/89303
>> * tree-ssa-structalias.c (set_uids_in_ptset): Or in vi->is_heap_var
>> into pt->vars_contains_escaped_heap instead of setting
>> pt->vars_contains_escaped_heap to it.
>>
>> 2019-02-13 Jonathan Wakely <jwakely@redhat.com>
>> Jakub Jelinek <jakub@redhat.com>
>>
>> PR middle-end/89303
>> * g++.dg/torture/pr89303.C: New test.
>
> the new testcase FAILs on Solaris:
>
> +FAIL: g++.dg/torture/pr89303.C -O0 (test for excess errors)
> +FAIL: g++.dg/torture/pr89303.C -O1 (test for excess errors)
> +FAIL: g++.dg/torture/pr89303.C -O2 (test for excess errors)
> +FAIL: g++.dg/torture/pr89303.C -O2 -flto (test for excess errors)
> +FAIL: g++.dg/torture/pr89303.C -O2 -flto -flto-partition=none (test for
> excess errors)
> +FAIL: g++.dg/torture/pr89303.C -O3 -fomit-frame-pointer -funroll-loops
> -fpeel-loops -ftracer -finline-functions (test for excess errors)
> +FAIL: g++.dg/torture/pr89303.C -O3 -g (test for excess errors)
> +FAIL: g++.dg/torture/pr89303.C -Os (test for excess errors)
>
> Excess errors:
> ld: warning: symbol 'typeinfo for std::bad_weak_ptr' has differing sizes:
> (file /var/tmp//ccB1o8Ya.o value=0x8; file
> /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/./libstdc++-v3/src/.libs/libstdc++.so
> value=0xc);
> /var/tmp//ccB1o8Ya.o definition taken
>
> I suspect the class can just be renamed in pr89303.C to avoid the
> conflict with include/bits/shared_ptr_base.h?
the following patch does this. I've verified that it still FAILs on
x86_64-pc-linux-gnu before your patch and PASSes afterwards, as well as
avoiding the linker warning on i386-pc-solaris2.11.
Ok for mainline?
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
2019-02-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/torture/pr89303.C (bad_weak_ptr): Rename to
bad_weak_ptr_.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sol2-testsuite-pr89303.patch --]
[-- Type: text/x-patch, Size: 603 bytes --]
# HG changeset patch
# Parent 056fe4093ce40dc462c6b50c3ae49df032a92230
Fix g++.dg/torture/pr89303.C with Solaris ld
diff --git a/gcc/testsuite/g++.dg/torture/pr89303.C b/gcc/testsuite/g++.dg/torture/pr89303.C
--- a/gcc/testsuite/g++.dg/torture/pr89303.C
+++ b/gcc/testsuite/g++.dg/torture/pr89303.C
@@ -350,11 +350,11 @@ namespace std
{ return static_cast<const _Tp*>(_M_addr()); }
};
- class bad_weak_ptr { };
+ class bad_weak_ptr_ { };
inline void
__throw_bad_weak_ptr()
- { (throw (bad_weak_ptr())); }
+ { (throw (bad_weak_ptr_())); }
class _Sp_counted_base
{
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [committed] Fix set_uids_in_ptset (PR middle-end/89303)
2019-02-18 20:15 ` Rainer Orth
@ 2019-02-18 20:22 ` Jakub Jelinek
2019-02-19 2:52 ` Jonathan Wakely
0 siblings, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2019-02-18 20:22 UTC (permalink / raw)
To: Rainer Orth, Jonathan Wakely; +Cc: gcc-patches
On Mon, Feb 18, 2019 at 09:15:39PM +0100, Rainer Orth wrote:
> 2019-02-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
>
> * g++.dg/torture/pr89303.C (bad_weak_ptr): Rename to
> bad_weak_ptr_.
Ok, thanks.
If needed, guess we could rename much more (or rename the namespace in which
most of it is from std to my_std, though we'd need to check for stuff that
needs to be in std namespace).
> # HG changeset patch
> # Parent 056fe4093ce40dc462c6b50c3ae49df032a92230
> Fix g++.dg/torture/pr89303.C with Solaris ld
>
> diff --git a/gcc/testsuite/g++.dg/torture/pr89303.C b/gcc/testsuite/g++.dg/torture/pr89303.C
> --- a/gcc/testsuite/g++.dg/torture/pr89303.C
> +++ b/gcc/testsuite/g++.dg/torture/pr89303.C
> @@ -350,11 +350,11 @@ namespace std
> { return static_cast<const _Tp*>(_M_addr()); }
> };
>
> - class bad_weak_ptr { };
> + class bad_weak_ptr_ { };
>
> inline void
> __throw_bad_weak_ptr()
> - { (throw (bad_weak_ptr())); }
> + { (throw (bad_weak_ptr_())); }
>
> class _Sp_counted_base
> {
Jakub
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [committed] Fix set_uids_in_ptset (PR middle-end/89303)
2019-02-18 20:22 ` Jakub Jelinek
@ 2019-02-19 2:52 ` Jonathan Wakely
2019-02-19 9:20 ` Jakub Jelinek
0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Wakely @ 2019-02-19 2:52 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Rainer Orth, gcc-patches
On 18/02/19 21:22 +0100, Jakub Jelinek wrote:
>On Mon, Feb 18, 2019 at 09:15:39PM +0100, Rainer Orth wrote:
>> 2019-02-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
>>
>> * g++.dg/torture/pr89303.C (bad_weak_ptr): Rename to
>> bad_weak_ptr_.
>
>Ok, thanks.
>If needed, guess we could rename much more (or rename the namespace in which
>most of it is from std to my_std, though we'd need to check for stuff that
>needs to be in std namespace).
I think that whole testcase could be in some non-std namespace. I
don't think there are any magic functions or types that need to be in
namespace std to work correctly.
>> # HG changeset patch
>> # Parent 056fe4093ce40dc462c6b50c3ae49df032a92230
>> Fix g++.dg/torture/pr89303.C with Solaris ld
>>
>> diff --git a/gcc/testsuite/g++.dg/torture/pr89303.C b/gcc/testsuite/g++.dg/torture/pr89303.C
>> --- a/gcc/testsuite/g++.dg/torture/pr89303.C
>> +++ b/gcc/testsuite/g++.dg/torture/pr89303.C
>> @@ -350,11 +350,11 @@ namespace std
>> { return static_cast<const _Tp*>(_M_addr()); }
>> };
>>
>> - class bad_weak_ptr { };
>> + class bad_weak_ptr_ { };
>>
>> inline void
>> __throw_bad_weak_ptr()
>> - { (throw (bad_weak_ptr())); }
>> + { (throw (bad_weak_ptr_())); }
>>
>> class _Sp_counted_base
>> {
>
>
> Jakub
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [committed] Fix set_uids_in_ptset (PR middle-end/89303)
2019-02-19 2:52 ` Jonathan Wakely
@ 2019-02-19 9:20 ` Jakub Jelinek
0 siblings, 0 replies; 6+ messages in thread
From: Jakub Jelinek @ 2019-02-19 9:20 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: Rainer Orth, gcc-patches
On Tue, Feb 19, 2019 at 02:52:54AM +0000, Jonathan Wakely wrote:
> On 18/02/19 21:22 +0100, Jakub Jelinek wrote:
> > On Mon, Feb 18, 2019 at 09:15:39PM +0100, Rainer Orth wrote:
> > > 2019-02-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
> > >
> > > * g++.dg/torture/pr89303.C (bad_weak_ptr): Rename to
> > > bad_weak_ptr_.
> >
> > Ok, thanks.
> > If needed, guess we could rename much more (or rename the namespace in which
> > most of it is from std to my_std, though we'd need to check for stuff that
> > needs to be in std namespace).
>
> I think that whole testcase could be in some non-std namespace. I
> don't think there are any magic functions or types that need to be in
> namespace std to work correctly.
Ok, I've tested following (both with the tree-ssa-structalias.c change
reverted and vanilla) and committed to trunk and 8.3 (for 8.3 without
reversion of Rainer's change of course):
2019-02-19 Jakub Jelinek <jakub@redhat.com>
PR middle-end/89303
* g++.dg/torture/pr89303.C: Move everything from std namespace to my
namespace.
--- gcc/testsuite/g++.dg/torture/pr89303.C.jj 2019-02-19 09:33:15.000193513 +0100
+++ gcc/testsuite/g++.dg/torture/pr89303.C 2019-02-19 09:51:47.197721460 +0100
@@ -2,7 +2,7 @@
// { dg-do run }
// { dg-additional-options "-std=c++14" }
-namespace std
+namespace my
{
typedef __SIZE_TYPE__ size_t;
typedef decltype(nullptr) nullptr_t;
@@ -172,28 +172,28 @@ template <class... T> using __void_t = t
template<typename _Tp>
constexpr _Tp&&
- forward(typename std::remove_reference<_Tp>::type& __t) noexcept
+ forward(typename my::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
template<typename _Tp>
constexpr _Tp&&
- forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
+ forward(typename my::remove_reference<_Tp>::type&& __t) noexcept
{
return static_cast<_Tp&&>(__t);
}
template<typename _Tp>
- constexpr typename std::remove_reference<_Tp>::type&&
+ constexpr typename my::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
- { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
+ { return static_cast<typename my::remove_reference<_Tp>::type&&>(__t); }
}
-inline void* operator new(std::size_t, void* p) { return p; }
+inline void* operator new(my::size_t, void* p) { return p; }
-extern "C" void* malloc(std::size_t);
+extern "C" void* malloc(my::size_t);
extern "C" void free(void*);
-namespace std
+namespace my
{
template<typename T>
class allocator
@@ -254,7 +254,7 @@ namespace std
using value_type = _Tp;
using pointer = _Tp*;
using const_pointer = const _Tp*;
- using size_type = std::size_t;
+ using size_type = my::size_t;
static pointer
allocate(allocator_type& __a, size_type __n)
@@ -267,7 +267,7 @@ namespace std
template<typename _Up, typename... _Args>
static void
construct(allocator_type& __a, _Up* __p, _Args&&... __args)
- { __a.construct(__p, std::forward<_Args>(__args)...); }
+ { __a.construct(__p, my::forward<_Args>(__args)...); }
template<typename _Up>
static void
@@ -282,13 +282,13 @@ namespace std
using value_type = typename allocator_traits<_Alloc>::value_type;
__allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
- : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
+ : _M_alloc(my::__addressof(__a)), _M_ptr(__ptr)
{ }
template<typename _Ptr,
typename _Req = _Require<is_same<_Ptr, value_type*>>>
__allocated_ptr(_Alloc& __a, _Ptr __ptr)
- : _M_alloc(std::__addressof(__a)),
+ : _M_alloc(my::__addressof(__a)),
_M_ptr(__ptr)
{ }
@@ -299,11 +299,11 @@ namespace std
~__allocated_ptr()
{
if (_M_ptr != nullptr)
- std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
+ my::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
}
__allocated_ptr&
- operator=(std::nullptr_t) noexcept
+ operator=(my::nullptr_t) noexcept
{
_M_ptr = nullptr;
return *this;
@@ -320,7 +320,7 @@ namespace std
__allocated_ptr<_Alloc>
__allocate_guarded(_Alloc& __a)
{
- return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
+ return { __a, my::allocator_traits<_Alloc>::allocate(__a, 1) };
}
template<typename _Tp>
@@ -350,11 +350,11 @@ namespace std
{ return static_cast<const _Tp*>(_M_addr()); }
};
- class bad_weak_ptr_ { };
+ class bad_weak_ptr { };
inline void
__throw_bad_weak_ptr()
- { (throw (bad_weak_ptr_())); }
+ { (throw (bad_weak_ptr())); }
class _Sp_counted_base
{
@@ -461,7 +461,7 @@ namespace std
: _M_impl(__a)
{
allocator_traits<_Alloc>::construct(__a, _M_ptr(),
- std::forward<_Args>(__args)...);
+ my::forward<_Args>(__args)...);
}
~_Sp_counted_ptr_inplace() noexcept { }
@@ -500,10 +500,10 @@ namespace std
{
typedef _Sp_counted_ptr_inplace<_Tp, _Alloc> _Sp_cp_type;
typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
- auto __guard = std::__allocate_guarded(__a2);
+ auto __guard = my::__allocate_guarded(__a2);
_Sp_cp_type* __mem = __guard.get();
auto __pi = ::new (__mem)
- _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
+ _Sp_cp_type(__a._M_a, my::forward<_Args>(__args)...);
__guard = nullptr;
_M_pi = __pi;
__p = __pi->_M_ptr();
@@ -631,7 +631,7 @@ namespace std
template<typename _Alloc, typename... _Args>
shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
- : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
+ : _M_ptr(), _M_refcount(_M_ptr, __tag, my::forward<_Args>(__args)...)
{ _M_enable_shared_from_this_with(_M_ptr); }
template<typename _Tp1, typename _Alloc,
@@ -645,8 +645,8 @@ namespace std
template<typename _Yp>
using __esft_base_t = decltype(__enable_shared_from_this_base(
- std::declval<const __shared_count&>(),
- std::declval<_Yp*>()));
+ my::declval<const __shared_count&>(),
+ my::declval<_Yp*>()));
template<typename _Yp, typename = void>
struct __has_esft_base
@@ -757,20 +757,20 @@ namespace std
allocate_shared(const _Alloc& __a, _Args&&... __args)
{
return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
- std::forward<_Args>(__args)...);
+ my::forward<_Args>(__args)...);
}
template<typename _Tp, typename... _Args>
inline shared_ptr<_Tp>
make_shared(_Args&&... __args)
{
- typedef typename std::remove_const<_Tp>::type _Tp_nc;
- return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
- std::forward<_Args>(__args)...);
+ typedef typename my::remove_const<_Tp>::type _Tp_nc;
+ return my::allocate_shared<_Tp>(my::allocator<_Tp_nc>(),
+ my::forward<_Args>(__args)...);
}
}
-class blob final: public std::enable_shared_from_this<blob>
+class blob final: public my::enable_shared_from_this<blob>
{
int* data;
@@ -780,13 +780,13 @@ public:
};
static int
-bar(std::shared_ptr<blob>)
+bar(my::shared_ptr<blob>)
{
return 0;
}
int main()
{
- std::shared_ptr<blob> tg = std::make_shared<blob>();
+ my::shared_ptr<blob> tg = my::make_shared<blob>();
return tg->shared_from_this().use_count() - 2;
}
Jakub
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-02-19 9:20 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-13 13:34 [committed] Fix set_uids_in_ptset (PR middle-end/89303) Jakub Jelinek
2019-02-14 15:13 ` Rainer Orth
2019-02-18 20:15 ` Rainer Orth
2019-02-18 20:22 ` Jakub Jelinek
2019-02-19 2:52 ` Jonathan Wakely
2019-02-19 9:20 ` Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).