https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108458

            Bug ID: 108458
           Summary: Incorrect detection of constexpr heap usage in
                    non-constexpr context
           Product: gcc
           Version: 12.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ajscimone at live dot com
  Target Milestone: ---

I am currently seeing errors around compile time context evaluation of various
C++ structures. This happens on both gcc trunk and gcc 12.2 on the C++20 and
C++23 standards. The following code should give a thorough example:


#include <vector>

[[nodiscard]] constexpr std::vector<std::vector<int>> constexpr_get_data() {
    return std::vector<std::vector<int>>{{1, 2}, {3, 4}};
}

[[nodiscard]] consteval std::vector<std::vector<int>> consteval_get_data() {
    return std::vector<std::vector<int>>{{1, 2}, {3, 4}};
}

[[nodiscard]] constexpr auto get_val(
    const std::vector<std::vector<int>> list_of_lists) {
    return list_of_lists.data()[0];
}

static_assert(std::vector<int>{1, 2} == get_val(std::vector<std::vector<int>>{
                                            {1, 2}, {3, 4}}));  // Failing
static_assert(std::vector<int>{1, 2} ==
              get_val(consteval_get_data()));  // Failing
static_assert(std::vector<int>{1, 2} ==
              get_val(constexpr_get_data()));  // Working

For Reference: https://godbolt.org/z/bxjThY5WE

For each of these failed structures, gcc errors that these are non-constant
expressions. The compiler seems to believe that there are heap allocated values
that are escaping compile time. This is clearly not the case, as all execution
is happening in the context of a `static_assert()`.  This code behaves as
expected in a compile time context on both the clang and circle compilers. This
also does not happen with a non-nested vector. The following example with a
consteval function allocating a vector at compile time compiles and passes:

#include <vector>

[[nodiscard]] constexpr auto get_val(const std::vector<int> list) {
        return list.data()[0];
}

static_assert(1 == get_val(std::vector<int>{1, 2})); //Working

Reply via email to