Skip to content

[Clang] constexpr checking not considering copy elision #116778

Open
@aywala

Description

@aywala
#include <iostream>

struct Elem {
    unsigned short data;
    constexpr Elem(unsigned int a) noexcept : data(static_cast<unsigned short>(a)){};
    Elem(const Elem& elem) : data(elem.data) { std::cout<<"call copy constructor\n"; }; // error with clang -std=c++14, ok with gcc and msvc
    // constexpr Elem(const Elem& elem) : data(elem.data) {}; // ok
};

 constexpr Elem foo() noexcept {
    return Elem{0x0400};
}

int main() {
    Elem e1 = foo();
    std::cout<<e1.data<<std::endl;
}
<source>:10:17: error: constexpr function never produces a constant expression [-Winvalid-constexpr]
   10 |  constexpr Elem foo() noexcept {
      |                 ^~~
<source>:11:12: note: non-constexpr constructor 'Elem' cannot be used in a constant expression
   11 |     return Elem{0x0400};
      |            ^
<source>:6:5: note: declared here
    6 |     Elem(const Elem& elem) : data(elem.data) { std::cout<<"call copy constructor\n"; }; // error with clang -std=c++14, ok with gcc and msvc
      |     ^
1 error generated.

With -std=c++14 flag, Clang performs the copy elision for the return statement in foo(), but still reports error about the copy constructor. I know copy elision is not guaranteed with pre-C++17, but since clang does perform it, there should not be an error.
When C++ standard is not specified, Clang-15 reports an error while higher versions do not.
GCC and MSVC have no problem with this code sample.

https://godbolt.org/z/af5aGzn1a

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++14clang:frontendLanguage frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions