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"に到達しない事が判明(でいいのか?)。