http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38607
sumamb <sumamb at yahoo dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |sumamb at yahoo dot com --- Comment #16 from sumamb <sumamb at yahoo dot com> 2012-06-20 11:25:30 UTC --- This is a compiler problem. This issue is not generated due to the apar IZ24688. The g++ code is as below. #include #include using namespace std; template class MyClass { public: typedef Key KeyType; MyClass(KeyType aNumber) { cout << aNumber << "! = " << factorial(aNumber) << endl; } ~MyClass(){} private: long factorial(KeyType __x); long factorialHelper(KeyType __x); }; template long MyClass::factorial (KeyType __x) { if (__x <= 0) return 1; else return __x * factorial(__x-1); //else return __x * factorialHelper(__x-1); } template long MyClass:: factorialHelper(KeyType __x) { return factorial(__x); } void foo() { MyClass myClass(5); } Compile with: g++ -save-temps -shared -Wl,-G -o libshare.so share.cc The error received will be: ld: 0711-768 WARNING: Object share.o, section 1, function .MyClass::factorial(int): The branch at address 0x36c is not followed by a recognized no-op or TOC-reload instruction. The unrecognized instruction is 0x7C691B78. Here is an explanation from the problem we see with a below example. .csect .foo[PR] .x: code for x... .globl .x .z: nop .y: code for y... .globl .y .csect .bar[PR] ... bl .y The "bl .y" and ".y:" are in different csects, so the "bl" requires an RLD. Note that the "bl .y" could also be written as: bl .z + 4 or as bl .foo[PR] + (.y - .x) The generated code would look the same, but the corresponding RLDs might refer to different symbols. That is, "bl .y" would have an RLD referring to .y, "bl .z+4" would have an RLD referring to .z, and "bl .foo[PR] + (.y-.x)" would have an RLD referring to .foo[PR]. In the g++ example above, the -G linker flag causes glink code to be used for all function calls to exported symobls. These calls need to be followed by a TOC reload instruction. If .y were not exported, no warning would occur. There are a few possible compiler fixes: 1) Use ".lglobl .y" instead of ".globl .y" This will keep .y from being exported. 2) Add another label at the same address and use .lglobl with the label. (The assembler could do this, but it would change the behavior of the program, because .y would no longer be superceded by the runtime linker. .y: .globl .y .y_local: .lglobl .y_local ... bl .y_local Since .y_local cannot be exported, no nop instruction is needed after "bl". Finally, it is possible for the compiler source code to be: .csect .foo[PR] ... .y: ... .csect .bar[PR] ... bl .y In this case, .y is not in the output symbol table at all, so the RLD must refer to the csect .foo[PR]. If this symbol is global and exported, a warning will still be seen for the missing nop. Regardless, if branch overflow occurs, this particular branch might not be able to be fixed up.