[Bug c++/101118] coroutines: unexpected ODR warning for coroutine frame type in LTO builds

2021-06-18 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101118

--- Comment #3 from Nils Gladitz  ---
Thanks for looking into this!

Any idea what the potential implications are?
I assume I can't just ignore the warning as this will likely break code?
When I turn off LTO the diagnostic will go away but the ODR violations are
still there; could they still break something?

[Bug c++/101118] New: coroutines: unexpected ODR warning for coroutine frame type in LTO builds

2021-06-18 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101118

Bug ID: 101118
   Summary: coroutines: unexpected ODR warning for coroutine frame
type in LTO builds
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nilsgladitz at gmail dot com
  Target Milestone: ---

Created attachment 51033
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51033=edit
Testcase source files

The attached sources files are reduced from a C++ project using boost::asio and
coroutines.

I don't fully understand it but compiling them with vanilla GCC 11.1.0 like
this:
g++ -std=c++2a -fPIC -fcoroutines -Wall -flto -fno-fat-lto-objects -shared
foo.cpp bar.cpp

unexpectedly produces the following diagnostic:
boost.hpp:81:3: warning: type ‘struct
_ZN5boost4asio1gIiFviEE2abIiEENS0_9awaitableIiiEET_.frame’ violates the C++ One
Definition Rule [-Wodr]
   81 |   }
  |   ^
boost.hpp:81:3: note: a different type is defined in another translation unit
   81 |   }
  |   ^
boost.hpp:79:34: note: the first difference of corresponding definitions is
field ‘__D.9984.3.4’
   79 |   template  static w ab(k ai) {
  |  ^
boost.hpp:79:34: note: a field with different name is defined in another
translation unit
   79 |   template  static w ab(k ai) {
  |

[Bug c++/100611] coroutines: destructor called too many times for coroutine lambda stored object

2021-05-15 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100611

--- Comment #1 from Nils Gladitz  ---
(In reply to Nils Gladitz from comment #0)
> Indicating that "Foo" is constructed more often than it gets destructed.

Sorry that of course was supposed to read:
 Indicating that "Foo" is destructed more often than it gets constructed.

[Bug c++/99576] [coroutines] destructor of a temporary called too early within co_await expression

2021-05-15 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99576

--- Comment #2 from Nils Gladitz  ---
I opened bug 100611 for what I described above; assuming this is related but
distinct.

[Bug c++/100611] New: coroutines: destructor called too many times for coroutine lambda stored object

2021-05-15 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100611

Bug ID: 100611
   Summary: coroutines: destructor called too many times for
coroutine lambda stored object
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nilsgladitz at gmail dot com
  Target Milestone: ---

Created attachment 50816
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50816=edit
test case

Given the attached test case compiled and run with e.g.
 g++ test.cpp -std=c++20 -fcoroutines && ./a.out

produces the output:
 Foo(23) 0x55c938eb5ed4
 Foo(const& 23) 0x55c938eb5ee4
 ~Foo(23) 0x55c938eb5ee0
 ~Foo(23) 0x55c938eb5ee4
 ~Foo(23) 0x55c938eb5ed4

Indicating that "Foo" is constructed more often than it gets destructed.

This may be a variation of or related to bug 99576 which my test case is based
on.

Bug 99576 seems to be observable in 10.2 while this new issue seems to be
observable in 10.3 and 11.1.

Bisecting the gcc-10 release branch the dividing commit seems to be:
 commit f43a1b1d1718969423337190ddbbbc9037c67783
 Author: Iain Sandoe 
 Date:   Sun Jul 19 18:39:21 2020 +0100

 coroutines: Correct frame capture of compiler temps [PR95591+4].

[Bug c++/99576] [coroutines] destructor of a temporary called too early within co_await expression

2021-05-14 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99576

Nils Gladitz  changed:

   What|Removed |Added

 CC||nilsgladitz at gmail dot com

--- Comment #1 from Nils Gladitz  ---
I am seeing issues with lambdas and coroutines that I can't quite explain yet.
Specifically reference counting objects capture copied (e.g. std::shared_ptr)
seemed to decrease their reference count more often than they should.

Found this issue which didn't quite seem to match but trying Paweł Wegner's
test case I see something that may explain some weirdness (haven't fully
digested the test case or disregarded the possibility that it is my fault
though).

With vanilla gcc 10.2.0 I am seeing what Paweł observed:

START TASK
Foo()
~Foo()
IN LAMBDA

With vanilla 10.3.0 and 11.1.0 I however see the following:

START TASK
Foo()
IN LAMBDA
~Foo()
~Foo()

i.e. the Foo destructor now gets called later but apparently twice

[Bug libstdc++/99846] [11 regression] std::variant comparison operator error for recursive type

2021-04-13 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99846

--- Comment #8 from Nils Gladitz  ---
(In reply to Jonathan Wakely from comment #5)
> Now this is *obviously* wrong. The left < right expression uses the
> operator< defined for the std::list base class, which depends on
> comparing the list's elements, which obviously recurses.

Maybe my original test case was reduced a bit too far.
Recursive but bounded example which maybe is a little closer to the original
case and I hope maybe a little less obviously wrong:

#include 
#include 
#include 

struct Value;

using Array = std::list;
using Variant = std::variant;

struct Value : Variant
{
using Variant::variant;
};

int main()
{
Value left = Array{2, Array{}, 3};
Value right = Array{1};

std::cout << "<\t" << (left < right) << std::endl;
std::cout << ">\t" << (left > right) << std::endl;
std::cout << "==\t" << (left == right) << std::endl;
}

[Bug libstdc++/99846] New: [11 regression] std::variant comparison operator error for recursive type

2021-03-31 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99846

Bug ID: 99846
   Summary: [11 regression] std::variant comparison operator error
for recursive type
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nilsgladitz at gmail dot com
  Target Milestone: ---

Created attachment 50491
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50491=edit
Test case source code

The attached source is a test case I reduced from a JSON like library that uses
std::variant to store alternate value types.

This still builds with GCC 10.2.0 but fails in 11.0.1 (g65374af219f) with:

/opt/gcc/git-snapshot/include/c++/11.0.1/compare: In substitution of
‘template  requires (three_way_comparable<_Types,
std::partial_ordering> && ...) constexpr
std::common_comparison_category_t...> std::operator<=>(const std::variant<_Types ...>&, const
std::variant<_Types ...>&) [with _Types = {std::__cxx11::list >}]’:
/opt/gcc/git-snapshot/include/c++/11.0.1/compare:893:10:   required by
substitution of ‘template constexpr auto
std::__detail::_Synth3way::operator()(const _Tp&, const _Up&) const requires
requires{{std::__detail::_Synth3way::operator()::__t <
std::__detail::_Synth3way::operator()::__u} -> decltype(auto) [requires
std::__detail::__boolean_testable<,
>];{std::__detail::_Synth3way::operator()::__u <
std::__detail::_Synth3way::operator()::__t} -> decltype(auto) [requires
std::__detail::__boolean_testable<, >];} [with _Tp = Value; _Up =
Value]’
/opt/gcc/git-snapshot/include/c++/11.0.1/compare:914:34:   required by
substitution of ‘template using __synth3way_t = decltype
(std::__detail::__synth3way(declval<_Tp&>(), declval<_Up&>())) [with _Tp =
Value; _Up = Value]’
/opt/gcc/git-snapshot/include/c++/11.0.1/bits/stl_list.h:2030:5:   required by
substitution of ‘template
std::__detail::__synth3way_t<_T1> std::operator<=>(const
std::__cxx11::list<_Tp, _Alloc>&, const std::__cxx11::list<_Tp, _Alloc>&) [with
_Tp = Value; _Alloc = std::allocator]’
/opt/gcc/git-snapshot/include/c++/11.0.1/concepts:306:10:   required by
substitution of ‘template  requires
(three_way_comparable<_Types, std::partial_ordering> && ...) constexpr
std::common_comparison_category_t...> std::operator<=>(const std::variant<_Types ...>&, const
std::variant<_Types ...>&) [with _Types = {std::__cxx11::list >}]’
test.cpp:16:16:   required from here
/opt/gcc/git-snapshot/include/c++/11.0.1/variant:1218:5:   required by the
constraints of ‘template  requires
(three_way_comparable<_Types, std::partial_ordering> && ...) constexpr
std::common_comparison_category_t...> std::operator<=>(const std::variant<_Types ...>&, const
std::variant<_Types ...>&)’
cc1plus: error: satisfaction of atomic constraint
‘(three_way_comparable<_Types, std::partial_ordering> && ...) [with _Types =
{_Types ...}]’ depends on itself
/opt/gcc/git-snapshot/include/c++/11.0.1/compare: In substitution of
‘template  requires (three_way_comparable<_Types,
std::partial_ordering> && ...) constexpr
std::common_comparison_category_t...> std::operator<=>(const std::variant<_Types ...>&, const
std::variant<_Types ...>&) [with _Types = {std::__cxx11::list >}]’:
/opt/gcc/git-snapshot/include/c++/11.0.1/compare:894:10:   required by
substitution of ‘template constexpr auto
std::__detail::_Synth3way::operator()(const _Tp&, const _Up&) const requires
requires{{std::__detail::_Synth3way::operator()::__t <
std::__detail::_Synth3way::operator()::__u} -> decltype(auto) [requires
std::__detail::__boolean_testable<,
>];{std::__detail::_Synth3way::operator()::__u <
std::__detail::_Synth3way::operator()::__t} -> decltype(auto) [requires
std::__detail::__boolean_testable<, >];} [with _Tp = Value; _Up =
Value]’
/opt/gcc/git-snapshot/include/c++/11.0.1/compare:914:34:   required by
substitution of ‘template using __synth3way_t = decltype
(std::__detail::__synth3way(declval<_Tp&>(), declval<_Up&>())) [with _Tp =
Value; _Up = Value]’
/opt/gcc/git-snapshot/include/c++/11.0.1/bits/stl_list.h:2030:5:   required by
substitution of ‘template
std::__detail::__synth3way_t<_T1> std::operator<=>(const
std::__cxx11::list<_Tp, _Alloc>&, const std::__cxx11::list<_Tp, _Alloc>&) [with
_Tp = Value; _Alloc = std::allocator]’
/opt/gcc/git-snapshot/include/c++/11.0.1/concepts:306:10:   required by
substitution of ‘template  requires
(three_way_comparable<_Types, std::partial_ordering> && ...) constexpr
std::common_comparison_category_t...> std::operator<=

[Bug c++/99710] New: coroutines: co_yield and co_await should only be allowed in suspension context

2021-03-22 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99710

Bug ID: 99710
   Summary: coroutines: co_yield and co_await should only be
allowed in suspension context
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nilsgladitz at gmail dot com
  Target Milestone: ---

I quite enjoyed seemingly being able to co_await in exception catch handlers
but as I am being told by another compiler this is apparently not legal.

Not sure I really understand why the standard disallows this but perhaps gcc
should issue a corresponding error diagnostic as well.

Equivalent (fixed) issue report I found for clang:
https://bugs.llvm.org/show_bug.cgi?id=40978

[Bug c++/99215] coroutines: debugging with gdb

2021-03-22 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99215

--- Comment #7 from Nils Gladitz  ---
(In reply to Nils Gladitz from comment #5)
> Apparently when the coroutine happens to be a member function (even a static
> one) printing *frame_ptr results in "{}".

I reported the "{}" issue at the gdb issue tracker:
https://sourceware.org/bugzilla/show_bug.cgi?id=27556

Managed to create a local workaround from comments made there.
It was mentioned that gcc itself may be generating improper debug information
(I think specifically nesting the frame type within a function) but as I
mentioned  over there I myself don't know for sure if this is uncommon or
actually invalid.

[Bug c++/98056] ICE tree check: expected record_type or union_type or qual_union_type, have array_type in build_special_member_call, at cp/call.c:9862 since r11-2183-g0f66b8486cea8668

2021-03-06 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98056

--- Comment #4 from Nils Gladitz  ---
Not sure if this is helpful at all but I think I ran into the same issue and
reduced it to the following which is slightly shorter but also keeps the
standard C++ includes intact (manually reintroduced them after reduction):

#include 
#include 

struct a {
  a();
};

struct task {
  struct promise_type {
std::suspend_always initial_suspend();
std::suspend_always final_suspend() noexcept;
void unhandled_exception();
task get_return_object();
  };

  std::suspend_always c(a);

  a bar(std::initializer_list);

 task e() {
co_await c(bar({a{}}));
  }
};

[Bug c++/99215] coroutines: debugging with gdb

2021-02-24 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99215

--- Comment #5 from Nils Gladitz  ---
Apparently when the coroutine happens to be a member function (even a static
one) printing *frame_ptr results in "{}".

Ideally I'd want to have non-static member coroutines and would like to be able
to inspect the "this" pointer during debugging.

I was also wondering if "frame_ptr" as a non-reserved name isn't problematic in
case there happens to be e.g. a local variable with that name.

[Bug c++/99215] coroutines: debugging with gdb

2021-02-23 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99215

--- Comment #4 from Nils Gladitz  ---
(In reply to Iain Sandoe from comment #3)
> ... the essence of the idea [on the mentioned long TODO] is to change the
> way in which frame vars are referenced; instead of changing the uses to
> point to the frame version, change the vars to have a DECL_VALUE_EXPR
> pointing to the frame version.  This is a totally theoretical sketch (no
> experiments done yet).
> 
> Stated in one sentence, that doesn't sound too tricky .. but maintaining the
> state of the coroutine *is* quite tricky (and lambdas already use the
> DECL_VALUE_EXPRs).

Alright, thank you! Just knowing that this is thought of, on a todo list and
currently not completely inaccessible helps build confidence somewhat; I think
for me enough to try some of this in production code. With some luck you still
get through your todo list faster than I get to my next corresponding release
:)

[Bug c++/99215] coroutines: debugging with gdb

2021-02-23 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99215

--- Comment #2 from Nils Gladitz  ---
(In reply to Iain Sandoe from comment #1)
> Can you identify specific key blockers to progress?
> (I think the paper cited contained a number of desiderata, but it would be
> good to start from the most important requirements).

Thank you for the quick reply.

As you and the paper have stated setting breakpoints so far seems to work fine
for me.

What stands out most for me is being unable to inspect parameters (which for
the debugger don't seem to exist) and local variables (their names seem to be
known but their values all show as "").

On second look this seems to be only half true as I seem to be able to inspect
both local variables and parameters via the debugger visible "frame_ptr"
variable.

Not straightforward and names seem to be mangled but that might suffice to get
started to some degree; won't work with gdb frontends though (which I have been
using).

I have no idea of how any of this is actually implemented but I am hoping this
is just a matter of emitting debug information that tells gdb to look for
members and parameters in the corresponding frame_ptr locations?

[Bug c++/99215] New: coroutines: debugging with gdb

2021-02-22 Thread nilsgladitz at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99215

Bug ID: 99215
   Summary: coroutines: debugging with gdb
   Product: gcc
   Version: 10.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: nilsgladitz at gmail dot com
  Target Milestone: ---

I am itching to get into C++20 coroutines (and very grateful for their
implementation) but am somewhat put off by the apparent inability to inspect
them from within a debugger currently.

While looking for existing related GCC specific issues, discussions or commits
(none of which I found) the following paper [Debugging C++ coroutines] did come
up: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2073r0.pdf
This seems to at least confirm the current state that I was seeing.

I can not tell if support for this is missing in GCC or GDB or both but I
figured I'd try finding out here first.
Presumably (hopefully) someone here is at least aware of the issue and might be
able to point out if this is maybe already done (and I am just doing it wrong
or using the wrong GCC version), in the works or on some agenda somewhere.

[Bug libstdc++/86164] std::regex crashes when matching long lines

2018-12-04 Thread nilsgladitz at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164

Nils Gladitz  changed:

   What|Removed |Added

 CC||nilsgladitz at gmail dot com

--- Comment #6 from Nils Gladitz  ---
I think I am hitting this issue somewhat earlier on an ARM system with a more
limited stack size.

Was able to reproduce it on Desktop x86_64 Linux with e.g.:

#include 

int main()
{
std::regex_match(
std::string(2000, 'a'),
std::regex(".*")
);
}

$ ulimit -s 256 # 256kb stack; which is what have by default on the ARM system
$ g++ test.cpp -o regex_test
$ ./regex_test
Segmentation fault (core dumped)