From: "François Dumont" <frs.dumont@gmail.com>
To: Jonathan Wakely <jwakely.gcc@gmail.com>
Cc: Jonathan Wakely <jwakely@redhat.com>,
"libstdc++@gcc.gnu.org" <libstdc++@gcc.gnu.org>,
gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: vector lightweight debug mode
Date: Wed, 07 Oct 2015 19:38:00 -0000 [thread overview]
Message-ID: <561574BE.1060005@gmail.com> (raw)
In-Reply-To: <CAH6eHdSR-GM2uYUOyxmi6voLOn1CreSFp=tVRJigf9oSDCZ_dQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3828 bytes --]
Hi
I completed vector assertion mode. Here is the result of the new
test you will find in the attached patch.
With debug mode:
/home/fdt/dev/gcc/build_git/x86_64-unknown-linux-gnu/libstdc++-v3/include/debug/safe_iterator.h:375:
Error: attempt to advance a dereferenceable (start-of-sequence) iterator 2
steps, which falls outside its valid range.
Objects involved in the operation:
iterator @ 0x0x7fff1c346760 {
type =
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*,
std::__cxx1998::vector<int, std::allocator<int> > >,
std::__debug::vector<int, std::allocator<int> > > (mutable iterator);
state = dereferenceable (start-of-sequence);
references sequence with type 'std::__debug::vector<int,
std::allocator<int> >' @ 0x0x7fff1c3469a0
}
XFAIL: 23_containers/vector/debug/insert8_neg.cc execution test
With assertion mode:
/home/fdt/dev/gcc/build_git/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/stl_vector.h:1124:
Error: invalid insert position outside container [begin, end) range.
Objects involved in the operation:
sequence "this" @ 0x0x7fff60b1f870 {
type = std::vector<int, std::allocator<int> >;
}
iterator "__position" @ 0x0x7fff60b1f860 {
type = __gnu_cxx::__normal_iterator<int const*, std::vector<int,
std::allocator<int> > >;
}
XFAIL: 23_containers/vector/debug/insert8_neg.cc execution test
As expected assertion mode doesn't detect invalid operation on the
iterator but only its usage later.
There is still one debug assertion I would like to use in assertion
mode: __valid_range. I could use it to check erase range and iterator
range used on the insert method. But for that it means including
<debug/helper_functions.h> and so:
#include <bits/stl_iterator_base_types.h> // for iterator_traits,
// categories and _Iter_base
#include <bits/cpp_type_traits.h> // for __is_integer
#include <bits/stl_pair.h> // for pair
That looks fine to me, what do you think ?
François
On 19/09/2015 11:47, Jonathan Wakely wrote:
> On 19 September 2015 at 10:12, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> On 19 September 2015 at 08:31, François Dumont wrote:
>>> On 16/09/2015 22:29, Jonathan Wakely wrote:
>>>> No, because it is undefined to compare iterators that belong to
>>>> different containers, or to compare pointers that point to different
>>>> arrays.
>>>>
>>> (Written before Christopher reply:)
>>>
>>> At least program will compile only if iterator is coming from a vector
>>> of the same type. So behavior is undefined only if user pass an invalid
>>> iterator which is exactly what this check tries to detect, isn't it
>>> paradoxical ? If this undefined behavior results in the program abortion
>>> this is what should happen anyway. If it doesn't abort then the program
>>> will definitely not behaves as expected so this check doesn't make
>>> anything worst, no ?
>> The problem is that undefined behaviour can "travel backwards in time".
>>
>> It's not as simple as saying that if the invalid check happens _then_
>> undefined behaviour happens afterwards.
> Just to be clear, I agree that it can't hurt a correct program (except
> for the small cost of doing the checks).
>
> My concern was that for an incorrect program (which is the entire
> purpose of adding the checks) the results could be unpredictable. It
> might abort, which is the desired behaviour, or it might do something
> else and keep executing, and in that case it could be harmful for
> debugging because users would look at the source and think "well my
> iterators must be in range, otherwise that assertion would have
> failed, so the bug must be elsewhere".
>
> However ...
>
>> However, Google seem to find these checks useful, and you and Chris
>> are in favour, so let's keep them.
[-- Attachment #2: vector_debug.patch --]
[-- Type: text/x-patch, Size: 17537 bytes --]
diff --git libstdc++-v3/include/bits/stl_vector.h libstdc++-v3/include/bits/stl_vector.h
index 305d446..23e2e6a 100644
--- libstdc++-v3/include/bits/stl_vector.h
+++ libstdc++-v3/include/bits/stl_vector.h
@@ -63,6 +63,8 @@
#include <initializer_list>
#endif
+#include <debug/debug.h>
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
@@ -778,7 +780,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
operator[](size_type __n) _GLIBCXX_NOEXCEPT
- { return *(this->_M_impl._M_start + __n); }
+ {
+ __glibcxx_requires_subscript(__n);
+ return *(this->_M_impl._M_start + __n);
+ }
/**
* @brief Subscript access to the data contained in the %vector.
@@ -793,7 +798,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
operator[](size_type __n) const _GLIBCXX_NOEXCEPT
- { return *(this->_M_impl._M_start + __n); }
+ {
+ __glibcxx_requires_subscript(__n);
+ return *(this->_M_impl._M_start + __n);
+ }
protected:
/// Safety check used only from at().
@@ -850,7 +858,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
front() _GLIBCXX_NOEXCEPT
- { return *begin(); }
+ {
+ __glibcxx_requires_nonempty();
+ return *begin();
+ }
/**
* Returns a read-only (constant) reference to the data at the first
@@ -858,7 +869,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
front() const _GLIBCXX_NOEXCEPT
- { return *begin(); }
+ {
+ __glibcxx_requires_nonempty();
+ return *begin();
+ }
/**
* Returns a read/write reference to the data at the last
@@ -866,7 +880,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
reference
back() _GLIBCXX_NOEXCEPT
- { return *(end() - 1); }
+ {
+ __glibcxx_requires_nonempty();
+ return *(end() - 1);
+ }
/**
* Returns a read-only (constant) reference to the data at the
@@ -874,7 +891,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
const_reference
back() const _GLIBCXX_NOEXCEPT
- { return *(end() - 1); }
+ {
+ __glibcxx_requires_nonempty();
+ return *(end() - 1);
+ }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 464. Suggestion for new member functions in standard containers.
@@ -949,6 +969,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
pop_back() _GLIBCXX_NOEXCEPT
{
+ __glibcxx_requires_nonempty();
--this->_M_impl._M_finish;
_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
}
@@ -1051,6 +1072,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator
insert(const_iterator __position, size_type __n, const value_type& __x)
{
+ __glibcxx_requires_valid_insert_position(__position);
difference_type __offset = __position - cbegin();
_M_fill_insert(begin() + __offset, __n, __x);
return begin() + __offset;
@@ -1071,7 +1093,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
void
insert(iterator __position, size_type __n, const value_type& __x)
- { _M_fill_insert(__position, __n, __x); }
+ {
+ __glibcxx_requires_valid_insert_position(__position);
+ _M_fill_insert(__position, __n, __x);
+ }
#endif
#if __cplusplus >= 201103L
@@ -1096,6 +1121,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(const_iterator __position, _InputIterator __first,
_InputIterator __last)
{
+ __glibcxx_requires_valid_insert_position(__position);
difference_type __offset = __position - cbegin();
_M_insert_dispatch(begin() + __offset,
__first, __last, __false_type());
@@ -1121,6 +1147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
+ __glibcxx_requires_valid_insert_position(__position);
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
_M_insert_dispatch(__position, __first, __last, _Integral());
@@ -1145,10 +1172,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator
#if __cplusplus >= 201103L
erase(const_iterator __position)
- { return _M_erase(begin() + (__position - cbegin())); }
+ {
+ __glibcxx_requires_valid_erase_position(__position);
+ return _M_erase(begin() + (__position - cbegin()));
+ }
#else
erase(iterator __position)
- { return _M_erase(__position); }
+ {
+ __glibcxx_requires_valid_erase_position(__position);
+ return _M_erase(__position);
+ }
#endif
/**
@@ -1173,13 +1206,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
erase(const_iterator __first, const_iterator __last)
{
+ __glibcxx_assert(__first < __last || !(__last < __first));
+ __glibcxx_assert((cbegin() < __first || !(__first < cbegin()))
+ && (__first < cend() || __first == __last));
+ __glibcxx_assert((cbegin() < __last || __first == __last)
+ && (__last < cend() || !(cend() < __last)));
const auto __beg = begin();
const auto __cbeg = cbegin();
return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
}
#else
erase(iterator __first, iterator __last)
- { return _M_erase(__first, __last); }
+ {
+ __glibcxx_assert(__first < __last || !(__last < __first));
+ __glibcxx_assert((begin() < __first || !(__first < begin()))
+ && (__first < end() || __first == __last));
+ __glibcxx_assert((begin() < __last || __first == __last)
+ && (__last < end() || !(end() < __last)));
+ return _M_erase(__first, __last);
+ }
#endif
/**
@@ -1194,6 +1239,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
swap(vector& __x) _GLIBCXX_NOEXCEPT
{
+#if __cplusplus >= 201103L
+ __glibcxx_requires_cond(
+ _Alloc_traits::propagate_on_container_swap::value
+ || _M_get_Tp_allocator() == __x._M_get_Tp_allocator(),
+ _M_message(__gnu_debug::__msg_equal_allocs)
+ ._M_sequence(this, "this"));
+#endif
this->_M_impl._M_swap_data(__x._M_impl);
_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
__x._M_get_Tp_allocator());
diff --git libstdc++-v3/include/bits/vector.tcc libstdc++-v3/include/bits/vector.tcc
index 34118a4..965dab3 100644
--- libstdc++-v3/include/bits/vector.tcc
+++ libstdc++-v3/include/bits/vector.tcc
@@ -111,6 +111,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
insert(iterator __position, const value_type& __x)
#endif
{
+ __glibcxx_requires_valid_insert_position(__position);
const size_type __n = __position - begin();
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
&& __position == end())
@@ -301,6 +302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
vector<_Tp, _Alloc>::
emplace(const_iterator __position, _Args&&... __args)
{
+ __glibcxx_requires_valid_insert_position(__position);
const size_type __n = __position - begin();
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
&& __position == end())
diff --git libstdc++-v3/include/debug/debug.h libstdc++-v3/include/debug/debug.h
index b5935fe..8a3eb3b 100644
--- libstdc++-v3/include/debug/debug.h
+++ libstdc++-v3/include/debug/debug.h
@@ -74,33 +74,26 @@ namespace __gnu_debug
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred)
# define __glibcxx_requires_string(_String)
# define __glibcxx_requires_string_len(_String,_Len)
-# define __glibcxx_requires_subscript(_N)
# define __glibcxx_requires_irreflexive(_First,_Last)
# define __glibcxx_requires_irreflexive2(_First,_Last)
# define __glibcxx_requires_irreflexive_pred(_First,_Last,_Pred)
# define __glibcxx_requires_irreflexive_pred2(_First,_Last,_Pred)
-#ifdef _GLIBCXX_ASSERTIONS
-// Verify that [_First, _Last) forms a non-empty iterator range.
-# define __glibcxx_requires_non_empty_range(_First,_Last) \
- __glibcxx_assert(_First != _Last)
-// Verify that the container is nonempty
-# define __glibcxx_requires_nonempty() \
- __glibcxx_assert(! this->empty())
-#else
-# define __glibcxx_requires_non_empty_range(_First,_Last)
-# define __glibcxx_requires_nonempty()
#endif
+#ifndef _GLIBCXX_ASSERTIONS
+# define __glibcxx_requires_non_empty_range(_First,_Last)
+# define __glibcxx_requires_valid_insert_position(_Position)
+# define __glibcxx_requires_valid_erase_position(_Position)
+# define __glibcxx_requires_nonempty()
+# define __glibcxx_requires_subscript(_N)
#else
# include <debug/macros.h>
-# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
+# ifdef _GLIBCXX_DEBUG
# define __glibcxx_requires_valid_range(_First,_Last) \
__glibcxx_check_valid_range(_First,_Last)
-# define __glibcxx_requires_non_empty_range(_First,_Last) \
- __glibcxx_check_non_empty_range(_First,_Last)
# define __glibcxx_requires_sorted(_First,_Last) \
__glibcxx_check_sorted(_First,_Last)
# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \
@@ -121,11 +114,9 @@ namespace __gnu_debug
__glibcxx_check_heap(_First,_Last)
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \
__glibcxx_check_heap_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty()
# define __glibcxx_requires_string(_String) __glibcxx_check_string(_String)
# define __glibcxx_requires_string_len(_String,_Len) \
__glibcxx_check_string_len(_String,_Len)
-# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N)
# define __glibcxx_requires_irreflexive(_First,_Last) \
__glibcxx_check_irreflexive(_First,_Last)
# define __glibcxx_requires_irreflexive2(_First,_Last) \
@@ -136,6 +127,19 @@ namespace __gnu_debug
__glibcxx_check_irreflexive_pred2(_First,_Last,_Pred)
# include <debug/functions.h>
+#endif
+
+# define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
+# define __glibcxx_requires_valid_insert_position(_Position) \
+ __glibcxx_check_insert2(_Position)
+# define __glibcxx_requires_valid_erase_position(_Position) \
+ __glibcxx_check_erase2(_Position)
+# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N)
+# define __glibcxx_requires_non_empty_range(_First,_Last) \
+ __glibcxx_check_non_empty_range(_First,_Last)
+# define __glibcxx_requires_nonempty() __glibcxx_check_nonempty()
+
+# include <debug/formatter.h>
#endif
diff --git libstdc++-v3/include/debug/formatter.h libstdc++-v3/include/debug/formatter.h
index 6e56c8f..921d1bc 100644
--- libstdc++-v3/include/debug/formatter.h
+++ libstdc++-v3/include/debug/formatter.h
@@ -47,8 +47,22 @@ namespace __gnu_debug
{
using std::type_info;
+ // An arbitrary iterator pointer is not singular.
+ inline bool
+ __check_singular_aux(const void*) { return false; }
+
+ // We may have an iterator that derives from _Safe_iterator_base but isn't
+ // a _Safe_iterator.
template<typename _Iterator>
- bool __check_singular(const _Iterator&);
+ inline bool
+ __check_singular(const _Iterator& __x)
+ { return __check_singular_aux(std::__addressof(__x)); }
+
+ /** Non-NULL pointers are nonsingular. */
+ template<typename _Tp>
+ inline bool
+ __check_singular(const _Tp* __ptr)
+ { return __ptr == 0; }
class _Safe_sequence_base;
diff --git libstdc++-v3/include/debug/functions.h libstdc++-v3/include/debug/functions.h
index 218092a..3437b22 100644
--- libstdc++-v3/include/debug/functions.h
+++ libstdc++-v3/include/debug/functions.h
@@ -51,23 +51,6 @@ namespace __gnu_debug
template<typename _Sequence>
struct _Is_contiguous_sequence : std::__false_type { };
- // An arbitrary iterator pointer is not singular.
- inline bool
- __check_singular_aux(const void*) { return false; }
-
- // We may have an iterator that derives from _Safe_iterator_base but isn't
- // a _Safe_iterator.
- template<typename _Iterator>
- inline bool
- __check_singular(const _Iterator& __x)
- { return __check_singular_aux(std::__addressof(__x)); }
-
- /** Non-NULL pointers are nonsingular. */
- template<typename _Tp>
- inline bool
- __check_singular(const _Tp* __ptr)
- { return __ptr == 0; }
-
/** Assume that some arbitrary iterator is dereferenceable, because we
can't prove that it isn't. */
template<typename _Iterator>
diff --git libstdc++-v3/include/debug/macros.h libstdc++-v3/include/debug/macros.h
index c636663..71a3744 100644
--- libstdc++-v3/include/debug/macros.h
+++ libstdc++-v3/include/debug/macros.h
@@ -86,6 +86,25 @@ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
._M_sequence(*this, "this") \
._M_iterator(_Position, #_Position))
+/** The same as previous macro but when _Position is not a debug iterator. */
+#if __cplusplus >= 201103L
+# define __glibcxx_check_insert2(_Position) \
+_GLIBCXX_DEBUG_VERIFY((cbegin() < _Position || !(_Position < cbegin())) \
+ && (_Position < cend() || !(cend() < _Position)), \
+ _M_message("invalid insert position outside container" \
+ " [begin, end) range") \
+ ._M_sequence(*this, "this") \
+ ._M_iterator(_Position, #_Position))
+#else
+# define __glibcxx_check_insert2(_Position) \
+_GLIBCXX_DEBUG_VERIFY((begin() < _Position || !(_Position < begin())) \
+ && (_Position < end() || !(end() < _Position)), \
+ _M_message("invalid insert position outside container" \
+ " [begin, end) range") \
+ ._M_sequence(*this, "this") \
+ ._M_iterator(_Position, #_Position))
+#endif
+
/** Verify that we can insert into *this after the iterator _Position.
* Insertion into a container after a specific position requires that
* the iterator be nonsingular, either dereferenceable or before-begin,
@@ -152,6 +171,24 @@ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
._M_sequence(*this, "this") \
._M_iterator(_Position, #_Position))
+/** Same as above but for normal (non-debug) containers. */
+#if __cplusplus >= 201103L
+# define __glibcxx_check_erase2(_Position) \
+_GLIBCXX_DEBUG_VERIFY((cbegin() < _Position || !(_Position < cbegin())) \
+ && _Position < cend(), \
+ _M_message(__gnu_debug::__msg_erase_bad) \
+ ._M_sequence(*this, "this") \
+ ._M_iterator(_Position, #_Position));
+#else
+# define __glibcxx_check_erase2(_Position) \
+_GLIBCXX_DEBUG_VERIFY((begin() < _Position || !(_Position < begin())) \
+ && _Position < end(), \
+ _M_message(__gnu_debug::__msg_erase_bad) \
+ ._M_sequence(*this, "this") \
+ ._M_iterator(_Position, #_Position));
+#endif
+
+
/** Verify that we can erase the element after the iterator
* _Position. We can erase the element if the _Position iterator is
* before a dereferenceable one and references this sequence.
diff --git libstdc++-v3/include/debug/vector libstdc++-v3/include/debug/vector
index fede4f0..7fccf28 100644
--- libstdc++-v3/include/debug/vector
+++ libstdc++-v3/include/debug/vector
@@ -406,49 +406,10 @@ namespace __debug
}
// element access:
- reference
- operator[](size_type __n) _GLIBCXX_NOEXCEPT
- {
- __glibcxx_check_subscript(__n);
- return _M_base()[__n];
- }
-
- const_reference
- operator[](size_type __n) const _GLIBCXX_NOEXCEPT
- {
- __glibcxx_check_subscript(__n);
- return _M_base()[__n];
- }
-
+ using _Base::operator[];
using _Base::at;
-
- reference
- front() _GLIBCXX_NOEXCEPT
- {
- __glibcxx_check_nonempty();
- return _Base::front();
- }
-
- const_reference
- front() const _GLIBCXX_NOEXCEPT
- {
- __glibcxx_check_nonempty();
- return _Base::front();
- }
-
- reference
- back() _GLIBCXX_NOEXCEPT
- {
- __glibcxx_check_nonempty();
- return _Base::back();
- }
-
- const_reference
- back() const _GLIBCXX_NOEXCEPT
- {
- __glibcxx_check_nonempty();
- return _Base::back();
- }
+ using _Base::front;
+ using _Base::back;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 464. Suggestion for new member functions in standard containers.
diff --git libstdc++-v3/testsuite/23_containers/vector/debug/insert8_neg.cc libstdc++-v3/testsuite/23_containers/vector/debug/insert8_neg.cc
new file mode 100644
index 0000000..5d915c2
--- /dev/null
+++ libstdc++-v3/testsuite/23_containers/vector/debug/insert8_neg.cc
@@ -0,0 +1,41 @@
+// -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-D_GLIBCXX_ASSERTIONS" }
+// { dg-do run { xfail *-*-* } }
+
+#include <iterator>
+
+#include <vector>
+
+void
+test01()
+{
+ std::vector<int> v1, v2;
+
+ v1.push_back(0);
+
+ v1.insert(v1.begin() + 2, v2.begin(), v2.end());
+}
+
+int
+main()
+{
+ test01();
+}
next prev parent reply other threads:[~2015-10-07 19:38 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-14 18:30 François Dumont
2015-09-14 19:55 ` Jonathan Wakely
2015-09-16 19:43 ` François Dumont
2015-09-16 20:53 ` Jonathan Wakely
[not found] ` <CA+jCFLueUi0Zo4m2D-scXNG5JLVSObKbJgXWaQRJrQ+notbXzg@mail.gmail.com>
2015-09-17 21:14 ` Fwd: " Christopher Jefferson
2015-09-19 9:12 ` Jonathan Wakely
2015-09-19 9:09 ` François Dumont
2015-09-19 9:48 ` Jonathan Wakely
2015-09-19 12:00 ` Jonathan Wakely
2015-10-07 19:38 ` François Dumont [this message]
2015-10-07 20:09 ` Jonathan Wakely
2015-10-12 19:43 ` François Dumont
2015-11-15 21:12 ` François Dumont
2015-11-16 10:29 ` Jonathan Wakely
2015-11-17 19:49 ` François Dumont
2015-11-18 12:27 ` Jonathan Wakely
2015-11-18 12:34 ` Jonathan Wakely
2015-11-19 21:17 ` François Dumont
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=561574BE.1060005@gmail.com \
--to=frs.dumont@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jwakely.gcc@gmail.com \
--cc=jwakely@redhat.com \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).