Skip to content

Temporary std::string in template argument is not considert a constant expression in C++20 mode #62462

@bebuch

Description

@bebuch

This is a bug in clang++. I tested with libc++ and libstdc++ which both give similar error messages.

#include <algorithm>
#include <string>

template <std::size_t N>
struct ct_to_rt_string {
    consteval ct_to_rt_string(std::string const str) {
        std::copy_n(str.c_str(), N + 1, buffer);
    }

    char buffer[N + 1];
};

constexpr std::string make_ct_std_string() {
    return "compile time text";
}

#include <iostream>

int main() {
    std::cout << ct_to_rt_string<make_ct_std_string().size()>(make_ct_std_string()).buffer;
}

GCC 12.2 compiles this code and prints compile time text as expected.

clang++ -std=c++20 -stdlib=libc++ fails to compile with:

<source>:20:34: error: non-type template argument is not a constant expression
    std::cout << ct_to_rt_string<make_ct_std_string().size()>(make_ct_std_string()).buffer;
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-16.0.0/bin/../include/c++/v1/__memory/allocator.h:113:38: note: allocation performed here was not deallocated
            return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
                                     ^
1 error generated.
ASM generation compiler returned: 1
<source>:20:34: error: non-type template argument is not a constant expression
    std::cout << ct_to_rt_string<make_ct_std_string().size()>(make_ct_std_string()).buffer;
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/clang-16.0.0/bin/../include/c++/v1/__memory/allocator.h:113:38: note: allocation performed here was not deallocated
            return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
                                     ^
1 error generated.

Clang++ does accept the code if you change the call to: (Found by Paul Sanders at Stackoverflow)

int main() {
    constexpr size_t N = make_ct_std_string().size();
    std::cout << ct_to_rt_string<N>(make_ct_std_string()).buffer;
}

I tested with LLVM 16.0.0:

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions