[LLVMbugs] [Bug 11332] New: Calls using a bitcast of a function don't show up in the call graph

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Nov 7 23:41:53 PST 2011


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

             Bug #: 11332
           Summary: Calls using a bitcast of a function don't show up in
                    the call graph
           Product: libraries
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Interprocedural Analyses
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: jobnoorman at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Created attachment 7590
  --> http://llvm.org/bugs/attachment.cgi?id=7590
patch

Consider the following C code:

void foo();
int main() {foo();}

Clang emits the following IR:

define i32 @main() nounwind {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval
  call void bitcast (void (...)* @foo to void ()*)()
  %0 = load i32* %retval
  ret i32 %0
}
declare void @foo(...)

Note the call using a bitcast. This is of course needed since foo is declared
as having a variable argument list and this is probably the correct way to do
this given what the C standard says about this declaration of foo (it has an
unspecified number and types of arguments).

This use of a bitcast has two side-effects on the call graph:
1) Since the bitcast is a use of foo other than a direct call, foo will be
considered as having its address taken. This means foo will have an incoming
edge from the external node in the call graph.
2) Since the call to foo is not considered as being direct, there will not be
an edge from main to foo in the call graph.

IMO, both effects are not valid since 1) the address of foo is not really taken
and 2) the call to foo is really a direct call.

I have attached a patch that will undo both side-effects.

This patch does the following:
1) If a function is only used by either
 - Call instructions as the callee, or
 - Constant (bitcast) expressions that in turn are only used as the callee in
call instructions
then it will not be considered as having its address taken.
2) The callee function will be extracted from call instructions having a
constant (bitcast) expression as the called value.

I have implemented this just at the call graph level by adding two functions to
the BasicCallGraph class to avoid a bigger impact on LLVM. It is also possible
(and maybe beneficial for other parts of LLVM?) to implement 1) in
Function::hasAddressTaken and 2) in
CallInst/InvokeInst/CallSite::getCalledFunction but I didn't dare to touch
those parts of LLVM :-)

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list