Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp	(revision 133261)
+++ lib/CodeGen/CGExprAgg.cpp	(working copy)
@@ -247,16 +247,6 @@
 
 void
 AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-  if (E->getType().isPODType(CGF.getContext())) {
-    // For a POD type, just emit a load of the lvalue + a copy, because our
-    // compound literal might alias the destination.
-    // FIXME: This is a band-aid; the real problem appears to be in our handling
-    // of assignments, where we store directly into the LHS without checking
-    // whether anything in the RHS aliases.
-    EmitAggLoadOfLValue(E);
-    return;
-  }
-  
   AggValueSlot Slot = EnsureSlot(E->getType());
   CGF.EmitAggExpr(E->getInitializer(), Slot);
 }
@@ -403,6 +393,62 @@
   EmitFinalDestCopy(E, LV);
 }
 
+/// Determine whether the given aggregate expression is constructed piecemeal,
+/// e.g., through an initializer list, rather than being built as a whole.
+static bool isPiecemealConstructedAggregate(ASTContext &Context,
+                                            const Expr *E) {
+  while (true) {
+    if (const ParenExpr *Parens = dyn_cast<ParenExpr>(E)) {
+      E = Parens->getSubExpr();
+      continue;
+    }
+    
+    if (const UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
+      if (UnOp->getOpcode() == UO_Extension) {
+        E = UnOp->getSubExpr();
+        continue;
+      }
+      
+      break;
+    }
+    
+    if (const CastExpr *Cast = dyn_cast<CastExpr>(E)) {
+      if (Cast->getCastKind() == CK_LValueBitCast ||
+          Cast->getCastKind() == CK_NoOp ||
+          Cast->getCastKind() == CK_LValueToRValue) {
+        E = Cast->getSubExpr();
+        continue;
+      }
+      
+      break;
+    }
+    
+    if (const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E)) {
+      if (BinOp->getOpcode() == BO_Comma) {
+        E = BinOp->getRHS();
+        continue;
+      }
+      
+      break;
+    }
+    
+    if (const ChooseExpr *Choose = dyn_cast<ChooseExpr>(E)) {
+      E = Choose->getChosenSubExpr(Context);
+      continue;
+    }
+    
+    if (const GenericSelectionExpr *Generic = dyn_cast<GenericSelectionExpr>(E)) {
+      E = Generic->getResultExpr();
+      continue;
+    }
+    
+    break;
+  }
+
+  return isa<CompoundLiteralExpr>(E) || isa<InitListExpr>(E);
+}
+                                            
+
 void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
   // For an assignment to work, the value on the right has
   // to be compatible with the value on the left.
@@ -447,10 +493,20 @@
     if (CGF.getContext().getLangOptions().getGCMode())
       GCollection = TypeRequiresGCollection(E->getLHS()->getType());
 
-    // Codegen the RHS so that it stores directly into the LHS.
-    AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, 
-                                                   GCollection);
-    CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
+    if (!isPiecemealConstructedAggregate(CGF.getContext(), E->getRHS())) {
+      // Codegen the RHS so that it stores directly into the LHS.
+      AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, 
+                                                     GCollection);
+      CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
+      EmitFinalDestCopy(E, LHS, true);
+      return;
+    }
+    
+    // Generate an aggregate temporary for the RHS, then copy that temporary
+    // over to the LHS.
+    AggValueSlot TempSlot = CGF.CreateAggTemp(E->getRHS()->getType());
+    CGF.EmitAggExpr(E->getRHS(), TempSlot, false);
+    CGF.EmitAggregateCopy(LHS.getAddress(), TempSlot.getAddr(), E->getType());
     EmitFinalDestCopy(E, LHS, true);
   }
 }
