From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 6DB6D3857C7B; Mon, 8 Mar 2021 10:27:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6DB6D3857C7B From: "gcc.mexon at spamgourmet dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/99460] New: [C++20] Template with complex non-type argument re-uses different specialisation Date: Mon, 08 Mar 2021 10:27:51 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: gcc.mexon at spamgourmet dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Mar 2021 10:27:51 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D99460 Bug ID: 99460 Summary: [C++20] Template with complex non-type argument re-uses different specialisation Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gcc.mexon at spamgourmet dot com Target Milestone: --- =EF=BB=BFSee below example of a Builder class. It is templated with an arr= ay of two booleans, and includes member functions that return an instance of a differ= ent specialisation of the same template. However, the different specialisations appear to get mixed up. The intended behaviour is that both usages in main() result in a Builder wi= th both booleans set. In fact the result is that the second usage only has one boolean set. However, removing the first usage resolves the problem, indicating that the problem is caused by unrelated specialisations interfer= ing with each other. I checked this with gcc 9.3.0 and gcc 10.2.0. I also tried compiling from = git, version 11.0.1 change a18ebd6c439. Command line was "g++ -Wall --std=3Dc++= 2a builder.cpp". More discussion and examples [on StackOverflow](https://stackoverflow.com/questions/66520012/c-20-stdarray-a= s-non-type-template-argument-reshuffles-elements/66520217#66520217). It seems likely that this is a known problem, in which case this bug report= can be closed as a duplicate. But I would like a tracking bug to attach to the StackOverflow question. ---- #include #include using Flags =3D std::array; template class Builder { public: Builder() { } auto SetFirst() { constexpr auto new_flags =3D SetFieldFlag<0>(); Builder new_builder; return new_builder; } auto SetSecond() { constexpr auto new_flags =3D SetFieldFlag<1>(); Builder new_builder; return new_builder; } Flags GetFlags() const { return flags; } private: template static constexpr auto SetFieldFlag() { auto new_flags =3D flags; std::get(new_flags) =3D true; return new_flags; } }; int main() { auto flags1 =3D Builder().SetFirst().SetSecond().GetFlags(); assert(flags1[0]); assert(flags1[1]); auto flags2 =3D Builder().SetSecond().SetFirst().GetFlags(); assert(flags2[0]); assert(flags2[1]); return 0; }=