Open
Description
In an attempt to get around #32, I've been trying to get a program working that can call printf with a string array. Looking at working IR, I see that to convert from an array to a pointer, an inbounds GEP instruction is used. This is the code I came up with to replicate that.
extern crate inkwell;
extern crate pest;
use inkwell::context::Context;
use inkwell::targets::{InitializationConfig, Target};
use inkwell::AddressSpace;
use inkwell::module::Linkage;
use inkwell::values::IntValue;
use std::path::Path;
fn main() {
Target::initialize_native(&InitializationConfig::default()).unwrap();
let ctx = Context::create();
let module = ctx.create_module("program");
let builder = ctx.create_builder();
let str_type = ctx.i8_type().ptr_type(AddressSpace::Generic);
let i32_type = ctx.i32_type();
let my_message = "Hello, World!\n\0";
let arr_type = ctx.i8_type().array_type(my_message.len() as u32);
let mut chars = Vec::with_capacity(my_message.len());
for ch in my_message.chars() {
chars.push(ctx.i8_type().const_int(ch as u64, false));
}
let global = module.add_global(&arr_type, Some(AddressSpace::Generic), "message");
let oof: Vec<&IntValue> = chars.iter().map(|x| x).collect();
let str_array = arr_type.const_array(&oof[..]);
global.set_initializer(&str_array);
let printf_type = i32_type.fn_type(&[&str_type], true);
let printf = module.add_function("printf", &printf_type, Some(&Linkage::ExternalLinkage));
let main_fn_type = i32_type.fn_type(&[&i32_type, &str_type.ptr_type(AddressSpace::Generic)], false);
let main_fn = module.add_function("main", &main_fn_type, None);
let block = ctx.append_basic_block(&main_fn, "entry");
builder.position_at_end(&block);
let value = builder.build_in_bounds_gep(&global.as_pointer_value(), &oof[..], "");
builder.build_call(&printf, &[&value], "", false);
builder.build_return(Some(&i32_type.const_int(0, false)));
// println!("{:?}", module.print_to_string());
module.print_to_file(Path::new("test.ll"));
}
At the line where value
is bound, the program exits with a SIGSEGV
Environment
Operating system: Arch Linux
Kernel version: 4.15.3-1-ARCH
LLVM version: 5.0.1-2
Inkwell version: 0.1.0#eafca272
rustc -vV output:
rustc 1.25.0-nightly (3ec5a99aa 2018-02-14)
binary: rustc
commit-hash: 3ec5a99aaa0084d97a9e845b34fdf03d1462c475
commit-date: 2018-02-14
host: x86_64-unknown-linux-gnu
release: 1.25.0-nightly
LLVM version: 6.0