[LLVMbugs] [Bug 15334] New: CallSite::getCalledFunction returns null if the function callee pointer is a bitcast

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Fri Feb 22 09:44:51 PST 2013


http://llvm.org/bugs/show_bug.cgi?id=15334

            Bug ID: 15334
           Summary: CallSite::getCalledFunction returns null if the
                    function callee pointer is a bitcast
           Product: libraries
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: Support Libraries
          Assignee: unassignedbugs at nondot.org
          Reporter: khilan.gudka at cl.cam.ac.uk
                CC: csdavec at swan.ac.uk, llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Created attachment 10055
  --> http://llvm.org/bugs/attachment.cgi?id=10055&action=edit
proposed patch

Dear all

I think there is a bug in CallSite.getCalledFunction() whereby if the callee
function pointer is bitcast'd, getCalledFunction() will return null even if it
is still a direct call. I came across this when trying to generate a callgraph
for the freebsd version of gzip linked together with libz (the linking is
performed using llvm-link). The generated callgraph for gzip+libz missed the
call from gz_compress to deflate.

Digging into why this edge wasn't generated, I narrowed it down to this portion
in lib/Analysis/IPA/CallGraph.cpp: 

144 if (CS) {
145   const Function *Callee = CS.getCalledFunction();
146   if (!Callee)
147     // Indirect calls of intrinsics are not allowed so no need to check.
148     Node->addCalledFunction(CS, CallsExternalNode);
149   else if (!Callee->isIntrinsic())
150     Node->addCalledFunction(CS, getOrInsertFunction(Callee));
151 }

And in particular that CS.getCalledFunction() was returning null even though
the call was a direct one. The reason for this is because prior to linking gzip
with libz, gz_compress contained the call:

%call69 = call i32 @deflate(%struct.z_stream_s* %z, i32 4) nounwind

However, after linking, gz_compress now contained this call instead:

%call69 = call i32 bitcast (i32 (%struct.z_stream_s.1*, i32)* @deflate to i32
(%struct.z_stream_s*, i32)*)      (%struct.z_stream_s* %z, i32 4) nounwind

I.e. a bitcast is introduced to handle renaming of types during linking. As a
result, when getCalledFunction casts the called value to a Function, it returns
null.

The fix seems to remove the cast inside getCalledFunction as follows:

return dyn_cast<FunTy>(getCalledValue()->stripPointerCasts());

I've attached this proposed patch.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20130222/a39748a6/attachment.html>


More information about the llvm-bugs mailing list