Question about insert call func with pionter parameter

Hi,

I got a problem when I am trying to insert a call function with pointer arguments.

The function C proto-type is the following,

void stat_func(char *);

ConstantArray *Cstr = dyn_cast(gI->getInitializer());

Function exFunc = M->getOrInsertFunction(“stat_func”, Type::VoidTy, PointerType::get(Type::SByteTy),0);
std::vector<Value
> Args(1);
Args[0] = constantArray::get(Cstr->getAsString());
CallInst *call = new CallInst(exFunc, Args,“”,InsertPos);

If the code look like the above, it could compile successfully. But once I run this pass, finally, I got errors as the following.

" Call parameter type does not match function signature!"
[21 x sbyte] c"This a example\00\00\00\00\00\00"
sbyte* call void %stat_func( [21 x sbyte] c “this a example\00\00\00\00”

Broken module found, comilation aborted!

The information comes from verifier.cpp which mean the type of parameter of the function differ with the type of parameter the code passed.

I knew that the constantarry differ from sbyte pointer ( sbyte*), but I tried to change the code to

Function *exFunc = M->getOrInsertFunction(“stat_func”, Type::VoidTy, Cstr->getType(),0);
or

Function *exFunc = M->getOrInsertFunction(“stat_func”, Type::VoidTy, Type::ArrayTyID,0);

and once I run the pass, it is worse than the above. the error information is

" llvm::FunctionType::FunctionType(const llvm::Type*, const std::vector<const llvm::Type*, std::allocator>&,bool): Assertion …Function arguments must be value types!"

Finally, I tried to change the code of arguments like this

Function exFunc = M->getOrInsertFunction(“stat_func”, Type::VoidTy, PointerType::get(Type::SByteTy),0);
std::vector<Value
> Args(1);
Args[0] = constantExpr::getGetElementPtr(constantArray::get(Cstr->getAsString()), 0);

But I failed to pass the compilation. How could I fix this problem?

Thanks so much.
Qiuyu

Hi,

I got a problem when I am trying to insert a call function with pointer arguments.

The function C proto-type is the following,

void stat_func(char *);

ConstantArray *Cstr = dyn_cast<ConstantArray>(gI->getInitializer());

......

Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, PointerType::get(Type::SByteTy),0);
std::vector<Value*> Args(1);
Args[0] = constantArray::get(Cstr->getAsString());
CallInst *call = new CallInst(exFunc, Args,"",InsertPos);

If the code look like the above, it could compile successfully. But once I run this pass, finally, I got errors as the following.

" Call parameter type does not match function signature!"
[21 x sbyte] c"This a example\00\00\00\00\00\00"
sbyte* call void %stat_func( [21 x sbyte] c "this a example\00\00\00\00"
...........
Broken module found, comilation aborted!
........

The information comes from verifier.cpp which mean the type of parameter of the function differ with the type of parameter the code passed.

Yes, this analysis is exactly right.

I knew that the constantarry differ from sbyte pointer ( sbyte*), but I tried to change the code to

Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, Cstr->getType(),0);

or

Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, Type::ArrayTyID,0);

and once I run the pass, it is worse than the above. the error information is

" llvm::FunctionType::FunctionType(const llvm::Type*, const std::vector<const llvm::Type*, std::allocator<const llvm::Type::>>&,bool): Assertion ..............Function arguments must be value types!"

Frankly, I'm suprised this compiles. "TyID"'s are not types. In particular, there is no way to say "pass any array as this argument".

Finally, I tried to change the code of arguments like this

Function *exFunc = M->getOrInsertFunction("stat_func", Type::VoidTy, PointerType::get(Type::SByteTy),0);
std::vector<Value*> Args(1);
Args[0] = constantExpr::getGetElementPtr(constantArray::get(Cstr->getAsString()), 0);

But I failed to pass the compilation. How could I fix this problem?

Here you're definitely on the right track. To get to [n x sbyte]* to sbyte*, you need to use a 'getelementptr Ptr, 0, 0' instruction or constant expr. The problem with the code above is that the getGetElementPtr method takes a vector as the second argument (of the indexes), and that ConstantExpr is capitalized. You can certainly create a vector<Value*>, and pass in two Constant 0's (not literal C integer 0's). Alternatively, you can just *cast* the pointer to array to pointer to sbyte, and VMCore should notice that it can create the getelementptr constantexpr instead, saving you the trouble.

The second problem with this is that ConstantArray's cannot be used as normal values, they can only be used to initialize a global variable. Given that global variable, you can use the global's address to access the contents of the array.

-Chris