Bug 107598 - implicitly-defined copy/move assignment op not constexpr
Summary: implicitly-defined copy/move assignment op not constexpr
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2022-11-09 19:26 UTC by Marek Polacek
Modified: 2022-11-16 14:09 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-11-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marek Polacek 2022-11-09 19:26:01 UTC
The following test is rejected with:

bug1.C: In function ‘constexpr void g()’:
bug1.C:11:7: error: call to non-‘constexpr’ function ‘S& S::operator=(const S&)’
   11 |   b = a;
      |       ^
bug1.C:5:4: note: ‘S& S::operator=(const S&)’ is not usable as a ‘constexpr’ function because:
    5 | S& S::operator=(const S&) = default;
      |    ^

...because what?

I think it should be accepted, at least in C++23, because [class.copy.assign]/10:
"A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) (e.g., when it is selected by overload resolution to assign to an object of its class type), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration.
The implicitly-defined copy/move assignment operator is constexpr."

Here it is explicitly defaulted after its first declaration.


struct S {
  constexpr S() {}
  S& operator=(const S&);
};
S& S::operator=(const S&) = default;

constexpr void
g ()
{
  S a, b;
  b = a;
}
Comment 1 Jason Merrill 2022-11-16 13:27:55 UTC
It's not constexpr because it wasn't declared to be constexpr (or defaulted) in the class body, and "If any declaration of a function or function template has a constexpr or consteval specifier, then all its declarations shall contain the same specifier."  The wording (and the error) could use some clarification.
Comment 2 Marek Polacek 2022-11-16 14:09:21 UTC
Ah, thanks.  Then it's a diagnostic-only PR, we should still explain what the problem is.