Search code examples
c++clangsfinae

See SFINAE reason for a certain function


I'm using CLang. Is there a way for a certain function or whole .cpp to treat SFINAE as error? If there is an option --sfinae-as-error, or #pragma sfinae_disable/#pragma sfinae_enable for a certain function?

It seems that due to SFINAE my function specialization has disappeared (became unusable) and I don't know how to find the reason why it has failed (where SFINAE comes from), basically I have unintentional SFINAE case and I want to find out the line that causes it.

To explain this, I have a small method:

template <typename To>
auto casttc() const {
    if constexpr(std::is_same_v<To, T>)
        return *this;
    Vec<RTBits, Bits, To> c;
    auto constexpr castt_ = castt_reg_helper<RTGet<To>, RT>::f;
    LOOPM({ GI; c.template reg<I>() = castt_(this->template reg<I>()); });
    return c;
}

From another method I call it like this->template casttc<u64>() and it gives compile error:

drafts/intrin_simd3.hpp:199:10: note: candidate template ignored: substitution failure [with To = unsigned long long]
    auto casttc() const {

Line 199 in above error message points to auto casttc() const {.

There were several screens of error log and these lines are last lines of this log:

In file included from drafts/cordic.cpp:12:
In file included from drafts/intrin_simd3.hpp:157:
drafts/intrin_simd2.hpp:140:61: error: no matching member function for call to 'casttc'
        *this = this->template casttc<T0>().and_(b.template casttc<T0>()).template casttc<T>();
                                                 ~~~~~~~~~~~^~~~~~~~~~
drafts/intrin_simd3.hpp:199:10: note: candidate template ignored: substitution failure [with To = unsigned long long]
    auto casttc() const {

So basically it says that for some reason <u64> specialization of this function can't be used. And I don't know in advance what is causing this problem.

Some time later I managed to find out the problem, which was that castt_reg_helper<RTGet<To>, RT> has no specialization for given template arguments. After I added necessary specialization everything started to compile.

So I'm concerned that CLang didn't give me precise reason of error, it just said that <u64> specialization is unusable without extra reasons. As I understand this specialization was removed (or became unusable) due to SFINAE. So for similar cases I want to be able to see precise reason of failure without compiler silently using SFINAE.

In my case function was not very big and I was able to find error manually. But if the body of a function is huge (I had such case before), finding reason of SFINAE could be problematic and takes a lot of time.


Solution

  • Basically my build system just outputted last screen of errors, it truncated errors to last screen showing on console. Of cause in the beginning of screen it showed tiny message that truncation happened but I didn't noticed that. And when I restored whole log there appeared following lines:

    In file included from drafts/cordic.cpp:12:
    drafts/intrin_simd3.hpp:203:33: error: implicit instantiation of undefined template 'asimd::Vec<256, 512, double>::castt_reg_helper<__attribute__((__vector_size__(4 * sizeof(long long)))) long long, __attribute__((__vector_size__(4 * sizeof(double)))) double>'
            auto constexpr castt_ = castt_reg_helper<RTGet<To>, RT>::f;
                                    ^
    

    which solve my problem. Apparently it appeared that it wasn't SFINAE reason and that CLang actually showed detailed reason but far above in the error log.

    So my question was a mistake not due to bad CLang but due to me not noticing that my build system truncated errors.

    We have a special build system written specifically for our organization and our needs. It is not any well known open source build system.