public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/99460] New: [C++20] Template with complex non-type argument re-uses different specialisation
@ 2021-03-08 10:27 gcc.mexon at spamgourmet dot com
  2021-03-08 11:00 ` [Bug c++/99460] " redi at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: gcc.mexon at spamgourmet dot com @ 2021-03-08 10:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99460

            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: ---

See below example of a Builder class.  It is templated with an array of two
booleans, and includes member functions that return an instance of a different
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 with
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 interfering
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=c++2a
builder.cpp".

More discussion and examples [on
StackOverflow](https://stackoverflow.com/questions/66520012/c-20-stdarray-as-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 <array>
#include <cassert>

using Flags = std::array<bool, 2>;

template<Flags flags = Flags{}>
class Builder
{
public:
    Builder() {
    }

    auto SetFirst() {
        constexpr auto new_flags = SetFieldFlag<0>();
        Builder<new_flags> new_builder;
        return new_builder;
    }

    auto SetSecond() {
        constexpr auto new_flags = SetFieldFlag<1>();
        Builder<new_flags> new_builder;
        return new_builder;
    }

    Flags GetFlags() const {
        return flags;
    }

private:
    template<int field>
    static constexpr auto SetFieldFlag() {
        auto new_flags = flags;
        std::get<field>(new_flags) = true;
        return new_flags;
    }
};

int main()
{
    auto flags1 = Builder().SetFirst().SetSecond().GetFlags();
    assert(flags1[0]);
    assert(flags1[1]);

    auto flags2 = Builder().SetSecond().SetFirst().GetFlags();
    assert(flags2[0]);
    assert(flags2[1]);

    return 0;
}

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-08-23 21:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-08 10:27 [Bug c++/99460] New: [C++20] Template with complex non-type argument re-uses different specialisation gcc.mexon at spamgourmet dot com
2021-03-08 11:00 ` [Bug c++/99460] " redi at gcc dot gnu.org
2021-03-08 13:05 ` gcc.mexon at spamgourmet dot com
2021-03-08 22:09 ` gcc.mexon at spamgourmet dot com
2021-08-23 21:02 ` pinskia at gcc dot gnu.org

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).