[cfe-commits] [PATCH] Fix struct assignment from "piecemeal" aggregates

Douglas Gregor dgregor at apple.com
Fri Jun 17 11:21:07 PDT 2011

The fix I added in r133261 to solve the miscompilation of

  typedef struct S { int x,y; } S;
  S x(struct S s) { s = (S){s.y,s.x}; return s; }	

was terribly unsatisfying, because it worked around a bug in the compilation of aggregate assignment expressions, e.g.,

  lhs = rhs

As an optimization, IR generation computes the address of the the lhs and then directly initializes 'lhs' with the value of rhs. This works great except when the expression 'rhs' actually builds a structure piece-by-piece, as in

	s = (S){s.y,s.x}

and individual pieces refer back to the lhs, because those individual pieces are written immediately to the lhs. No temporary structure for the rhs is ever created or allocated. In the example, the function x(), when given a structure { 1,  2 }, will end up returning { 2, 2 } rather than the intended { 2, 1 }.

The fix in r133261 basically forced us to always create a temporary and memcpy when generating a non-POD compound literal, but that's a hack: the real bug is that assignment is directly initializing the lhs from the rhs when it isn't safe to do so.

The attached patch fixes the root of the problem: by detecting when the rhs is something that will build an aggregate piecemeal, we can generate safer code that creates a temporary for the rhs and then copies it over. In the common case (rhs builds a full aggregate value in one shot), we still perform the optimization.

Comments appreciated!

	- Doug

-------------- next part --------------
A non-text attachment was scrubbed...
Name: agg-piecemeal-init.patch
Type: application/octet-stream
Size: 3780 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110617/35129833/attachment.obj>

More information about the cfe-commits mailing list