2017-06-01 80 views
1

我正在爲大學項目構建編譯器而我正在使用llvm。爲什麼我的編譯器生成的llvm IR是segfaulting

我已經產生了這種IR的最小程序:

; ModuleID = 'Main' 
source_filename = "Main.java" 

%A = type { i16 } 
%Main = type { i16 } 

@progvtable = constant [1 x <{ i16, i8*, i8* }>] [<{ i16, i8*, i8* }> <{ i16 0, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @1, i64 0, i64 0), i8* bitcast (i64 (%A*)* @getX to i8*) }>], align 8 
@0 = constant [8 x i8] c"%lld %c\00", align 8 
@1 = constant [5 x i8] c"getX\00", align 8 

declare i32 @strcmp(i8*, i8*) 

define i8* @vlookup(i16 %type, i8* %funcname) { 
vlookup: 
    %i = alloca i64, align 8 
    %finalres = alloca i8*, align 8 
    store i64 0, i64* %i, align 8 
    store i8* null, i8** %finalres, align 8 
    br i1 true, label %loop, label %endloop 

loop:            ; preds = %loop, %vlookup 
    %0 = load i64, i64* %i, align 8 
    %1 = getelementptr inbounds [1 x <{ i16, i8*, i8* }>], [1 x <{ i16, i8*, i8* }>]* @progvtable, i64 0, i64 %0 
    %2 = getelementptr <{ i16, i8*, i8* }>, <{ i16, i8*, i8* }>* %1, i32 0, i32 0 
    %3 = load i16, i16* %2, align 8 
    %4 = getelementptr <{ i16, i8*, i8* }>, <{ i16, i8*, i8* }>* %1, i32 0, i32 1 
    %5 = load i8*, i8** %4, align 8 
    %6 = getelementptr <{ i16, i8*, i8* }>, <{ i16, i8*, i8* }>* %1, i32 0, i32 2 
    %7 = load i8*, i8** %6, align 8 
    store i8* %7, i8** %finalres, align 8 
    %8 = icmp eq i16 %3, %type 
    %9 = call i32 @strcmp(i8* %5, i8* %funcname) 
    %10 = icmp eq i32 %9, 0 
    %11 = and i1 %10, %8 
    %12 = add i64 %0, 1 
    store i64 %12, i64* %i, align 8 
    br i1 %11, label %loop, label %endloop 

endloop:           ; preds = %loop, %vlookup 
    %13 = load i8*, i8** %finalres, align 8 
    ret i8* %13 
} 

declare i32 @printf(i8*, ...) 

declare i8* @GC_malloc(i64) 

define %A* @A_init() { 
A_init: 
    %0 = call i8* @GC_malloc(i64 2) 
    %this = bitcast i8* %0 to %A* 
    %1 = getelementptr inbounds %A, %A* %this, i32 0, i32 0 
    store i16 0, i16* %1, align 8 
    ret %A* %this 
} 

define i64 @getX(%A* %this) { 
getX: 
    ret i64 1 
} 

define %Main* @Main_init() { 
Main_init: 
    %0 = call i8* @GC_malloc(i64 2) 
    %this = bitcast i8* %0 to %Main* 
    %1 = getelementptr inbounds %Main, %Main* %this, i32 0, i32 0 
    store i16 5, i16* %1, align 8 
    ret %Main* %this 
} 

define void @main(i8**) { 
main: 
    %1 = alloca i8**, align 8 
    store i8** %0, i8*** %1, align 8 
    %args = load i8**, i8*** %1, align 8 
    %2 = alloca %A*, align 8 
    %3 = call %A* @A_init() 
    store %A* %3, %A** %2, align 8 
    %e = load %A*, %A** %2, align 8 
    %4 = getelementptr inbounds %A, %A* %e, i32 0, i32 0 
    %5 = load i16, i16* %4, align 8 
    %6 = call i8* @vlookup(i16 %5, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @1, i64 0, i64 0)) 
    %7 = bitcast i8* %6 to i64 (%A*)* 
    %8 = call i64 %7(%A* %e) 
    %9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @0, i64 0, i64 0), i64 %8, i8 10) 
    ret void 
} 

目前,這是未經優化的輸出,但是這不是問題,我llc上面,然後我用gcc鏈接libgc.so然後我運行應用程序它段錯誤。

使用gdb我驗證了segfaults發生在strcmp的調用中,lldb顯示其中一個參數爲null。

我仔細看了一下IR,我沒有看到它的任何問題,但它segfaults,爲什麼發生這種情況?

備案@progvtable是我用virtual tables表示支持我要實現的語言中的多態性。

我使用llvm 4和gcc 7.1.1,我的操作系統是Arch Linux x64。

回答

0

我傻,這個問題是很瑣碎的xD都能在這裏找到:

br i1 %11, label %loop, label %endloop 

該指令的問題是條件操作數是打破循環無法繼續了,一切都需要的是切換label %looplabel %endloop的地方。