Template matching question

Hello,
there is an interesting (for me) problem with luabind that you might be
able to answer.

Considering the template:

template< typename T >
void deduce( T (*)(), ... ) {}

template< typename T >
void deduce( T f, SomeType g ) {}

...more overloads...

and the function:

void foo() {
   throw some();
}

deduce( foo );

clang 3.2 seems to add an implicit attribute "noreturn" (I assume that
is because clang detected the function will never return). This
attribute seems to rule out the given first overload of function
template "deduce", which would otherwise be responsible to match the
given function's signature and consequently fails on the second
overload. Is that legal? Or maybe the mismatch is caused by another reason?

Kind regards,
Michael

Could you provide a standalone example of the problem? And include a log showing the file contents, the compiler version, the full command used to compile the source as well as all the output (error messages, etc)?

My attempts to reproduce this with ToT Clang seem to have failed - something similar to what you described compiles without error.

This:

struct SomeType {};
template void deduce(T (*)(), …) {}

template void deduce(T f, SomeType g) {}
void foo() { throw SomeType(); }

void bar() { deduce( foo ); }

… works fine on Clang 3.2 and on Clang trunk.

Hrmmm,
thank you very much for verifying, and many excuses for the bother then. The error must be elsewhere then. Do you get a “noreturn” attribute decoration for the type of the function pointer btw?

Just for the context, the error message given that I try to reason about (I don’t have clang myself) is

In file included from ../test/test_exception_handlers.cpp:7:
In file included from ../luabind/luabind.hpp:27:
In file included from ../luabind/class.hpp:89:
../luabind/function.hpp:28:43: error: no matching function for call to 'deduce_signature'
          object fn = make_function(L, f, deduce_signature(f), policies);
                                          ^~~~~~~~~~~~~~~~
../luabind/function.hpp:48:13: note: in instantiation of member function 'luabind::detail::function_registration<void (*)() __attribute__((noreturn)), luabind::detail::null_type>::register_' requested here
        new detail::function_registration<F, Policies>(name, f, policies)));
            ^
../luabind/function.hpp:54:12: note: in instantiation of function template specialization 'luabind::def<void (*)() __attribute__((noreturn)), luabind::detail::null_type>' requested here
    return def(name, f, detail::null_type());
           ^
../test/test_exception_handlers.cpp:50:9: note: in instantiation of function template specialization 'luabind::def<void (*)() __attribute__((noreturn))>' requested here
        def("raise", &raise_my_exception),
        ^
../luabind/detail/deduce_signature.hpp:47:5: note: candidate template ignored: disabled by 'enable_if' [with F = void (*)() __attribute__((noreturn))]
    is_function<F>,
    ^
../luabind/detail/deduce_signature.hpp:60:1: note: candidate function template not viable: requires 2 arguments, but 1 was provided
deduce_signature(F, Wrapped*)

>>>>>>>>>>>>>>>>>>>>>>

I hope you don’t see garbage due to html there.
The “deduce_signature” function indicated there has exactly the same signature as the one I gave in my OP-sample and the F-Type is a pointer to void-function which always throws. It should normally match, but apparently on clang 3.2 (in that very specific environment) it doesn’t. That attribute((noreturn)) looked suspicious to me, but maybe it’s something with the is_function template. I will investigate further, what might go wrong there.

Thank you again!

Michael

Hrmmm,
thank you very much for verifying, and many excuses for the bother then.
The error must be elsewhere then. Do you get a "noreturn" attribute
decoration for the type of the function pointer btw?

No. We don't deduce a 'noreturn' attribute from the function definition,
and I don't think we ever did. If you're seeing one somewhere, I expect
your code is adding it itself.

Just for the context, the error message given that I try to reason about
(I don't have clang myself) is

>>>>>>>>>>>>>>>>>>>>>

In file included from ../test/test_exception_handlers.cpp:7:
In file included from ../luabind/luabind.hpp:27:
In file included from ../luabind/class.hpp:89:
../luabind/function.hpp:28:43: error: no matching function for call to 'deduce_signature'
          object fn = make_function(L, f, deduce_signature(f), policies);
                                          ^~~~~~~~~~~~~~~~
../luabind/function.hpp:48:13: note: in instantiation of member function 'luabind::detail::function_registration<void (*)() __attribute__((noreturn)), luabind::detail::null_type>::register_' requested here
        new detail::function_registration<F, Policies>(name, f, policies)));
            ^
../luabind/function.hpp:54:12: note: in instantiation of function template specialization 'luabind::def<void (*)() __attribute__((noreturn)), luabind::detail::null_type>' requested here
    return def(name, f, detail::null_type());
           ^
../test/test_exception_handlers.cpp:50:9: note: in instantiation of function template specialization 'luabind::def<void (*)() __attribute__((noreturn))>' requested here
        def("raise", &raise_my_exception),

Can you show us the declaration (preferably after preprocessing) of

raise_my_exception? (Also maybe of luabind::def.)

Hello,

No. We don't deduce a 'noreturn' attribute from the function
definition, and I don't think we ever did. If you're seeing one
somewhere, I expect your code is adding it itself.

Thank you! Would such attributes (implicit or explicit) affect overload
resolution and argument deduction like qualifiers do? Anyways, since
there is absolutely no __attribute__((noreturn)) in all of the library
that is reported broken, this issue must have a reason that I should not
bother you with any further. I just came here because it seemed
"possible" that clang did some automatic code annotations and I wondered
whether that could be the issue.

Michael