aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index ad62e10473..41518fb11b 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -303,7 +303,8 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
if (InitializedDecl) {
// Get the destructor for the reference temporary.
- if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
+ if (const RecordType *RT =
+ E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
if (!ClassDecl->hasTrivialDestructor())
ReferenceTemporaryDtor = ClassDecl->getDestructor();
@@ -406,10 +407,19 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl);
if (VD && VD->hasGlobalStorage()) {
if (ReferenceTemporaryDtor) {
- llvm::Constant *DtorFn =
- CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
- CGM.getCXXABI().registerGlobalDtor(*this, DtorFn,
- cast<llvm::Constant>(ReferenceTemporary));
+ llvm::Constant *CleanupFn;
+ llvm::Constant *CleanupArg;
+ if (E->getType()->isArrayType()) {
+ CleanupFn = CodeGenFunction(CGM).generateDestroyHelper(
+ cast<llvm::Constant>(ReferenceTemporary), E->getType(),
+ destroyCXXObject, getLangOpts().Exceptions);
+ CleanupArg = llvm::Constant::getNullValue(Int8PtrTy);
+ } else {
+ CleanupFn =
+ CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
+ CleanupArg = cast<llvm::Constant>(ReferenceTemporary);
+ }
+ CGM.getCXXABI().registerGlobalDtor(*this, CleanupFn, CleanupArg);
} else {
assert(!ObjCARCReferenceLifetimeType.isNull());
// Note: We intentionally do not register a global "destructor" to
@@ -419,9 +429,13 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
return RValue::get(Value);
}
- if (ReferenceTemporaryDtor)
- PushDestructorCleanup(ReferenceTemporaryDtor, ReferenceTemporary);
- else {
+ if (ReferenceTemporaryDtor) {
+ if (E->getType()->isArrayType())
+ pushDestroy(NormalAndEHCleanup, ReferenceTemporary, E->getType(),
+ destroyCXXObject, getLangOpts().Exceptions);
+ else
+ PushDestructorCleanup(ReferenceTemporaryDtor, ReferenceTemporary);
+ } else {
switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) {
case Qualifiers::OCL_None:
llvm_unreachable(