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

            Bug ID: 123931
           Summary: [reflection] bogus "is not a constant expression
                    error" with reflect_constant_array
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mpolacek at gcc dot gnu.org
  Target Milestone: ---

Thanks to Barry Revzin for the test.

```
#include <meta>
#include <vector>

struct Interpolation { char const* fmt; int index; int count; };

struct Information {
    size_t num_interpolations;
    char const* const* strings;
    Interpolation const* interpolations;
};


template <Information Info, class... Args>
auto highlight_print_impl(Args&&... args) -> void {
    // doesn't matter
}

consteval auto into_interpolation_info(std::string_view sv) -> std::meta::info
{
    auto it = sv.begin();
    std::vector<char const*> strings;
    std::vector<Interpolation> interpolations;
    int index = 0;
    while (true) {
        auto next = [&]{
            auto cur = it;
            for (; cur != sv.end(); ++cur) {
                if (*cur == '{') {
                    break;
                }
            }
            return cur;
        }();

        strings.push_back(std::define_static_string(std::string_view(it,
next)));
        if (next == sv.end()) {
            break;
        }

        // interpolation starting at next
        it = next + 1;
        int count = 1;
        int braces = 1;
        while (true) {
            if (*it == '}') {
                --braces;
                if (braces == 0) {
                    break;
                }
            } else if (*it == '{') {
                ++braces;
                ++count;
            }
            ++it;
        }

        ++it;

        interpolations.push_back({
            .fmt = std::define_static_string(std::string_view(next, it)),
            .index=index,
            .count=count
        });

        index += count;
    }

    auto info = Information{
        .num_interpolations = interpolations.size(),
        .strings = std::define_static_array(strings).data(),
        .interpolations = std::define_static_array(interpolations).data(),
    };    

    return std::meta::reflect_constant(info);
}

constexpr auto r = into_interpolation_info("x={} and y={:*^{}} and z={}!\n");

consteval auto highlight_format_string(std::string_view s) -> int {
    [[maybe_unused]] auto impl = into_interpolation_info(s);
    return 0;
}

auto main() -> int {
    [[maybe_unused]] auto s = highlight_format_string("x={} and y={:*^{}} and
z={}!\n");
}
```

results in

.../x86_64-pc-linux-gnu/libstdc++-v3/include/meta:624:50: error: ‘const
Interpolation [3]{Interpolation(), Interpolation(), Interpolation()}’ is not a
constant expression
  624 |       auto __array = meta::reflect_constant_array(__r);
      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~

but this should compile.

Reply via email to