CodeGen: correct materialize temporary aggregates in ARC mode
Avoid an assertion when materializing a lifetime type aggregate temporary. When
performing CodeGen for ObjC++, we could generate a lifetime-only aggregate
temporary by using an initializer list (which is effectively an array). We
would reach through the temporary expression, fishing out the inner expression.
If this expression was a lifetime expression, we would attempt to emit this as a
scalar. This would eventually result in an assertion as the emission would
eventually assert that the expression being emitted has a scalar evaluation
kind.
Add a case to handle the aggregate expressions. Use the EmitAggExpr to emit the
aggregate expression rather than the EmitScalarInit.
Addresses PR21347.
llvm-svn: 220590
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index cabedc3..08ee37b4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -210,7 +210,6 @@
case SD_Automatic:
case SD_FullExpression:
- assert(!ObjCARCReferenceLifetimeType->isArrayType());
CodeGenFunction::Destroyer *Destroy;
CleanupKind CleanupKind;
if (Lifetime == Qualifiers::OCL_Strong) {
@@ -317,11 +316,12 @@
EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
const Expr *E = M->GetTemporaryExpr();
+ // FIXME: ideally this would use EmitAnyExprToMem, however, we cannot do so
+ // as that will cause the lifetime adjustment to be lost for ARC
if (getLangOpts().ObjCAutoRefCount &&
M->getType()->isObjCLifetimeType() &&
M->getType().getObjCLifetime() != Qualifiers::OCL_None &&
M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
- // FIXME: Fold this into the general case below.
llvm::Value *Object = createReferenceTemporary(*this, M, E);
LValue RefTempDst = MakeAddrLValue(Object, M->getType());
@@ -332,7 +332,21 @@
Var->setInitializer(CGM.EmitNullConstant(E->getType()));
}
- EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
+ switch (getEvaluationKind(E->getType())) {
+ default: llvm_unreachable("expected scalar or aggregate expression");
+ case TEK_Scalar:
+ EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
+ break;
+ case TEK_Aggregate: {
+ CharUnits Alignment = getContext().getTypeAlignInChars(E->getType());
+ EmitAggExpr(E, AggValueSlot::forAddr(Object, Alignment,
+ E->getType().getQualifiers(),
+ AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers,
+ AggValueSlot::IsNotAliased));
+ break;
+ }
+ }
pushTemporaryCleanup(*this, M, E, Object);
return RefTempDst;