https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87665

            Bug ID: 87665
           Summary: gcc HEAD (svn: 265340) breaks elements on resize
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: linux at obiwahn dot org
  Target Milestone: ---

» cat test.cpp 
#include <iostream>
#include <cstdlib>
#include <vector>
#include <memory>
#include <functional>

int main()
{
  using my_pair = std::pair<std::unique_ptr<int>, double*>;
  std::vector<my_pair> vec;

  for (int i = 0; i < 17; ++i) {
    std::unique_ptr<int> p(new int(i));
    vec.emplace_back(std::move(p), nullptr);
    std::cerr << "capacity: " << vec.capacity() << " size: " << vec.size() <<
std::endl;
    for (size_t i = 0, count = vec.size(); i < count; ++i) {
      std::cerr << " " << i << "-" << (vec[i].first == nullptr ? "fail" :
"ok");
    }
    std::cerr << std::endl;
  }
}

» g++-head test.cpp -O3 -Wall -Wshadow -std=c++14 && ./a.out 
test.cpp: In function ‘int main()’:
test.cpp:16:17: warning: declaration of ‘i’ shadows a previous local [-Wshadow]
   16 |     for (size_t i = 0, count = vec.size(); i < count; ++i) {
      |                 ^
test.cpp:12:12: note: shadowed declaration is here
   12 |   for (int i = 0; i < 17; ++i) {
      |            ^
capacity: 1 size: 1
 0-ok
capacity: 2 size: 2
 0-ok 1-ok
capacity: 4 size: 3
 0-ok 1-ok 2-ok
capacity: 4 size: 4
 0-ok 1-ok 2-ok 3-ok
capacity: 8 size: 5
 0-fail 1-fail 2-fail 3-fail 4-ok
capacity: 8 size: 6
 0-fail 1-fail 2-fail 3-fail 4-ok 5-ok
capacity: 8 size: 7
 0-fail 1-fail 2-fail 3-fail 4-ok 5-ok 6-ok
capacity: 8 size: 8
 0-fail 1-fail 2-fail 3-fail 4-ok 5-ok 6-ok 7-ok
capacity: 16 size: 9
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok
capacity: 16 size: 10
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok
capacity: 16 size: 11
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok 10-ok
capacity: 16 size: 12
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok 10-ok 11-ok
capacity: 16 size: 13
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok 10-ok 11-ok
12-ok
capacity: 16 size: 14
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok 10-ok 11-ok
12-ok 13-ok
capacity: 16 size: 15
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok 10-ok 11-ok
12-ok 13-ok 14-ok
capacity: 16 size: 16
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-ok 9-ok 10-ok 11-ok
12-ok 13-ok 14-ok 15-ok
capacity: 32 size: 17
 0-fail 1-fail 2-fail 3-fail 4-fail 5-fail 6-fail 7-fail 8-fail 9-fail 10-fail
11-fail 12-fail 13-fail 14-fail 15-fail 16-ok

The code compiles and works fine with recent clang. If the shadowed variable is
changed to something else or the double* member is replaced by something else
the code works as expected.

The behavior was originally found by Vasiliy Nabatchikov on gcc 8.2 using
`typedef std::function<uint32_t(uint32_t)> f_t; typedef
std::pair<std::unique_ptr<int>, f_t*> term_iterator_t1` as pair type.

gcc was build with `--disable-multilib` and custom suffix and prefix on Debian
stable and sid.

Reply via email to