[llvm-dev] CallInst::getCalledFunction returns null?

John Criswell via llvm-dev llvm-dev at lists.llvm.org
Tue Sep 8 09:37:38 PDT 2015


On 9/8/15 11:52 AM, Christian Convey wrote:
> Hi John,
>
> On Tue, Sep 8, 2015 at 11:26 AM, John Criswell <jtcriswel at gmail.com 
> <mailto:jtcriswel at gmail.com>> wrote:
>
>     The getCalledFunc() method is not very sophisticated.  It turns
>     NULL if the called value is not trivially a function constant.
>
>     I'm not sure for the reasoning behind this.  My best guess is that
>     a constant expression could do all sorts of interesting things. 
>     For example, a constant expression can select one of several
>     values or pull a value out of an array using a constant expression
>     GEP.
>
>     You'll need to do what SAFECode does; use
>     getCalledValue()->stripPointerCasts() to get the called value and
>     remove any casts that stand between you and the function value. 
>     It's inconvenient, but it works.
>
>
> My apologies if this should be a clang question, but I'm trying to 
> reconcile what people mean by "direct" calls in the clang vs. LLVM 
> communities.  (The documentation for getCalledFunction makes me wonder 
> if I'm using term the same way as everyone else.)
>
> I'm coming to this question with my AA-implementer's hat on.  I want 
> to handle C/C++ indirect calls well, and I'm trying to figure out if 
> that basically means handling non-`llvm::Constant` 
> callee-specifications well.

I would think so, yes.

>
> Do you know if it tends to be the case that:
>
>   * A direct function call at the C/C++ level becomes an
>     llvm::CallInst or llvm::InvokeInst where the callee is name by an
>     llvm::Constant.
>
>   * An indirect function call at the C/C++ level ends up being
>     translated to a llvm::CallInst or llvm::InvokeInst where the
>     callee is named by an llvm::Value which is /not/ an llvm::Constant.
>

No.  A direct call at the C/C++ source level can end up being a call in 
which the argument to the CallInst or InvokeInst is not a function 
constant.  Examples include:

1) Cases in which a function is used with a different number of 
arguments than the declared type.  This is common when a C function 
prototype has no arguments but the function definition has arguments.

2) An optimization changes an if/then/else to a predicated instruction.  
For example, it is possible that:

if (flag)
     foo(5);
else
     bar(5);

... could become something like (in a combined LLVM/C notation):

call ((flag) ? foo : bar) (5)

Note that I don't know if this optimization will happen, but in theory, 
it can happen.

In short, if you want to handle C/C++ code, you need to handle whatever 
the frontend spits out in LLVM IR.  That includes function constants, 
casted function constants, function arguments that are a select 
instruction between several constants, etc.

You may want to grep the DSA code in the poolalloc project for 
getCalledValue() to see what kind of CallInsts it handles.  That way, 
you can piggy-back off the experiences we've had updating DSA to handle 
what the newer LLVM front-ends do.

Regards,

John Criswell

>
> Thanks again,
> Christian


-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150908/6ea3d572/attachment.html>


More information about the llvm-dev mailing list