Skip to content

[Clang] Placement-new in constant evaluation can give indeterminate result #117294

Open
@frederick-vs-ja

Description

@frederick-vs-ja

The following program shouldn't be accepted per [expr.const]/5.18.2.1 as corrected by CWG2922 (since the constructed array type is unsuitable).

However, Clang currently accepts it and give different results in different compilation. Godbolt link.

#include <new>
#include <typeinfo>

constexpr int N = []
{
    struct S {
        int a[1];
    };
    S s;
    ::new (s.a) int[1][2][3][4]();
    return s.a[0];
}();

template<int X>
struct tag {};

void unknown(const std::type_info&) noexcept;

int main()
{
    unknown(typeid(tag<N>));
}

Moreover, the following seems valid because the array type is suitable, but there are still indeterminate results. Godbolt link.
(The correct N is 0.)

#include <new>
#include <typeinfo>

constexpr int N = []
{
    struct S {
        int a[1];
    };
    S s;
    ::new (s.a) int[1](); // s.a is converted to the poiner to s.a[0]
    return s.a[0];
}();

template<int X>
struct tag {};

void unknown(const std::type_info&) noexcept;

int main()
{
    unknown(typeid(tag<N>));
}

This can be also trigged by the current resolution of LWG3436 (so labeled c++20).

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++20c++26clang:frontendLanguage frontend issues, e.g. anything involving "Sema"confirmedVerified by a second partyconstexprAnything related to constant evaluation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions