TheDan64 / inkwell

It's a New Kind of Wrapper for Exposing LLVM (Safely)
https://thedan64.github.io/inkwell/
Apache License 2.0
2.37k stars 229 forks source link

Inkwell causing a crash when `metadata` is encountered as the type of a function argument #546

Open iamrecursion opened 1 month ago

iamrecursion commented 1 month ago

Describe the Bug As part of a project that ingests LLVM IR I am probing function definitions (and calls) for the types of their arguments. As my ingested IR comes from Rust (for now), it is not uncommon for me to see calls to @llvm.dbg.declare and the accompanying declaration.

declare void @llvm.dbg.declare(metadata, metadata, metadata)

Given the func: FunctionValue corresponding to this declaration, calling func.get_type().get_param_types() will cause a crash in BasicTypeEnum::new with the message "Unsupported basic type: Metadata".

To Reproduce

In an environment with the below things available, run test2::run.

lib.rs:


#[cfg(test)]
mod test2 {
    use std::path::Path;

    use inkwell::{context::Context, memory_buffer::MemoryBuffer};

    #[test]
    fn run() {
        let test_input = r"add_min.ll";
        let source_buf = MemoryBuffer::create_from_file(Path::new(test_input)).unwrap();

        let mut ctx = Context::create();
        let module = ctx.create_module_from_ir(source_buf).unwrap();

        for function in module.get_functions() {
            let fun_ty = function.get_type();

            // This crashes
            fun_ty.get_param_types();
        }
    }
}

add_min.ll:

declare void @llvm.dbg.declare(metadata, metadata, metadata) #1

Expected Behavior

I would have initially expected for metadata to be a supported type, but the fact that it isn't indicates that there is likely quite some complexity to making it so. For my use case, it would be sufficient to know that the type was metadata and avoid the crash.

Ideally I would like to avoid just banning known-problematic functions from my analysis, but that is a stopgap I am considering for the moment.

LLVM Version (please complete the following information):

Desktop (please complete the following information):

Additional Context

If there is a better way to detect usages of metadata in type position that doesn't eventually result in a crashing call to BasicTypeEnum::new, I would be happy to hear about it.

TheDan64 commented 1 week ago

We already have a BasicMetadataValueEnum type, we probably want get_param_types to return that instead. Would be happy to review a PR