aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/valarray
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-11-01 11:06:51 +0000
committerJonathan Wakely <jwakely@redhat.com>2021-11-01 13:26:29 +0000
commit91bac9fed5d082f0b180834110ebc0f46f97599a (patch)
treefee69d3a9ffe1e3a6252ea0e4e09132e8b068883 /libstdc++-v3/include/std/valarray
parentbc5baac5c37d8da1931043c4bbeffa3ab93a8e91 (diff)
downloadgcc-91bac9fed5d082f0b180834110ebc0f46f97599a.zip
gcc-91bac9fed5d082f0b180834110ebc0f46f97599a.tar.gz
gcc-91bac9fed5d082f0b180834110ebc0f46f97599a.tar.bz2
libstdc++: Fix range access for empty std::valarray [PR103022]
The std::begin and std::end overloads for std::valarray are defined in terms of std::addressof(v[0]) which is undefined for an empty valarray. libstdc++-v3/ChangeLog: PR libstdc++/103022 * include/std/valarray (begin, end): Do not dereference an empty valarray. Add noexcept and [[nodiscard]]. * testsuite/26_numerics/valarray/range_access.cc: Check empty valarray. Check iterator properties. Run as well as compiling. * testsuite/26_numerics/valarray/range_access2.cc: Likewise. * testsuite/26_numerics/valarray/103022.cc: New test.
Diffstat (limited to 'libstdc++-v3/include/std/valarray')
-rw-r--r--libstdc++-v3/include/std/valarray30
1 files changed, 22 insertions, 8 deletions
diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray
index 5adc942..c6242eb 100644
--- a/libstdc++-v3/include/std/valarray
+++ b/libstdc++-v3/include/std/valarray
@@ -1210,9 +1210,10 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
* @param __va valarray.
*/
template<class _Tp>
+ [[__nodiscard__]]
inline _Tp*
- begin(valarray<_Tp>& __va)
- { return std::__addressof(__va[0]); }
+ begin(valarray<_Tp>& __va) noexcept
+ { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
/**
* @brief Return an iterator pointing to the first element of
@@ -1220,9 +1221,10 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
* @param __va valarray.
*/
template<class _Tp>
+ [[__nodiscard__]]
inline const _Tp*
- begin(const valarray<_Tp>& __va)
- { return std::__addressof(__va[0]); }
+ begin(const valarray<_Tp>& __va) noexcept
+ { return __va.size() ? std::__addressof(__va[0]) : nullptr; }
/**
* @brief Return an iterator pointing to one past the last element of
@@ -1230,9 +1232,15 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
* @param __va valarray.
*/
template<class _Tp>
+ [[__nodiscard__]]
inline _Tp*
- end(valarray<_Tp>& __va)
- { return std::__addressof(__va[0]) + __va.size(); }
+ end(valarray<_Tp>& __va) noexcept
+ {
+ if (auto __n = __va.size())
+ return std::__addressof(__va[0]) + __n;
+ else
+ return nullptr;
+ }
/**
* @brief Return an iterator pointing to one past the last element of
@@ -1240,9 +1248,15 @@ _DEFINE_BINARY_OPERATOR(>=, __greater_equal)
* @param __va valarray.
*/
template<class _Tp>
+ [[__nodiscard__]]
inline const _Tp*
- end(const valarray<_Tp>& __va)
- { return std::__addressof(__va[0]) + __va.size(); }
+ end(const valarray<_Tp>& __va) noexcept
+ {
+ if (auto __n = __va.size())
+ return std::__addressof(__va[0]) + __n;
+ else
+ return nullptr;
+ }
#endif // C++11
/// @} group numeric_arrays