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

--- Comment #2 from James Panayis <james at jamespanayis dot com> ---
I've found a repro that more closely matches the original issue I had:

struct iterator_state {};

struct buffer {
  char* out;
  void (*grow)(buffer&);
};

struct unbuffered_buffer : buffer {
  void (*write)(iterator_state&, const char&);
  iterator_state& state;
};

int main() {
  char out = 0;
  buffer buf{&out, [](buffer&) {}};
  for (int i = 0; i < 2; ++i) {
    if (!buf.grow) {
      auto& self = static_cast<unbuffered_buffer&>(buf);
      self.write(self.state, 'x');
    } else buf.grow(buf);
    *buf.out = 'x';
  }
  return out != 'x';
}


The first repro writes a derived-only character member; this variant instead
reads derived-only callback/state members and invokes the callback. The derived
access is unreachable in both repros, and both include the tricky
buf.grow(buf).

The original code that surfaced this issue was a branch of the fmt library:
https://github.com/james-panayis/fmt/blob/852c02455d14ab0b5ec1369ad706dbb3858139de/include/fmt/core.h#L1773
.

Interestingly, this new repro emits no warnings on 10.5.0, and does emit the
warning on 11.1.0. But the original repro seems to emit no warning all the way
up to 14.4.0, and then emits from 15.1.0 onwards (though I haven't fully
bisected the compiler versions more finely).

I'm not sure if the difference in behaviour on compiler versions 11.1.0 to
14.4.0 warrants opening a separate bug report, or if this is better as just a
second example on this report.

Reply via email to