[cfe-dev] CFG temporary objects destructors

Ted Kremenek kremenek at apple.com
Fri Oct 22 15:49:06 PDT 2010


On Oct 22, 2010, at 10:59 AM, Marcin Świderski wrote:

> W dniu 22 października 2010 11:22 użytkownik Zhongxing Xu <xuzhongxing at gmail.com> napisał:
> When the binary operator is logical operator, why we need to replicate the control flow when adding the dtors in LHS and RHS? Could we just add the dtor right after where the LHS and RHS are evaluated?
> 
> That is, for code
> 
> A && B
> 
> we generate CFG like this:
> 
> A && B
> ~A()
> |      \
> |       B
> |       ~B()
> |        |
> A && B
> 
> Since in logical binary operator, we only need the boolean value. The temporary object can be destroyed right after it is evaluated.
> 
> This depends on how much we want to simulate real control flow of expression. C++ standard states that destructors of temporaries should be called at the end of full expression and in reverse order of their construction. Your example does not satisfy this. It only guaranties that destructor for temporary will be called.


I think Zhongxing is right.  Here is what the compiler does:

$ cat t.cpp
class A {
public:
  A();
  ~A();
  operator bool();
};
class B {
public:
  B();
  ~B();
  operator bool();
};

A foo();
B bar();

int test() {
  return foo() || bar();
}

$ /Developer/usr/bin/clang -S t.cpp -O2 -fno-exceptions
$ cat t.s | c++filt
...
test():                              ## @_Z4testv
Leh_func_begin0:
## BB#0:                                ## %entry
	pushq	%rbp
Ltmp0:
	movq	%rsp, %rbp
Ltmp1:
	pushq	%r14
	pushq	%rbx
	subq	$16, %rsp
Ltmp2:
	leaq	-24(%rbp), %rbx
	movq	%rbx, %rdi
	callq	foo()
	movq	%rbx, %rdi
	callq	A::operator bool()
	testb	%al, %al
	movl	$1, %ebx
	jne	LBB0_2
## BB#1:                                ## %temp.cond-dtor.call
	leaq	-32(%rbp), %rbx
	movq	%rbx, %rdi
	callq	bar()
	movq	%rbx, %rdi
	callq	B::operator bool()
	movb	%al, %r14b
	movq	%rbx, %rdi
	callq	B::~B()
	movzbl	%r14b, %ebx
LBB0_2:                                 ## %temp.cond-dtor.cont
	leaq	-24(%rbp), %rdi
	callq	A::~A()
	movl	%ebx, %eax
	addq	$16, %rsp
	popq	%rbx
	popq	%r14
	popq	%rbp
	ret
Leh_func_end0:


We can clearly see that there are 3 basic blocks and only 1 conditional branch.  Notice that ~B() is called immediately after calling 'operator bool()' in class B.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20101022/fc4722a1/attachment.html>


More information about the cfe-dev mailing list