[cfe-commits] Initializer bug with fix?

Aaron Ballman aaron at aaronballman.com
Sat Jan 14 14:47:35 PST 2012


While chasing butterflies recently, I noticed the code generated by
clang didn't match what was created by MSVC and ICC (but does match
what gcc was emitting).  Here's a simplified C++ example:

void *operator new( unsigned int size );  // note, non-throwing

class Test {
	void *data;
};

int main( void ) {
	Test *t = new Test();
	return (int)t; // ignore this, it's to trick the optimizer
}

This would produce the following assembly:

_main:                                  # @main
# BB#0:                                 # %entry
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%eax
	movl	$4, (%esp)
	calll	__Znwj
	movl	$0, (%eax)           # this is a problem, I think
	addl	$4, %esp
	popl	%ebp
	ret

After the call to operator new, the assumption is that eax will be
non-null, which isn't a valid assumption.  MSVC and ICC generate code
that performs a test for null before performing the initialization.
So clang's code will crash if operator new returns null.

My first question is: do you agree that we should be producing a null
check before initializing the members?

I've attached a patch that's my first attempt at changing this
behavior, and I'm looking for comments on whether it's the right
approach, or if there's a better way (even if it's not considered
behavior we want to change -- I'm using it as a learning experience
with the codegen).

Thanks!

~Aaron
-------------- next part --------------
A non-text attachment was scrubbed...
Name: null_check.patch
Type: application/octet-stream
Size: 1532 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120114/9571be81/attachment.obj>


More information about the cfe-commits mailing list