LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 38143 - defaulted destructor makes defaulted copy constructor non-constexpr
Summary: defaulted destructor makes defaulted copy constructor non-constexpr
Status: NEW
Alias: None
Product: clang
Classification: Unclassified
Component: C++ (show other bugs)
Version: trunk
Hardware: Macintosh All
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-07-11 18:39 PDT by Marshall Clow (home)
Modified: 2021-11-21 01:50 PST (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marshall Clow (home) 2018-07-11 18:39:52 PDT
Consider this code:

class span {
public:
    using pointer                = const int *;

    constexpr span() : __data{nullptr} {}

    constexpr span           (const span&) noexcept = default;
    constexpr span& operator=(const span&) noexcept = default;
    ~span() noexcept = default;

    constexpr pointer data()    const noexcept { return __data; }

private:
    pointer __data;
};

When compiled with a recent clang [clang version 7.0.0 (trunk 336548)], (-std=c++2a) it gives an error:
junk.cpp:8:5: error: defaulted definition of copy assignment operator is not
      constexpr
    constexpr span& operator=(const span&) noexcept = default;
    ^

However, if I switch the order of the two lines to:
    ~span() noexcept = default;
    constexpr span& operator=(const span&) noexcept = default;

then it compiles w/o error.

However, I believe that it should compile w/o error in *both* cases.
Comment 1 Marcel Ehrhardt 2019-04-30 04:44:14 PDT
duplicate of https://bugs.llvm.org/show_bug.cgi?id=25689 ?
Comment 2 Hyundeok Park 2021-11-21 01:50:12 PST
Still persists in Clang 13 with constexpr constructors.

This issue doesn't appear in GCC 11.2 and Clang 13 with -std=c++17, but it only appears when the flag -std=c++20 is given.

Below is the sample code:

```cpp
struct Foo {
  constexpr Foo(const Foo&) noexcept = default;
  constexpr Foo(Foo&&) noexcept = default;

  constexpr auto operator=(const Foo&) noexcept -> Foo& = default;
  constexpr auto operator=(Foo&&) noexcept -> Foo& = default;
};
```

with the following errors:

```
<source>:5:3: error: defaulted definition of copy assignment operator is not constexpr
  constexpr auto operator=(const Foo&) noexcept -> Foo& = default;
  ^
<source>:6:3: error: defaulted definition of move assignment operator is not constexpr
  constexpr auto operator=(Foo&&) noexcept -> Foo& = default;
  ^
2 errors generated.
Compiler returned: 1
```

Live demo: https://godbolt.org/z/6Mz6K3PMf

As shown above, the warning states that both assignment operators are not constexpr even though they are already declared constexpr, which is contradictory.