namespace /* anonymous */ { [[gnu::section(".mysection")]] void regular_func() { } template <class T> [[gnu::section(".mysection")]] void template_func() { } } // namespace /* anonymous */ void (*ptr1)() = ®ular_func; void (*ptr2)() = &template_func<int>; In the code above the section attribute is given to both of the regular function and the function template, but the templated function is not placed in .mysection but .text. $ g++ -std=c++14 a.cpp -c && objdump -t a.o | grep -E "regular|template" 0000000000000000 l F .mysection 0000000000000007 _ZN12_GLOBAL__N_112regular_funcEv 0000000000000000 l F .text 0000000000000007 _ZN12_GLOBAL__N_113template_funcIiEEvv ~/temp/c++/function_template_section $ I also tried it with clang and clang put the function into .mysection as I expected. $ clang++ -std=c++14 a.cpp -c && objdump -t a.o | grep -E "regular|template" 0000000000000000 l F .mysection 0000000000000006 _ZN12_GLOBAL__N_112regular_funcEv 0000000000000010 l F .mysection 0000000000000006 _ZN12_GLOBAL__N_113template_funcIiEEvv
I am having the same problem with static member variables: #include <sys/types.h> class TestClassRegular { public: static volatile const int32_t regularVar; }; volatile const int32_t TestClassRegular::regularVar __attribute__ ((section(".eepromdata.ints"))) = 0; template <uint32_t size, typename T> class TestClassTemplate { public: static volatile const int32_t templateVar; }; template <uint32_t size, typename T> volatile const int32_t TestClassTemplate<size,T>::templateVar __attribute__ ((section(".eepromdata.ints"))) = 0; int main() { int32_t blah = TestClassRegular::regularVar + TestClassTemplate<10, uint8_t>::templateVar; return blah; } arm-none-eabi-objdump -t stm32l0-Template.elf | grep Var 200000c4 w O .data 00000004 _ZN17TestClassTemplateILm10EhE11templateVarE 08080008 g O .eepromdata 00000004 _ZN16TestClassRegular10regularVarE
Problem is still present in version 6.3.1
Still an issue in gcc 8.2.0.
Confirmed with the top of trunk.
Having similiar issues with ARM Embedded and Linux GCC. Having trouble finding a work around for this. Here is an example code that demonstrates the issue in our particular use case: =============================================================== // g++ -std=c++17 static.cpp -o static.exe // // objdump -t static.exe | grep thing // 0000000000000740 u O .rodata 0000000000000064 _ZZ5test0ILi5EEvvE5thing // // clang -std=c++14 static.cpp -o static.exe // objdump -t static.exe | grep thing // 00000000004005d3 w O .log_entry 0000000000000064 _ZZ5test0ILi5EEvvE5thing #include <cstdio> #if __APPLE__ #define PUT_IN_SECTION(name) __attribute__((section("__text," name), used)) #else #define PUT_IN_SECTION(name) __attribute__((section(name), used)) #endif struct ThingType { constexpr ThingType(const char * str): data{} { for(int i = 0; str[i] != '\0' && i < sizeof(data); i++) { data[i] = str[i]; } } char data[100]; }; template <int dummy_template_parameter = 5> void test0() { PUT_IN_SECTION(".log_entry") static const ThingType thing("Goodbye!"); printf("Hello, World!\n"); } int main() { test0(); return 0; } =============================================================== Comment the test0 template line out, and the entry will appear in the appropriate section.
Related bug 88061 Here's a demonstration of the issue with GCC trunk x86-64 on godbolt: https://godbolt.org/z/9GFWZR Minimal example for reproducing: > template <typename Type> > Type __attribute__( ( used, section( ".my_section" ) ) ) add_types( Type a, Type b ) { > return a + b; > } > > int main( int argc, char * argv[] ) { > return test_class<int>( s_value<3> ).add( add_types( 1, 2 ) ); > } Current behaviour: add_types within section .text Desired behaviour: add_types within section .my_section Clang trunk demonstrates the desired behaviour: https://godbolt.org/z/t8FNe0
I also encountered this bug. I started fixing this bug (and PR 88061): https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00348.html
Bug still present in 11.2.1