http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49609

           Summary: No code emitted for address-taken instances of
                    function templates
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: sr...@srcf.ucam.org


In the following code

template <typename From, typename To>
inline
void *
value_convert_function(From *from, To *to)
{
    return 0;
}

void *(*my_table[])(void *, void *) = {
    reinterpret_cast<void*(*)(void*,void*)>(&(value_convert_function<double,
double>)),
    0
};    

void *(*my_function_ptr)(void*, void *)
 = reinterpret_cast<void*(*)(void*,void*)>(&(value_convert_function<float,
float>));

void *(*my_uncast_function_ptr)(bool *, bool *)
 = &(value_convert_function<bool, bool>);


... I expect to see code output for each of the three template instances that I
take the address of. But only the last one is actually generated. 

$ objdump -t test.o | c++filt

test.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 test.cc
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .text._Z22value_convert_functionIbbEPvPT_PT0_ 
0000000000000000 .text._Z22value_convert_functionIbbEPvPT_PT0_
0000000000000000 l    d  .note.GNU-stack        0000000000000000
.note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000 l    d  .group 0000000000000000 .group
0000000000000000 g     O .data  0000000000000010 my_table
0000000000000000         *UND*  0000000000000000 void*
value_convert_function<double, double>(double*, double*)
0000000000000010 g     O .data  0000000000000008 my_function_ptr
0000000000000000         *UND*  0000000000000000 void*
value_convert_function<float, float>(float*, float*)
0000000000000018 g     O .data  0000000000000008 my_uncast_function_ptr
0000000000000000  w    F .text._Z22value_convert_functionIbbEPvPT_PT0_ 
0000000000000013 void* value_convert_function<bool, bool>(bool*, bool*)


I notice that in g++ 4.4, the code for the first two is rejected with a clearly
bogus error ("address of overloaded function with no contextual type
information").  In 4.5.1 and later, it is accepted but yields an undefined
symbol (causing link errors in my actual use-case). This also happens in the
latest sources I've tried, which are a fairly recent subversion checkout:

$ g++ --version | head -n1
g++  (GCC) 4.7.0 20110417 (experimental)

One attempted workaround was to type my table entries as void *, insert no cast
and compile with -fpermissive (to get the implicit conversion to void*). But
that reverts to the 4.4-style bogus error, even in later versions:

void *my_voidptr_table[] = { &value_convert_function<char, char>, 0 };

test.cc:20: error: cannot resolve overloaded function ‘value_convert_function’
based on conversion to type ‘void*’

My workaround for now is to separately instantiate everything I want to put in
the table, by defining a bunch of static function pointers. 

Thanks for reading!

Reply via email to