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

            Bug ID: 113064
           Summary: assignement from temporary sometimes invokes
                    copy-assign instead of move-assign operator
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: m.cencora at gmail dot com
  Target Milestone: ---

Following code fails to compile on any gcc version with any selected language
version. Works with clang.

When invoking the conversion operator the problem does not occur.
Also the mere existence of second overloaded conversion operator is
problematic.
Even though this conversion operator does not participate in overload
resolution due to being && qualified.
I marked it as deleted to show that this is not the overload being chosen by
compiler but just declaring it normally is enough to trigger the bug.

Compilation fails with error:
<source>: In function 'void test()':
<source>:31:10: error: use of deleted function 'no_copy&
no_copy::operator=(const no_copy&)'
   31 |     nc = f;
      |          ^
<source>:9:14: note: declared here
    9 |     no_copy& operator=(const no_copy&) = delete;
      |              ^~~~~~~~
Compiler returned: 1



// test.cpp
struct no_copy
{
    no_copy() = default;

    no_copy(const no_copy&) = delete;
    no_copy(no_copy&&);

    no_copy& operator=(const no_copy&) = delete;
    no_copy& operator=(no_copy&&);
};

struct foo
{
    operator no_copy() &
    {
        return no_copy();
    }

#ifndef WORKAROUND1
    operator no_copy&&() && = delete;
#endif
};

void test()
{
    foo f;
    no_copy nc;

#ifndef WORKAROUND2
    nc = f;
#else
    nc = f.operator bar();
#endif
}

Reply via email to