summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-10-24 20:23:43 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-10-24 20:23:43 +0000
commitb31b94a8f7b5fb5b03997c2d0e86ed8818f72c54 (patch)
tree23c03cd48ea2be7ecb0b8a7acab77567c0b67492 /clang/lib/CodeGen
parent202210b3694940b4e5cca50aa3b6208e0298121b (diff)
downloadbcm5719-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.cpp20
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;
OpenPOWER on IntegriCloud