Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

17 Regression: over optimization at -O2 #123347

Open
NewSigma opened this issue Jan 17, 2025 · 2 comments
Open

17 Regression: over optimization at -O2 #123347

NewSigma opened this issue Jan 17, 2025 · 2 comments

Comments

@NewSigma
Copy link

godbolt: https://godbolt.org/z/4xEEz6fsY

#include <iostream>
#include <coroutine>
#include <utility>
#include <vector>

struct Promise {
    std::vector<int> obj;

    ~Promise() {
        std::cout << "~Promise: " << obj.data() << std::endl;
    }

    auto get_return_object() { return std::coroutine_handle<Promise>::from_promise(*this); };
    std::suspend_never initial_suspend() noexcept { return {}; }
    std::suspend_never final_suspend() noexcept { return {}; }
    std::suspend_always yield_value(std::vector<int> b) noexcept {
        obj = std::move(b);
        return {};
    }
    void return_void() noexcept {}
    void unhandled_exception() {}
};

struct coro {
    using promise_type = Promise;

    std::vector<int> arr;
    std::coroutine_handle<Promise> handle;

    coro(std::coroutine_handle<Promise> handle_) noexcept {
        handle = handle_;
        arr = std::move(handle_.promise().obj);
    }
};

coro fn() {
    co_yield std::vector<int>(1);
}

int main(int argc, char** argv) {
    coro cr = fn();
    std::cout << "main: " << cr.arr.data() << std::endl;
    cr.handle.resume();
    return 0;
}

The code works fine using clang 16, but it breaks using 17 ~ trunk.

Possible wrong result(-O2):
main: 0x61c7ada362f0
~Promise: 0x61c7ada362f0

Expected result(-O0):
main: 0x61c7ada362f0
~Promise: 0

@llvmbot
Copy link
Member

llvmbot commented Jan 17, 2025

@llvm/issue-subscribers-coroutines

Author: None (NewSigma)

godbolt: https://godbolt.org/z/4xEEz6fsY
#include &lt;iostream&gt;
#include &lt;coroutine&gt;
#include &lt;utility&gt;
#include &lt;vector&gt;

struct Promise {
    std::vector&lt;int&gt; obj;

    ~Promise() {
        std::cout &lt;&lt; "~Promise: " &lt;&lt; obj.data() &lt;&lt; std::endl;
    }

    auto get_return_object() { return std::coroutine_handle&lt;Promise&gt;::from_promise(*this); };
    std::suspend_never initial_suspend() noexcept { return {}; }
    std::suspend_never final_suspend() noexcept { return {}; }
    std::suspend_always yield_value(std::vector&lt;int&gt; b) noexcept {
        obj = std::move(b);
        return {};
    }
    void return_void() noexcept {}
    void unhandled_exception() {}
};

struct coro {
    using promise_type = Promise;

    std::vector&lt;int&gt; arr;
    std::coroutine_handle&lt;Promise&gt; handle;

    coro(std::coroutine_handle&lt;Promise&gt; handle_) noexcept {
        handle = handle_;
        arr = std::move(handle_.promise().obj);
    }
};

coro fn() {
    co_yield std::vector&lt;int&gt;(1);
}

int main(int argc, char** argv) {
    coro cr = fn();
    std::cout &lt;&lt; "main: " &lt;&lt; cr.arr.data() &lt;&lt; std::endl;
    cr.handle.resume();
    return 0;
}

The code works fine using clang 16, but it breaks using 17 ~ trunk.

Possible wrong result(-O2):
main: 0x61c7ada362f0
~Promise: 0x61c7ada362f0

Expected result(-O0):
main: 0x61c7ada362f0
~Promise: 0

@DimitryAndric
Copy link
Collaborator

Only occurs at -O2:

$ valgrind ./pr123347
==781807== Memcheck, a memory error detector
==781807== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==781807== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==781807== Command: ./pr123347
==781807==
main: 0x4e380f0
~Promise: 0x4e380f0
==781807== Invalid free() / delete / delete[] / realloc()
==781807==    at 0x484A61D: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==781807==    by 0x109365: deallocate (new_allocator.h:172)
==781807==    by 0x109365: deallocate (allocator.h:208)
==781807==    by 0x109365: deallocate (alloc_traits.h:513)
==781807==    by 0x109365: _M_deallocate (stl_vector.h:389)
==781807==    by 0x109365: ~_Vector_base (stl_vector.h:368)
==781807==    by 0x109365: ~vector (stl_vector.h:738)
==781807==    by 0x109365: ~coro (???:24)
==781807==    by 0x109365: main (???:45)
==781807==  Address 0x4e380f0 is 0 bytes inside a block of size 4 free'd
==781807==    at 0x484A61D: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==781807==    by 0x1093AC: fn() [clone .resume] (pr123347.cpp:36)
==781807==    by 0x109350: resume (coroutine:242)
==781807==    by 0x109350: main (???:43)
==781807==  Block was alloc'd at
==781807==    at 0x4846FA3: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==781807==    by 0x109236: allocate (new_allocator.h:151)
==781807==    by 0x109236: allocate (allocator.h:196)
==781807==    by 0x109236: allocate (alloc_traits.h:478)
==781807==    by 0x109236: _M_allocate (stl_vector.h:380)
==781807==    by 0x109236: _M_create_storage (stl_vector.h:398)
==781807==    by 0x109236: _Vector_base (stl_vector.h:334)
==781807==    by 0x109236: vector (stl_vector.h:557)
==781807==    by 0x109236: fn() (???:37)
==781807==    by 0x1092D0: main (pr123347.cpp:41)

Looks like gcc doesn't have this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants