[cfe-dev] question about function with linkage type AvailableExternallyLinkage

Akira Hatanaka ahatanak at gmail.com
Wed Feb 2 14:28:44 PST 2011


I am getting linkage errors when I try to compile foo1.c:

$: clang foo1.c -o foo1 -O3
/tmp/cc-VXVfGf.o:(.data+0x0): undefined reference to `f1'
/tmp/cc-VXVfGf.o:(.data+0x4): undefined reference to `f2'
clang: error: linker command failed with exit code 1 (use -v to see
invocation)

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".

Is this a bug?

// foo1.c
#include <stdlib.h>

typedef int (*ftype)(int);

inline int f1(int x) {
  return x * 3;
}

inline int f2(int x) {
  return x * 4;
}

ftype farray[] = {f1, f2};

int main(int argc, char** argv) {
  int sum = 0, i;

  for (i = 0; i < 2; ++i)
    sum += (*farray[i])(atoi(argv[1]));

  return sum;
}

// foo1.ll
; ModuleID = 'foo1.c'
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"
target triple = "i386-pc-linux-gnu"

@farray = global [2 x i32 (i32)*] [i32 (i32)* @f1, i32 (i32)* @f2], align 4

define available_externally i32 @f1(i32 %x) nounwind readnone inlinehint {
entry:
  %mul = mul i32 %x, 3
  ret i32 %mul
}

define available_externally i32 @f2(i32 %x) nounwind readnone inlinehint {
entry:
  %mul = shl i32 %x, 2
  ret i32 %mul
}

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
entry:
  %arrayidx4 = getelementptr inbounds i8** %argv, i32 1
  %tmp2 = load i32 (i32)** getelementptr inbounds ([2 x i32 (i32)*]*
@farray, i32 0, i32 0), align 4, !tbaa !0
  %tmp5 = load i8** %arrayidx4, align 4, !tbaa !0
  %call.i = tail call i32 @strtol(i8* nocapture %tmp5, i8** null, i32 10)
nounwind
  %call6 = tail call i32 %tmp2(i32 %call.i) nounwind
  %tmp2.1 = load i32 (i32)** getelementptr inbounds ([2 x i32 (i32)*]*
@farray, i32 0, i32 1), align 4, !tbaa !0
  %tmp5.1 = load i8** %arrayidx4, align 4, !tbaa !0
  %call.i.1 = tail call i32 @strtol(i8* nocapture %tmp5.1, i8** null, i32
10) nounwind
  %call6.1 = tail call i32 %tmp2.1(i32 %call.i.1) nounwind
  %add.1 = add i32 %call6.1, %call6
  ret i32 %add.1
}

declare i32 @strtol(i8*, i8** nocapture, i32) nounwind

!0 = metadata !{metadata !"any pointer", metadata !1}
!1 = metadata !{metadata !"omnipotent char", metadata !2}
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110202/fd1d0318/attachment.html>


More information about the cfe-dev mailing list