Skip to content

Commit 3f9d5da

Browse files
committed
rustc: Run the verifier over LLVM modules before writing them out
1 parent a1c7d19 commit 3f9d5da

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/comp/lib/llvm.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,16 @@ native mod llvm = llvm_lib {
687687
fn LLVMPreferredAlignmentOfType(TargetDataRef TD, TypeRef Ty) -> uint;
688688
/** Disposes target data. */
689689
fn LLVMDisposeTargetData(TargetDataRef TD);
690+
691+
/** Creates a pass manager. */
692+
fn LLVMCreatePassManager() -> PassManagerRef;
693+
/** Disposes a pass manager. */
694+
fn LLVMDisposePassManager(PassManagerRef PM);
695+
/** Runs a pass manager on a module. */
696+
fn LLVMRunPassManager(PassManagerRef PM, ModuleRef M) -> Bool;
697+
698+
/** Adds a verification pass. */
699+
fn LLVMAddVerifierPass(PassManagerRef PM);
690700
}
691701

692702
/* Slightly more terse object-interface to LLVM's 'builder' functions. */
@@ -1209,6 +1219,19 @@ fn mk_target_data(str string_rep) -> target_data {
12091219
ret rec(lltd=lltd, dtor=target_data_dtor(lltd));
12101220
}
12111221

1222+
/* Memory-managed interface to pass managers. */
1223+
1224+
obj pass_manager_dtor(PassManagerRef PM) {
1225+
drop { llvm.LLVMDisposePassManager(PM); }
1226+
}
1227+
1228+
type pass_manager = rec(PassManagerRef llpm, pass_manager_dtor dtor);
1229+
1230+
fn mk_pass_manager() -> pass_manager {
1231+
auto llpm = llvm.LLVMCreatePassManager();
1232+
ret rec(llpm=llpm, dtor=pass_manager_dtor(llpm));
1233+
}
1234+
12121235

12131236
//
12141237
// Local Variables:

src/comp/middle/trans.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import lib.llvm.llvm;
2323
import lib.llvm.builder;
2424
import lib.llvm.target_data;
2525
import lib.llvm.type_handle;
26-
import lib.llvm.mk_type_handle;
26+
import lib.llvm.mk_pass_manager;
2727
import lib.llvm.mk_target_data;
28+
import lib.llvm.mk_type_handle;
2829
import lib.llvm.llvm.ModuleRef;
2930
import lib.llvm.llvm.ValueRef;
3031
import lib.llvm.llvm.TypeRef;
@@ -2245,6 +2246,14 @@ fn declare_intrinsics(ModuleRef llmod) -> hashmap[str,ValueRef] {
22452246
ret intrinsics;
22462247
}
22472248

2249+
fn check_module(ModuleRef llmod) {
2250+
auto pm = mk_pass_manager();
2251+
llvm.LLVMAddVerifierPass(pm.llpm);
2252+
llvm.LLVMRunPassManager(pm.llpm, llmod);
2253+
2254+
// TODO: run the linter here also, once there are llvm-c bindings for it.
2255+
}
2256+
22482257
fn trans_crate(session.session sess, @ast.crate crate, str output) {
22492258
auto llmod =
22502259
llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"),
@@ -2302,6 +2311,8 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) {
23022311
trans_exit_task_glue(cx);
23032312
trans_main_fn(cx, crate_constant(cx));
23042313

2314+
check_module(llmod);
2315+
23052316
llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output));
23062317
llvm.LLVMDisposeModule(llmod);
23072318
}

0 commit comments

Comments
 (0)