Bug 55924 - [C++11] Not all copy-assignment operator forms are correctly detected
Summary: [C++11] Not all copy-assignment operator forms are correctly detected
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2013-01-09 18:27 UTC by Daniel Krügler
Modified: 2013-01-09 19:04 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.7.2, 4.8.0
Last reconfirmed: 2013-01-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Krügler 2013-01-09 18:27:33 UTC
The following code, compiled with 

-Wall -std=c++11 -pedantic

is rejected by gcc 4.7.2 and gcc 4.8.0 20130106 (experimental):

//----------------
struct mine
{
  mine& operator=(mine rhs) { return *this; }
  mine& operator=(mine&& rhs) noexcept { return *this; }
};

int main()
{
  mine a;
  mine b;
  a = b;
}
//----------------

"In function 'int main()':|
12|error: use of deleted function 'constexpr mine::mine(const mine&)'|
1|note: 'constexpr mine::mine(const mine&)' is implicitly declared as deleted because 'mine' declares a move constructor or move assignment operator|
3|error:   initializing argument 1 of 'mine& mine::operator=(mine)'|
"

According to 12.8 p17:

"A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&."

and p18:

"If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy
assignment operator is defined as deleted;"

Therefore class mine provides a user-declared copy-assignment operator, but gcc doesn't recognize that.

This code should be accepted.

I reduced the severity, because this kind of code is expected to be a rather unusual edge-case. Every other form of the copy-assignment operator using references is correctly detected.
Comment 1 Daniel Krügler 2013-01-09 18:32:26 UTC
Remark: The noexcept specifier was added unintentionally and is not relevant to reproduce the described problem.
Comment 2 Jonathan Wakely 2013-01-09 18:39:46 UTC
Clang thinks you need to add 

  mine() = default;
  mine(const mine&) = default;

for the code to be accepted and I agree, otherwise the operator=(mine) assignment operator calls the copy constructor which is deleted because of a user-declared move assignment operator.
Comment 3 Jonathan Wakely 2013-01-09 18:42:30 UTC
Oops, I didn't meant to change this to NEW, sorry
Comment 4 Daniel Krügler 2013-01-09 18:43:52 UTC
Oops I failed to read the error description correctly. The compiler is correct, so please declare this as INVALID. Sorry for the noise.
Comment 5 Jonathan Wakely 2013-01-09 19:04:13 UTC
.