public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "raffael at casagrande dot ch" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/112307] New: Segmentation fault with -O1 -fcode-hoisting Date: Tue, 31 Oct 2023 09:39:15 +0000 [thread overview] Message-ID: <bug-112307-4@http.gcc.gnu.org/bugzilla/> (raw) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112307 Bug ID: 112307 Summary: Segmentation fault with -O1 -fcode-hoisting Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: raffael at casagrande dot ch Target Milestone: --- *Affected Versions*: 10.0 - current (14.0.0 20231031). Earlier versions cannot compile the code because it uses c++20. *System*: Linux *Command Line*: g++ main.cc -std=c++20 -O1 -fcode-hoisting *Compiler Output*: <source>:48:87: warning: friend declaration 'bool operator==(const EnumeratorRange<ENUMERATOR>::Sentinel&, const EnumeratorRange<ENUMERATOR>::Iterator&)' declares a non-template function [-Wnon-template-friend] 48 | friend auto operator==(const Sentinel& /*unused*/, const Iterator& i) noexcept -> bool; | ^~~~ <source>:48:87: note: (if this is not what you intended, make sure the function template has already been declared and add '<>' after the function name here) *Runtime Output*: Segmentation fault, "boundary" is printed many times. *Source File*: #include <ranges> #include <iostream> #include <optional> #include <cassert> template <class ENUMERATOR> class EnumeratorRange { public: struct Sentinel { Sentinel() noexcept = default; Sentinel(const Sentinel&) noexcept = default; Sentinel(Sentinel&&) noexcept = default; auto operator=(const Sentinel&) noexcept -> Sentinel& = default; auto operator=(Sentinel&&) noexcept -> Sentinel& = default; ~Sentinel() noexcept = default; }; class Iterator { public: using value_type = typename ENUMERATOR::value_type; using difference_type = std::ptrdiff_t; explicit Iterator(EnumeratorRange* range) : range_(range) {} Iterator() noexcept = default; Iterator(const Iterator&) = delete; Iterator(Iterator&&) noexcept = default; ~Iterator() noexcept = default; auto operator=(const Iterator&) = delete; auto operator=(Iterator&&) noexcept -> Iterator& = default; auto operator*() const noexcept { assert(!range_->end_reached_); return *range_->enumerator_; } auto operator++() noexcept -> Iterator& { assert(!range_->end_reached_); range_->end_reached_ = !range_->enumerator_.Next(); return *this; } auto operator++(int) noexcept -> void { ++*this; } private: EnumeratorRange* range_; friend auto operator==(const Sentinel& /*unused*/, const Iterator& i) noexcept -> bool; }; explicit EnumeratorRange(ENUMERATOR&& e) : enumerator_(std::move(e)), end_reached_(!enumerator_.Next()) {} auto begin() const noexcept { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) return Iterator(const_cast<EnumeratorRange*>(this)); } auto end() const noexcept { return Sentinel(); } private: ENUMERATOR enumerator_; bool end_reached_; friend auto operator==(const Sentinel&, const Iterator& i) noexcept -> bool { return i.range_->end_reached_; } friend auto operator==(const Iterator& i, const Sentinel& s) noexcept -> bool { return s == i; } friend auto operator!=(const Sentinel& s, const Iterator& i) noexcept -> bool { return !(s == i); } friend auto operator!=(const Iterator& i, const Sentinel& s) noexcept -> bool { return !(s == i); } }; class Intersection { public: auto Boundary() const noexcept -> bool { return is_boundary_; } private: bool is_boundary_ = true; }; class CompositeMesh { public: auto Intersections() const noexcept -> std::ranges::input_range auto; }; auto CompositeMesh::Intersections() const noexcept -> std::ranges::input_range auto { class Enumerator { public: using wrapped_range_t = decltype(std::views::single(Intersection())); explicit Enumerator(wrapped_range_t&& range) : range_(std::move(range)), begin_{} {} using value_type = Intersection; auto operator*() const noexcept -> value_type { return *begin_.value(); } auto Next() noexcept -> bool { if (!begin_.has_value()) { auto b = range_.begin(); bool result = (b != range_.end()); begin_ = std::move(b); return result; } else { auto& b = *begin_; if ((*b).Boundary()) { std::cout << "boundary" << std::endl; } ++b; return b != range_.end(); } } private: wrapped_range_t range_; std::optional<std::ranges::iterator_t<wrapped_range_t>> begin_; }; return EnumeratorRange(Enumerator(std::views::single(Intersection()))); } int main() { auto mesh = CompositeMesh(); decltype(auto) intersections = mesh.Intersections(); for (auto intersection : intersections) { } } *Additional Notes* - It works if we use `-O2` (which includes -fcode-hoisting) - Godbolt: https://godbolt.org/z/1PqTKz33Y - One can disable the following compiler options from `-O1` and still reproduce the bug: -fno-auto-inc-dec -fno-branch-count-reg -fno-combine-stack-adjustments -fno-compare-elim -fno-cprop-registers -fno-dce -fno-defer-pop -fno-delayed-branch -fno-dse -fno-forward-propagate -fno-if-conversion -fno-if-conversion2 -fno-inline-functions-called-once -fno-ipa-modref -fno-ipa-profile -fno-ipa-pure-const -fno-ipa-reference -fno-ipa-reference-addressable -fno-merge-constants -fno-move-loop-invariants -fno-move-loop-stores -fno-omit-frame-pointer -fno-reorder-blocks -fno-shrink-wrap -fno-shrink-wrap-separate -fno-split-wide-types -fno-ssa-backprop -fno-ssa-phiopt -fno-tree-bit-ccp -fno-tree-ccp -fno-tree-ch -fno-tree-coalesce-vars -fno-tree-copy-prop -fno-tree-dce -fno-tree-dominator-opts -fno-tree-phiprop -fno-tree-scev-cprop -fno-tree-sink -fno-tree-slsr -fno-tree-sra -fno-tree-ter -fno-unit-at-a-time
next reply other threads:[~2023-10-31 9:39 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-10-31 9:39 raffael at casagrande dot ch [this message] 2023-10-31 9:51 ` [Bug tree-optimization/112307] " rguenth at gcc dot gnu.org 2023-10-31 10:21 ` rguenth at gcc dot gnu.org 2023-10-31 10:43 ` rguenth at gcc dot gnu.org 2024-03-05 11:34 ` rguenth at gcc dot gnu.org 2024-03-05 15:05 ` redi at gcc dot gnu.org 2024-03-05 15:37 ` rguenth at gcc dot gnu.org 2024-03-08 12:58 ` raffael at casagrande dot ch 2024-03-08 14:30 ` redi at gcc dot gnu.org 2024-03-08 14:32 ` redi at gcc dot gnu.org 2024-03-08 15:12 ` raffael at casagrande dot ch
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-112307-4@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).