<div dir="ltr"><div>Thanks you Tim,</div><div>that solved my problem!<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno mar 12 mar 2019 alle ore 18:50 Tim Northover <<a href="mailto:t.p.northover@gmail.com">t.p.northover@gmail.com</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Alberto,<br>
<br>
On Tue, 12 Mar 2019 at 18:33, Alberto Barbaro <<a href="mailto:barbaro.alberto@gmail.com" target="_blank">barbaro.alberto@gmail.com</a>> wrote:<br>
> call void bitcast (void (%struct.png_struct_def.68*, i8*, i8* (%struct.png_struct_def.68*, i64)*, void (%struct.png_struct_def.68*, i8*)*)* @png_set_mem_fn to void (%struct.png_struct_def*, i8*, i8* (%struct.png_struct_def*, i64)*, void (%struct.png_struct_def*, i8*)*)*)(%struct.png_struct_def* %create_struct, i8* %mem_ptr, i8* (%struct.png_struct_def*, i64)* %malloc_fn, void (%struct.png_struct_def*, i8*)* %free_fn) #15<br>
><br>
> I'm pretty sure that this is a CallInst but when I try to call getCalledFunction() I receive a null pointer and that really surprise me.<br>
><br>
> I would like to understand how to get the function that is called and its parameters. Can you tell me how please?<br>
<br>
The problem is that getCalledFunction is pretty naive, it just takes<br>
the getCalleeValue and dyn_cast<Function>s it. Because you've got a<br>
cast in the IR itself your situation is a bit more complicated.<br>
<br>
In this case, you could write a "findCalledFunction" something like:<br>
<br>
    Function *findCalledFunction(CallBase &CI) {<br>
      Value *Callee = CI.getCalledValue()->stripPointerCasts();<br>
      if (auto F = dyn_cast<Function>(Callee))<br>
        return F;<br>
      return nullptr;<br>
    }<br>
<br>
Where the "stripPointerCast" is the key extra ingredient that looks<br>
through the bitcast. (Someone could certainly argue that's what<br>
getCalledFunction should be doing anyway, but there are subtleties on<br>
weird targets like GPUs so it's not 100%).<br>
<br>
It won't catch all callsites (e.g. virtual function calls could still<br>
be plain %X values), but pretty much any algorithm has to be robust<br>
against an unknown callee anyway.<br>
<br>
> Am i right saying that:<br>
><br>
> (void (%struct.png_struct_def.68*, i8*, i8* (%struct.png_struct_def.68*, i64)*, void (%struct.png_struct_def.68*, i8*)*)* -> "old parameters type"<br>
> (%struct.png_struct_def*, i8*, i8* (%struct.png_struct_def*, i64)*, void (%struct.png_struct_def*, i8*)*)*) ->  "new parameters type"<br>
> (%struct.png_struct_def* %create_struct, i8* %mem_ptr, i8* (%struct.png_struct_def*, i64)* %malloc_fn, void (%struct.png_struct_def*, i8*)* %free_fn) "the parameters passed to the png_set_mem_fn"<br>
<br>
I think so, from what I understand. The essence of that cast is just<br>
changing one pointer type to another, so it doesn't actually affect<br>
how parameters are passed at all, and that is definitely the function<br>
called.<br>
<br>
As an aside, we're working towards a world where there's just one<br>
"ptr" type in LLVM. I think this whole situation would disappear<br>
completely there.<br>
<br>
> sorry I forgot to mention, how can I extract the keyword bitcast? I would like to be able to distinguish the function name.<br>
<br>
I think the answer to this question is the "stripPointerCasts"<br>
function I mentioned above, though I'm not 100% sure.<br>
<br>
Cheers.<br>
<br>
Tim.<br>
</blockquote></div>