opt -predsimplify

  • predsimplify(Predicate Simplifier)を指定したら静的解析ツール的な事ができないか、と思ったので実験。


sample.cpp

#include
#include

int *nonfail_malloc() {
    int *p = (int *)malloc(sizeof(int));
    if(p == 0) {
        exit(0);
    }
    return p;
}

int foo(int *r, int *s) {
    int *p = (int *)malloc(sizeof(int));
    int *q = (int *)nonfail_malloc();
    if(p == 0) {
        puts("p error");
    }
    if(q == 0) {
        puts("q error"); // ここは到達しないはず
    }
    *p = 10;
    *q = 10;
    return *p + *q;
}

command line
(なぜかoptを2回かけないと駄目だった)

llvm-gcc -O0 -S -emit-llvm sample.cpp -o sample.ll
llvm-as sample.ll -o sample.bc -f
opt -std-compile-opts -predsimplify sample.bc -o sample2.bc -f
opt -std-compile-opts -predsimplify sample2.bc -o sample3.bc -f
llvm-dis sample3.bc -o sample-after.ll -f

sample-after.ll

; ModuleID = 'sample3.bc'
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"
target triple = "i386-pc-linux-gnu"
@.str = internal constant [8 x i8] c"p error\00"		; <[8 x i8]*> [#uses=1]

define i32* @_Z14nonfail_mallocv() nounwind {
entry:
	%0 = malloc i32		;  [#uses=2]
	%1 = icmp eq i32* %0, null		;  [#uses=1]
.....

上記で、"p error"という文字列は残っているが、"q error"は残っていない → "q error"に到達しない事が判明(でいいのか?)。