Skip to content

Clang fails to compile consteval because of conflicting rule for variable arrays (?) #105796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
socketpair opened this issue Aug 23, 2024 · 8 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party consteval C++20 consteval diverges-from:gcc Does the clang frontend diverge from gcc on this issue extension:gnu

Comments

@socketpair
Copy link

socketpair commented Aug 23, 2024

https://godbolt.org/z/dKE6sa4PW

#include <algorithm>
#include <array>

template <std::size_t N>
struct CompTimeStr {
    std::array<char, N> store;

    consteval CompTimeStr(const char (&str)[N]) {
        std::copy_n(str, store.size(), store.data());
    }

    template <std::size_t N2>
    consteval CompTimeStr<N + N2 - 1> operator+(
        const CompTimeStr<N2> str) const {
        char newchar[size() + str.size() + 1];
        std::copy_n(data(), size(), newchar);
        std::copy_n(str.data(), str.size() + 1, newchar + size());
        return newchar;
    }

    consteval std::size_t size() const { return store.size() - 1; }
    consteval const char* data() const { return store.data(); }
};

template <CompTimeStr str>
consteval auto addBar() {
    return str + str;
}

int main() {
    constexpr CompTimeStr str = addBar<"foo">();

    return str.size();
}
@github-actions github-actions bot added the clang Clang issues not falling into any other category label Aug 23, 2024
@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Aug 23, 2024

At this time you can write char newchar[N + N2 - 1]; instead, which is shorter.

Slightly reduced example (Godbolt link):

#include <cstddef>
#include <type_traits>

template <std::size_t N>
struct record {
    consteval record(std::integral_constant<std::size_t, N>) {}

    template <std::size_t N2>
    consteval std::size_t test_with(const record<N2> other) const {
        constexpr auto len = size() + other.size() + 1; // HERE
        return len;
    }

    consteval std::size_t size() const { return N - 1; }
};

template <record Foo>
consteval auto test_two_records() {
    return Foo.test_with(Foo);
}

int main() {
    constexpr auto n = test_two_records<std::integral_constant<std::size_t, 42>{}>();
}

I believe this is P2280R4 which is tracked in #63139 and will be fixed by #95474.

@socketpair
Copy link
Author

@frederick-vs-ja Thank you, I already know how to fix. I just reported obvious bug in Clang.

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" consteval C++20 consteval diverges-from:gcc Does the clang frontend diverge from gcc on this issue and removed clang Clang issues not falling into any other category labels Aug 23, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 23, 2024

@llvm/issue-subscribers-clang-frontend

Author: Коренберг Марк (socketpair)

https://godbolt.org/z/dKE6sa4PW
#include &lt;algorithm&gt;
#include &lt;array&gt;

template &lt;std::size_t N&gt;
struct CompTimeStr {
    std::array&lt;char, N&gt; store;

    consteval CompTimeStr(const char (&amp;str)[N]) {
        std::copy_n(str, store.size(), store.data());
    }

    template &lt;std::size_t N2&gt;
    consteval CompTimeStr&lt;N + N2 - 1&gt; operator+(
        const CompTimeStr&lt;N2&gt; str) const {
        char newchar[size() + str.size() + 1];
        std::copy_n(data(), size(), newchar);
        std::copy_n(str.data(), str.size() + 1, newchar + size());
        return newchar;
    }

    consteval std::size_t size() const { return store.size() - 1; }
    consteval const char* data() const { return store.data(); }
};

template &lt;CompTimeStr str&gt;
consteval auto addBar() {
    return str + str;
}

int main() {
    constexpr CompTimeStr str = addBar&lt;"foo"&gt;();

    return str.size();
}

@AaronBallman AaronBallman added extension:gnu confirmed Verified by a second party labels Aug 23, 2024
@AaronBallman
Copy link
Collaborator

Related: #102970

@cor3ntin
Copy link
Contributor

@shafik

@shafik
Copy link
Collaborator

shafik commented Dec 19, 2024

Reduced some more: https://godbolt.org/z/x7P9TjYce

template <typename, unsigned>
struct A{};

template <unsigned N>
struct record {
    consteval record(A<unsigned, N>) {}

    consteval unsigned test_with() const {
        constexpr auto len = size() + 1;
        return len;
    }

    consteval unsigned size() const { return N - 1; }
};

template <record F>
consteval auto test_two_records() {
    return F.test_with();
}

void g() {
    constexpr auto n = test_two_records<A<unsigned, 42>{}>();
}

@shafik
Copy link
Collaborator

shafik commented Dec 19, 2024

I am not sure this is totally unknown refs and ptrs. It looks like we are not seeing up CurrentCall->This and I don't think that is purely part of the that proposal. I think we may be missing another feature here?

@shafik
Copy link
Collaborator

shafik commented Dec 20, 2024

Based on this, I think this is an unrelated bug: https://godbolt.org/z/nMh8Mebqo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party consteval C++20 consteval diverges-from:gcc Does the clang frontend diverge from gcc on this issue extension:gnu
Projects
None yet
Development

No branches or pull requests

7 participants