diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-10-24 20:23:43 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-10-24 20:23:43 +0000 |
commit | b31b94a8f7b5fb5b03997c2d0e86ed8818f72c54 (patch) | |
tree | 23c03cd48ea2be7ecb0b8a7acab77567c0b67492 /clang/lib/CodeGen | |
parent | 202210b3694940b4e5cca50aa3b6208e0298121b (diff) | |
download | bcm5719-llvm-b31b94a8f7b5fb5b03997c2d0e86ed8818f72c54.tar.gz bcm5719-llvm-b31b94a8f7b5fb5b03997c2d0e86ed8818f72c54.zip |
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
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index cabedc3857b..08ee37b4351 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -210,7 +210,6 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, case SD_Automatic: case SD_FullExpression: - assert(!ObjCARCReferenceLifetimeType->isArrayType()); CodeGenFunction::Destroyer *Destroy; CleanupKind CleanupKind; if (Lifetime == Qualifiers::OCL_Strong) { @@ -317,11 +316,12 @@ LValue CodeGenFunction:: 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 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { 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; |