diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index f168dd02ead..c8ba352e233 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -498,18 +498,51 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { } else { switch (M->getStorageDuration()) { case SD_Automatic: - case SD_FullExpression: if (auto *Size = EmitLifetimeStart( CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()), Alloca.getPointer())) { - if (M->getStorageDuration() == SD_Automatic) - pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalEHLifetimeMarker, - Alloca, Size); - else - pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca, - Size); + pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalEHLifetimeMarker, + Alloca, Size); } break; + + case SD_FullExpression: { + if (!ShouldEmitLifetimeMarkers) + break; + + // Avoid creating a conditional cleanup just to hold an llvm.lifetime.end + // marker. Instead, start the lifetime of a conditional temporary earlier + // so that it's unconditional. Don't do this in ASan's use-after-scope + // mode so that it gets the more precise lifetime marks. If the type has + // a non-trivial destructor, we'll have a cleanup block for it anyway, + // so this typically doesn't help; skip it in that case. + ConditionalEvaluation *OldConditional = nullptr; + CGBuilderTy::InsertPoint OldIP; + if (isInConditionalBranch() && !E->getType().isDestructedType() && + !CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) { + OldConditional = OutermostConditional; + OutermostConditional = nullptr; + + OldIP = Builder.saveIP(); + llvm::BasicBlock *Block = OldConditional->getStartingBlock(); + Builder.restoreIP(CGBuilderTy::InsertPoint( + Block, llvm::BasicBlock::iterator(Block->back()))); + } + + if (auto *Size = EmitLifetimeStart( + CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()), + Alloca.getPointer())) { + pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca, + Size); + } + + if (OldConditional) { + OutermostConditional = OldConditional; + Builder.restoreIP(OldIP); + } + break; + } + default: break; } |