Description
Bugzilla Link | 1658 |
Resolution | WONTFIX |
Resolved on | Mar 26, 2012 05:57 |
Version | 1.0 |
OS | All |
CC | @asl,@d0k,@edwintorok,@sunfishcode,@nlewycky |
Extended Description
Consider this code:
struct ctor {
void *foo;
ctor(const ctor &X);
ctor() {}
};
struct test {
unsigned char *field0;
};
test foo();
ctor bar();
void testfunc() {
test xx;
ctor yy;
xx = foo();
yy = bar();
}
In the GCC abi, single element structs are returned as registers, larger structs and any struct with a copy ctor are returned by passing a hidden "sret" pointer to the struct. llvm-gcc compiles this to:
%tmp2 = call i8* @​_Z3foov( ) ; <i8*> [#uses=0]
call void @​_Z3barv( %struct.ctor* %tmp1 sret )
which is correct. The problem is that the CBE doesn't know about this. When run through the CBE, we get:
struct l_struct_2E_ctor {
unsigned char field0;
};
...
struct l_struct_2E_ctor llvm_cbe_tmp1; / Address-exposed local */
*((&llvm_cbe_tmp1)) = _Z3barv();
...
Suddenly the the C compiler compiling the CBE output will return the struct in a register, instead of passing it by dummy argument. This causes miscompilation of Misc-C++/bigfib and probably a lot of other stuff because this affects std::string.
-Chris