Code in CodeGenModule::SetFunctionAttributes() can set an empty attribute implicit-section-name on a function that is affected by #pragma clang text="section". This is incorrect because the attribute should contain a valid section name. If the function additionally also uses __attribute__((section("section"))) then this results in emitting the function in a section with an empty name.
Example:
$ cat repr.c #pragma clang section text=".text_pragma" void f(void) __attribute__((section(".text_attr"))); void f(void) {} $ clang -target arm-none-eabi -march=armv7-a -c repr.c $ llvm-objdump -h repr.o repr.o: file format ELF32-arm-little Sections: Idx Name Size Address Type 0 00000000 0000000000000000 1 .strtab 0000005d 0000000000000000 2 .text 00000000 0000000000000000 TEXT 3 00000004 0000000000000000 TEXT 4 .ARM.exidx 00000008 0000000000000000 5 .rel.ARM.exidx 00000008 0000000000000000 6 .comment 000000b2 0000000000000000 7 .note.GNU-stack 00000000 0000000000000000 8 .ARM.attributes 0000003a 0000000000000000 9 .symtab 00000050 0000000000000000
Section with index 3 contains the code for function f(). The name of the section should be .text_attr but is instead empty.
The following happens in this example:
- CodeGenModule::EmitGlobalFunctionDefinition() is called to emit IR for f(). It invokes GetAddrOfFunction() -> GetOrCreateLLVMFunction() -> SetFunctionAttributes(). The last method notices that the FunctionDecl has the PragmaClangTextSectionAttr attribute and wrongly sets empty implicit-section-name attribute on the resulting llvm::Function.
- EmitGlobalFunctionDefinition() calls setNonAliasAttributes() which normally also sets the implicit-section-name attribute but because the Decl has SectionAttr it gets skipped.
The patch fixes the issue by removing the problematic code that sets empty implicit-section-name from CodeGenModule::SetFunctionAttributes(). The idea is that it is sufficient to set this attribute only from setNonAliasAttributes() when a function is emitted.
Isn't it possible for the test to fail if the Arm target is not configured?