diff --git a/mfbt/PodOperations.h b/mfbt/PodOperations.h index c53572972ff9..f57a9019db86 100644 --- a/mfbt/PodOperations.h +++ b/mfbt/PodOperations.h @@ -116,7 +116,16 @@ static MOZ_ALWAYS_INLINE void PodCopy(T* aDst, const T* aSrc, size_t aNElem) { } #endif + // GCC false-positive: value range propagation cannot prove mLength is bounded + // when Vector::convertToHeapStorage inlines through here (Bug 661957). +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif memcpy(aDst, aSrc, aNElem * sizeof(T)); +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif } template diff --git a/mfbt/Vector.h b/mfbt/Vector.h index 7be85736fa6d..a20705a3158c 100644 --- a/mfbt/Vector.h +++ b/mfbt/Vector.h @@ -20,6 +20,7 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/MemoryReporting.h" #include "mozilla/OperatorNewExtensions.h" +#include "mozilla/PodOperations.h" #include "mozilla/ReentrancyGuard.h" #include "mozilla/Span.h" @@ -271,16 +272,13 @@ struct VectorImpl { template static inline void copyConstruct(T* aDst, const U* aSrcStart, const U* aSrcEnd) { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(aDst, aSrcStart, sizeof(T) * (aSrcEnd - aSrcStart)); - */ MOZ_ASSERT(aSrcStart <= aSrcEnd); - for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { - new_(aDst, *p); + if constexpr (std::is_same_v) { + PodCopy(aDst, aSrcStart, PointerRangeSize(aSrcStart, aSrcEnd)); + } else { + for (const U* p = aSrcStart; p < aSrcEnd; ++p, ++aDst) { + new_(aDst, *p); + } } }