[Bug libstdc++/104874] New: Non-compile test in string_vector_iterators.cc test fails for the wrong reason.

2022-03-10 Thread brooks at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104874

Bug ID: 104874
   Summary: Non-compile test in string_vector_iterators.cc test
fails for the wrong reason.
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: brooks at gcc dot gnu.org
  Target Milestone: ---

The testsuite/24_iterators/random_access/string_vector_iterators.cc test
contains the following code blob, in every version since the test originated
with the initial libstdc++ checkin in April 2000, through to current HEAD:

 569 #ifdef ITER24_F8
 570std::vector v(1);
 571std::vector::reference r(v.begin()[0]);
 572r = 1;   // cannot assign through reference to
const
 573failures++;
 574 #endif

This code actually fails to compile on the first line because the template
parameter of a std::container object cannot be const.

This indicates a stronger problem with these non-compile tests, which is that
they're not actually testing what we think they're testing.  (As far as I can
tell, they're not checked at all, and so should either be deleted or replaced
with proper dejagnu non-compile tests.)

[Bug libstdc++/104218] New: 23_containers/vector/ext_pointer/types tests rely on GCC overload-resolution bug

2022-01-24 Thread brooks at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104218

Bug ID: 104218
   Summary: 23_containers/vector/ext_pointer/types tests rely on
GCC overload-resolution bug
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: brooks at gcc dot gnu.org
  Target Milestone: ---

In cleaning up some old internal bugs, I came across this one from years ago
when I was running the 4.9.4 libstdc++ testsuite through Clang, and it looks
like it's still relevant.

The 23_containers/vector/ext_pointer/types/{1,2}.cc programs compile
successfully with GCC, of course, but with Clang we get "use of overloaded
operator '-' is ambiguous" errors in std::vector >.

This reduced testcase shows the difference in the two compilers' behavior:


  template struct X {
template void operator-(const X&);
  };
  template void operator-(T, T);

  void f(X x) { x - x; }


Compiler explorer link: https://godbolt.org/z/nnb98W5nW

Richard Smith believes this is a GCC bug, not a Clang bug, per this analysis:
> GCC appears to believe the member function is more specialized, and calls it.
> Clang and I think that's wrong: deduction fails in both directions in partial
> ordering, so the call is ambiguous.
>
> Indeed, C++ DR 532 gives a very similar example. Following its rule, the above
> would be equivalent to:
>
>  template struct X {};
>  template void operator-(X &, const X&);
>  template void operator-(T, T);
>
>  void f(X x) { x - x; }
>
> ... which GCC and Clang agree is ambiguous. So: this test is relying on a GCC
> bug.


[Bug libstdc++/101542] New: __gnu_cxx::sequence_buffer const copy constructor is badly broken

2021-07-20 Thread brooks at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101542

Bug ID: 101542
   Summary: __gnu_cxx::sequence_buffer const copy constructor is
badly broken
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: brooks at gcc dot gnu.org
  Target Milestone: ---

This problem showed up when we were running the GCC 4.9.4 testsuite with the
latest Clang trunk as the compiler, and found that the ext/rope/4.cc test
started failing -- producing "wibblewibble" when it should produce "wibble".

However, the problem is broader than that, and affects much more current GCC
versions as well -- as can be seen at https://godbolt.org/z/74W78rdWP. 
Compiling the following program with Clang trunk produces "hellohello" as
output:

#include 
#include 

template T make_copy(const T &x) { return x; }

int main() {
std::string s;
__gnu_cxx::sequence_buffer a(s);
{
__gnu_cxx::sequence_buffer b = a;
b.push_back('h');
b.push_back('e');
b.push_back('l');
b.push_back('l');
b.push_back('o');

// Making a copy causes sequence_buffer to break.
make_copy(b);
}
std::cout << s;
}


This started failing with a recent Clang change
(https://github.com/llvm/llvm-project/commit/7d2d5a3a6d7aaa40468c30250bf6b0938ef02c08),
described as "Apply P1825 as Defect Report from C++11 up to C++20".  See
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1825r0.html for the
defect report details.  I would guess that GCC will be applying a similar
change.

My colleagues Jorge Gorbe and Richard Smith did a lot of digging on this, and
Richard explains the problem as follows:


The problem with sequence_buffer is that the sequence_buffer(const
sequence_buffer&) copy constructor copies the pending characters in the buffer
to the new copy, and when both are destroyed, they get flushed to the
underlying sequence twice.

But sequence_buffer is more broken than that: it also has another constructor,
sequence_buffer(sequence_buffer&) that has different semantics: it flushes the
source first. So if you only ever use non-const sequence_buffer objects, never
modify a copied-from object, and never do anything that would call the
sequence_buffer(const sequence_buffer&) constructor, it will appear to work.
And that's what this test was relying on.

Part of the consequence of the Clang change is that in code like this:

sequence_buffer f(sequence_buffer x) {
  return x;
}

... the return statement unconditionally behaves like return
(sequence_buffer&&)x;. And that means that we now choose the
sequence_buffer(const sequence_buffer&) constructor, not the
sequence_buffer(sequence_buffer&) constructor, because a non-const lvalue
reference can't bind to an rvalue.  Ultimately, I think that happens at line
342 of stl_algobase.h ("return __result"), here:
https://gcc.gnu.org/git?p=gcc.git;a=blame;f=libstdc%2B%2B-v3/include/bits/stl_algobase.h;hb=9b61c47826156fe17fd5f4306470ade01e2fc4dc#l238.

So: this libstdc++ code is broken, and the test really should never have
passed.


In our case, we're simply xfailing the test since we don't have any code that
uses __gnu_cxx::sequence_buffer or __gnu_cxx::rope, but I'm passing this bug
report along in hopes that it's useful to the libstdc++ maintainers.  :)