[LLVMdev] incorrect DSCallGraph for simple indirect call with vtable nearby

Ben Liblit liblit at cs.wisc.edu
Wed Aug 10 08:37:23 PDT 2011


In an earlier message 
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-August/042298.html), 
Andrew Lenharth suggested that EQTDDataStructures (from the poolalloc 
project) may only try to resolve indirect function calls.  However, I am 
now finding that the generated DSCallGraph over-approximates the callees 
in a very simple indirect call.  Some over-approximation is unavoidable, 
but this case seems simple enough that any reasonable analysis ought to 
have been able to give the exact, correct answer.

My example C++ source file, compiled to bitcode using clang from the 
current llvm trunk, is as follows:

	struct Base
	{
	  virtual void virt();
	};

	void Base::virt()
	{
	}

	void red();
	void blue();

	extern volatile int unknown;
	extern Base *base;

	void test()
	{
	  base->virt();
	  (unknown ? red : blue)();
	}

Observe that we have a class with a virtual method, and two indirect 
calls: one through a vtable to that virtual method, and another which is 
a simple non-deterministic choice between two possible function 
pointers.  I can understand an inexact (over-approximating) set of 
callees for the vtable call, as that is rather complex at the bitcode 
level.  However, I am very surprised to see an over-approximation at the 
second indirect call, which is merely picking between two possible values:

	%11 = phi void ()* [ @red(), %8 ], [ @blue(), %9 ]   # demangled
	call void %11()

Yet my DSCallGraph tester code reports that this instruction might call 
either red(), blue(), or Base::virt().  I am at a loss to explain why.

Equally strange: if I comment out the "base->virt();" call, then 
DSCallGraph *does* give the expected answer that "(unknown ? red : 
blue)()" could call either red() or blue() but not Base::virt(). 
Somehow having that vtable-based call present forces the other call to 
be unexpectedly conservative in its over-approximation.

Source code for my DSCallGraph tester is attached below.  I'd be most 
grateful for any clues you good people can provide.

Thanks,
Ben
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ShowCallGraph.cpp
Type: text/x-c++src
Size: 1379 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110810/6aa969f0/attachment.cpp>


More information about the llvm-dev mailing list