From d43568222a4564e22a6ffd370481e11ba031b318 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Sat, 16 Dec 2017 22:37:22 +0000 Subject: [PATCH] PR tree-optimization/83239 - False positive from -Wstringop-overflow PR tree-optimization/83239 - False positive from -Wstringop-overflow on simple std::vector code libstdc++/CHangeLog: * include/bits/vector.tcc (vector::_M_default_append): Assert invariant to generate better code. gcc/testsuite/ChangeLog: * g++.dg/pr83239.C: New test case. From-SVN: r255753 --- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/pr83239.C | 56 ++++++++++++++++++++++++++++ libstdc++-v3/ChangeLog | 6 +++ libstdc++-v3/include/bits/vector.tcc | 12 ++++-- 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr83239.C diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49c26ac0484..f16a1872230 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-12-16 Martin Sebor + + PR tree-optimization/83239 + * g++.dg/pr83239.C: New test case. + 2017-12-16 Sebastian Peryt PR testsuite/82767 diff --git a/gcc/testsuite/g++.dg/pr83239.C b/gcc/testsuite/g++.dg/pr83239.C new file mode 100644 index 00000000000..b0f31be33f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr83239.C @@ -0,0 +1,56 @@ +// PR tree-optimization/83239 - False positive from -Wstringop-overflow +// on simple std::vector code +// { dg-do compile } +// { dg-options "-O3 -Wall -fdump-tree-optimized" } + +#include + +// Verify no warnings are issued. + +template +void test_loop () +{ + std::vector a; + + int num = 2; + + while (num > 0) + { + const typename std::vector::size_type sz = a.size (); + + if (sz < 3) + a.assign (1, 0); + else + a.resize (sz - 2); + + --num; + } +} + +// Verify no warnings are issued here either. + +template +void test_if (std::vector &a, int num) +{ + if (num > 0) + { + const typename std::vector::size_type sz = a.size (); + + if (sz < 3) + a.assign (1, 0); + else + a.resize (sz - 2); + } +} + +// Instantiate each function on a different type to force both +// to be fully inlined. Instantiating both on the same type +// causes the inlining heuristics to outline _M_default_append +// which, in turn, masks the warning. +template void test_loop(); +template void test_if(std::vector&, int); + +// Verify that std::vector::_M_default_append() has been inlined +// (the absence of warnings depends on it). +// { dg-final { scan-tree-dump-not "_ZNSt6vectorIiSaIiEE17_M_default_appendEm" optimized } } +// { dg-final { scan-tree-dump-not "_ZNSt6vectorIPvSaIS0_EE17_M_default_appendEm" optimized } } diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1b4c6e281e6..1275ea5e85f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2017-12-16 Martin Sebor + + PR tree-optimization/83239 + * include/bits/vector.tcc (vector::_M_default_append): Assert + invariant to generate better code. + 2017-12-14 Jonathan Wakely PR libstdc++/83279 diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index eadce3c75da..595a7f32735 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -582,8 +582,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (__n != 0) { - if (size_type(this->_M_impl._M_end_of_storage - - this->_M_impl._M_finish) >= __n) + size_type __size = size(); + size_type __navail = size_type(this->_M_impl._M_end_of_storage + - this->_M_impl._M_finish); + + if (__size > max_size() || __navail > max_size() - __size) + __builtin_unreachable(); + + if (__navail >= __n) { _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = @@ -595,7 +601,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { const size_type __len = _M_check_len(__n, "vector::_M_default_append"); - const size_type __old_size = this->size(); + const size_type __old_size = __size; pointer __new_start(this->_M_allocate(__len)); pointer __new_finish(__new_start); __try -- 2.30.2