Clang report "constexpr if condition is not a constant expression" while GCC is ok

Viewed 605

I'm using clang 9.0.1 and gcc 9.2.1 on x64 Linux, both with --std=c++17 (or --std=c++2a).

Gcc can build the following example without any error or warning, while clang++ reports error: constexpr if condition is not a constant expression on both if constexpr lines. (btw, on my MacBook, Apple clang-11.0.0 reports the same error too.)

MCVE:

#include <utility>

enum class TopicType {
    MarketData = 'M',
    Timer = 'T',
};

template<class Topic>
struct TopicBase {
    constexpr static TopicType type() { return Topic::type; };
    const Topic& topicImp;
    explicit TopicBase(const Topic &t) : topicImp(t) {}
};

struct MarketDataTopic {
    static constexpr TopicType type{TopicType::MarketData};
};

struct TimerTopic {
    static constexpr TopicType type{TopicType::Timer};
};

template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {

    if constexpr (topic.type() == TopicType::MarketData) { // <-- clang++ reports error here
        return 1;
    }
    if constexpr (topic.type() == TopicType::Timer) { // and error here
        return 2;
    }

    return -1;
}

int main(int argc, const char **argv) {

    MarketDataTopic m{};
    TimerTopic t{};

    TopicBase<MarketDataTopic> b1{m};
    TopicBase<TimerTopic> b2{t};

    subscribe(std::move(b1));


    return 0;
}

Online compiler https://godbolt.org/z/rARi_N has the same result.

So which compiler is right about this? And if it is an error, how to fix it for clang?

1 Answers

Well you can do this to make it work for clang:

template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {
    using myType = TopicBase<Topic>;
    if constexpr (myType::type() == TopicType::MarketData) { // <-- clang++ reports error here
        return 1;
    }
    if constexpr (myType::type() == TopicType::Timer) { // and error here
        return 2;
    }

    return -1;
}

Run live

Most probably that's a bug in clang. Better report it.

Related