BuildCall2 fails with assertion error when passing variadic arguments to printf
Description
When trying to use BuildCall2 to call the printf function, I'm encountering an assertion error related to type mismatch in variadic arguments. The error occurs specifically when passing an integer value as a variadic argument to printf.
Error Message
Assertion failed: (i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!", file C:\src\llvm_package_6923b0a7\llvm-project\llvm\lib\IR\Instructions.cpp, line 455
Code Example
Here's a simplified version of my code that reproduces the issue:
public LLVMValueRef VisitPrintStatement(CodeParser.PrintStatementContext context)
{
string variableName = context.ID().GetText();
if (!_variables.TryGetValue(variableName, out var variable))
{
throw new Exception($"Variable {variableName} is not defined.");
}
// Load integer value from allocated memory
var varType = variable.TypeOf.ElementType;
var value = Builder.BuildLoad2(varType, variable, $"{variableName}_value");
// Create format string for printf
string formatStr = "%d\n";
var formatStrPtr = Builder.BuildGlobalStringPtr(formatStr, "formatStr");
// Define printf function
var printfType = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, [LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0)], true);
var func = GetOrInsertFunction("printf", printfType);
// Call printf - this line causes the assertion error
var call = Builder.BuildCall2(func.TypeOf, func, [formatStrPtr, value]);
return call;
}
Debugging Information
I've examined the types right before the assertion fails:
printfType = {i32 (i8*, ...)}func = {declare i32 @printf(i8*, ...)}formatStrPtr = {i8* getelementptr inbounds ([4 x i8], [4 x i8]* @formatStr, i32 0, i32 0)}args[0] = {i8* getelementptr inbounds ([4 x i8], [4 x i8]* @formatStr, i32 0, i32 0)}args[1] = { %value1_value = load i32, i32* %value1, align 4}
Expected Behavior
I expect BuildCall2 to properly handle variadic functions and their arguments, especially for common use cases like printf with integer arguments.
Environment
- LLVMSharp version: Latest in nuget.
- .NET version: .NET 9
- OS: Windows
Any guidance would be greatly appreciated!
Still happen on the latest release? https://github.com/dotnet/LLVMSharp/releases/tag/v20.1.2
Still happen on the latest release? https://github.com/dotnet/LLVMSharp/releases/tag/v20.1.2
I haven't used this library since its error:0
After experiencing the same issue, found the root cause: LLVMModuleRef.AddFunction(...) returns a pointer to the function. So calling LLVMValueRef.TypeOf, predictably, returned the {ptr} type instead of the function type.
Looking at the C API (https://llvm.org/doxygen/IR_2Core_8cpp_source.html), there's no way to get the function pointer from the LLVMValueRef, so I stored it in a separate Dictionary.
In your example, passing printfType instead of func.TypeOf should do the trick.