I am getting linkage errors when I try to compile foo1.c:<br><br>$: clang foo1.c -o foo1 -O3<br>/tmp/cc-VXVfGf.o:(.data+0x0): undefined reference to `f1'<br>/tmp/cc-VXVfGf.o:(.data+0x4): undefined reference to `f2'<br>
clang: error: linker command failed with exit code 1 (use -v to see invocation)<br><br>I inspected the bitcode foo1.ll, and it seems that definitions of f1 and f2 are not emitted because their linkage types are "available_externally".<br>
<br>Is this a bug?<br><br>// foo1.c<br>#include <stdlib.h><br><br>typedef int (*ftype)(int);<br><br>inline int f1(int x) {<br>  return x * 3;<br>}<br><br>inline int f2(int x) {<br>  return x * 4;<br>}<br><br>ftype farray[] = {f1, f2};<br>
<br>int main(int argc, char** argv) {<br>  int sum = 0, i;<br><br>  for (i = 0; i < 2; ++i)<br>    sum += (*farray[i])(atoi(argv[1]));<br><br>  return sum;<br>}<br><br>// foo1.ll<br>; ModuleID = 'foo1.c'<br>target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"<br>
target triple = "i386-pc-linux-gnu"<br><br>@farray = global [2 x i32 (i32)*] [i32 (i32)* @f1, i32 (i32)* @f2], align 4<br><br>define available_externally i32 @f1(i32 %x) nounwind readnone inlinehint {<br>entry:<br>
  %mul = mul i32 %x, 3<br>  ret i32 %mul<br>}<br><br>define available_externally i32 @f2(i32 %x) nounwind readnone inlinehint {<br>entry:<br>  %mul = shl i32 %x, 2<br>  ret i32 %mul<br>}<br><br>define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {<br>
entry:<br>  %arrayidx4 = getelementptr inbounds i8** %argv, i32 1<br>  %tmp2 = load i32 (i32)** getelementptr inbounds ([2 x i32 (i32)*]* @farray, i32 0, i32 0), align 4, !tbaa !0<br>  %tmp5 = load i8** %arrayidx4, align 4, !tbaa !0<br>
  %call.i = tail call i32 @strtol(i8* nocapture %tmp5, i8** null, i32 10) nounwind<br>  %call6 = tail call i32 %tmp2(i32 %call.i) nounwind<br>  %tmp2.1 = load i32 (i32)** getelementptr inbounds ([2 x i32 (i32)*]* @farray, i32 0, i32 1), align 4, !tbaa !0<br>
  %tmp5.1 = load i8** %arrayidx4, align 4, !tbaa !0<br>  %call.i.1 = tail call i32 @strtol(i8* nocapture %tmp5.1, i8** null, i32 10) nounwind<br>  %call6.1 = tail call i32 %tmp2.1(i32 %call.i.1) nounwind<br>  %add.1 = add i32 %call6.1, %call6<br>
  ret i32 %add.1<br>}<br><br>declare i32 @strtol(i8*, i8** nocapture, i32) nounwind<br><br>!0 = metadata !{metadata !"any pointer", metadata !1}<br>!1 = metadata !{metadata !"omnipotent char", metadata !2}<br>
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}<br>                                                             <br><br>