https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99117
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #5) > int* p = sum._M_data; > int* e1 = sum._M_data; > > If p and e1 aren't __restrict__ too, shouldn't that be fine? p (called __p below) doesn't use __restrict__: template<typename _Tp, class _Dom> void __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) { _Tp* __p (__a._M_data); for (size_t __i = 0; __i < __n; ++__i, ++__p) *__p = __e[__i]; } Here __e is the expression template which has two const valarray<int>& members, so maybe more accurately it's: struct valarray { int* __restrict__ _M_data; size_t _M_size; }; valarray sum{ new int[2]{1,1}, 2 }; valarray rhs{ new int[2]{2,2}, 2 }; int* p = sum._M_data; const valarray& e1 = sum; const valarray& e2 = rhs; for (size_t i = 0; i < sum._M_size; ++i, ++p) *p = e1._M_data[i] + e2._M_data[i]; So e1._M_data is marked with __restrict__.