Skip to content

clang seems to be overzealous with lifetime errors in constexpr #53494

@TobiSchluter

Description

@TobiSchluter

Consider this (derived from the Eigen library, tested with clang 13.0.0 and clang 12)

struct B;

#define CONSTEXPR constexpr
#define CONSTEVAL consteval

struct A {
public:
    CONSTEXPR A() { m_val = 1; }
    CONSTEXPR A(const A& other) { m_val = other.m_val;}
    CONSTEXPR ~A() {};

    CONSTEXPR int val() { return m_val; }

    int m_val;

    CONSTEXPR B operator<<(int);
};

struct B {
    A& m_a;
    CONSTEXPR B(A& ref) : m_a(ref) {}
    CONSTEXPR B& operator,(int i) { m_a.m_val = i; return *this; }
    CONSTEXPR ~B() { finished(); }
    CONSTEXPR A finished() { return m_a; }
};

CONSTEXPR B A::operator<<(int i) {
    m_val = i;
    return B(*this);
}

CONSTEVAL int f()
{
    A a{(A() << 1, 2, 3, 4).finished()};
    return a.val();
}

int g()
{
    return f();
}

Godbolt link here: https://godbolt.org/z/njfxf9jP5

As you can see in GCC's intermediate output (obtained by disabling constexpr via macros), ~B is always called before ~A. Nevertheless, clang prints

source>:44:12: error: call to consteval function 'f' is not a constant expression
    return f();
           ^
<source>:13:43: note: read of object outside its lifetime is not allowed in a constant expression
    CONSTEXPR A(const A& other) { m_val = other.m_val;}
                                          ^
<source>:28:37: note: in call to 'A(A())'
    CONSTEXPR A finished() { return m_a; }
                                    ^
<source>:27:22: note: in call to '&A() << 1->finished()'
    CONSTEXPR ~B() { finished(); }
                     ^
<source>:38:10: note: in call to '&A() << 1->~B()'
    A a{(A() << 1, 2, 3, 4).finished()};
         ^
<source>:44:12: note: in call to 'f()'
    return f();
           ^

(I think clang is wrong here, but of course gcc may be getting the destruction order wrong.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang: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