[Bug libstdc++/94540] New: stack overflow populating std::vector<very large type>
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Apr 9 13:03:58 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94540
Bug ID: 94540
Summary: stack overflow populating std::vector<very large type>
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
#include <vector>
struct yooj_type { char data[20*1024*1024]; };
int main() {
std::vector<yooj_type> v(1);
}
This dies with SIGSEGV due to a stack overflow, because a yooj_type temporary
is created on the stack in <bits/stl_uninitialized.h>:
template<>
struct __uninitialized_default_1<true>
{
template<typename _ForwardIterator>
static void
__uninit_default(_ForwardIterator __first, _ForwardIterator __last)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
std::fill(__first, __last, _ValueType());
}
};
We should either avoid using std::fill for large objects (for some arbitrary
meaning of large) or we should construct the first object in place and then use
that as the fill argument:
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -549,7 +549,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- std::fill(__first, __last, _ValueType());
+ if (__first == __last)
+ return;
+
+ const _ValueType& __val
+ = *std::_Construct(std::__addressof(*__first));
+ if (++__first != __last)
+ std::fill(__first, __last, __val);
}
};
@@ -585,7 +591,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
- return std::fill_n(__first, __n, _ValueType());
+ if (__size_to_integer(__n) <= 0)
+ return __first;
+
+ const _ValueType& __val
+ = *std::_Construct(std::__addressof(*__first));
+ return std::fill_n(++__first, __size_to_integer(__n) - 1, __val);
}
};
I'm concerned this will confuse the optimisers, but haven't checked yet.
More information about the Gcc-bugs
mailing list