rustc: Run the verifier over LLVM modules before writing them out
This commit is contained in:
parent
a1c7d19836
commit
3f9d5dab5b
2 changed files with 35 additions and 1 deletions
|
@ -687,6 +687,16 @@ native mod llvm = llvm_lib {
|
||||||
fn LLVMPreferredAlignmentOfType(TargetDataRef TD, TypeRef Ty) -> uint;
|
fn LLVMPreferredAlignmentOfType(TargetDataRef TD, TypeRef Ty) -> uint;
|
||||||
/** Disposes target data. */
|
/** Disposes target data. */
|
||||||
fn LLVMDisposeTargetData(TargetDataRef TD);
|
fn LLVMDisposeTargetData(TargetDataRef TD);
|
||||||
|
|
||||||
|
/** Creates a pass manager. */
|
||||||
|
fn LLVMCreatePassManager() -> PassManagerRef;
|
||||||
|
/** Disposes a pass manager. */
|
||||||
|
fn LLVMDisposePassManager(PassManagerRef PM);
|
||||||
|
/** Runs a pass manager on a module. */
|
||||||
|
fn LLVMRunPassManager(PassManagerRef PM, ModuleRef M) -> Bool;
|
||||||
|
|
||||||
|
/** Adds a verification pass. */
|
||||||
|
fn LLVMAddVerifierPass(PassManagerRef PM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Slightly more terse object-interface to LLVM's 'builder' functions. */
|
/* Slightly more terse object-interface to LLVM's 'builder' functions. */
|
||||||
|
@ -1209,6 +1219,19 @@ fn mk_target_data(str string_rep) -> target_data {
|
||||||
ret rec(lltd=lltd, dtor=target_data_dtor(lltd));
|
ret rec(lltd=lltd, dtor=target_data_dtor(lltd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Memory-managed interface to pass managers. */
|
||||||
|
|
||||||
|
obj pass_manager_dtor(PassManagerRef PM) {
|
||||||
|
drop { llvm.LLVMDisposePassManager(PM); }
|
||||||
|
}
|
||||||
|
|
||||||
|
type pass_manager = rec(PassManagerRef llpm, pass_manager_dtor dtor);
|
||||||
|
|
||||||
|
fn mk_pass_manager() -> pass_manager {
|
||||||
|
auto llpm = llvm.LLVMCreatePassManager();
|
||||||
|
ret rec(llpm=llpm, dtor=pass_manager_dtor(llpm));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
|
@ -23,8 +23,9 @@ import lib.llvm.llvm;
|
||||||
import lib.llvm.builder;
|
import lib.llvm.builder;
|
||||||
import lib.llvm.target_data;
|
import lib.llvm.target_data;
|
||||||
import lib.llvm.type_handle;
|
import lib.llvm.type_handle;
|
||||||
import lib.llvm.mk_type_handle;
|
import lib.llvm.mk_pass_manager;
|
||||||
import lib.llvm.mk_target_data;
|
import lib.llvm.mk_target_data;
|
||||||
|
import lib.llvm.mk_type_handle;
|
||||||
import lib.llvm.llvm.ModuleRef;
|
import lib.llvm.llvm.ModuleRef;
|
||||||
import lib.llvm.llvm.ValueRef;
|
import lib.llvm.llvm.ValueRef;
|
||||||
import lib.llvm.llvm.TypeRef;
|
import lib.llvm.llvm.TypeRef;
|
||||||
|
@ -2245,6 +2246,14 @@ fn declare_intrinsics(ModuleRef llmod) -> hashmap[str,ValueRef] {
|
||||||
ret intrinsics;
|
ret intrinsics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_module(ModuleRef llmod) {
|
||||||
|
auto pm = mk_pass_manager();
|
||||||
|
llvm.LLVMAddVerifierPass(pm.llpm);
|
||||||
|
llvm.LLVMRunPassManager(pm.llpm, llmod);
|
||||||
|
|
||||||
|
// TODO: run the linter here also, once there are llvm-c bindings for it.
|
||||||
|
}
|
||||||
|
|
||||||
fn trans_crate(session.session sess, @ast.crate crate, str output) {
|
fn trans_crate(session.session sess, @ast.crate crate, str output) {
|
||||||
auto llmod =
|
auto llmod =
|
||||||
llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
|
llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
|
||||||
|
@ -2302,6 +2311,8 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) {
|
||||||
trans_exit_task_glue(cx);
|
trans_exit_task_glue(cx);
|
||||||
trans_main_fn(cx, crate_constant(cx));
|
trans_main_fn(cx, crate_constant(cx));
|
||||||
|
|
||||||
|
check_module(llmod);
|
||||||
|
|
||||||
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
|
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
|
||||||
llvm.LLVMDisposeModule(llmod);
|
llvm.LLVMDisposeModule(llmod);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue