Consider the following OpenCL testcase:
$ cat -n test.cl
1
2 inline void bar()
3 {
4 }
5
6 void __kernel foo()
7 {
8 bar();
9 }
Compilation command:
$ clang -x cl -cl-std=CL3.0 -cl-opt-disable -S -emit-llvm test.cl
Since the definition of bar( ) doesn’t have the extern keyword, its linkage type is available_externally. With optimizations disabled (-cl-opt-disable), the Clang frontend is not inlining the call to bar( ) on line 8 — this seems like the correct behaviour — but it is also deleting the definition of bar( ) because of its linkage type. Consequently, we end up with a call to a function whose definition is missing. Isn’t this incorrect?
In clang/lib/CodeGen/CodeGenModule.cpp, we have this code in the function CodeGenModule::shouldEmitFunction:
bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage)
return true;
const auto *F = cast(GD.getDecl());
if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr())
return false;
Shouldn’t the last line be “return true;”?