diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprAgg.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index c3f1cbe..c574827 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -296,18 +296,25 @@ void AggExprEmitter::withReturnValueSlot( (RequiresDestruction && Dest.isIgnored()); Address RetAddr = Address::invalid(); - RawAddress RetAllocaAddr = RawAddress::invalid(); EHScopeStack::stable_iterator LifetimeEndBlock; llvm::Value *LifetimeSizePtr = nullptr; llvm::IntrinsicInst *LifetimeStartInst = nullptr; if (!UseTemp) { - RetAddr = Dest.getAddress(); + // It is possible for the existing slot we are using directly to have been + // allocated in the correct AS for an indirect return, and then cast to + // the default AS (this is the behaviour of CreateMemTemp), however we know + // that the return address is expected to point to the uncasted AS, hence we + // strip possible pointer casts here. + if (Dest.getAddress().isValid()) + RetAddr = Dest.getAddress().withPointer( + Dest.getAddress().getBasePointer()->stripPointerCasts(), + Dest.getAddress().isKnownNonNull()); } else { - RetAddr = CGF.CreateMemTemp(RetTy, "tmp", &RetAllocaAddr); + RetAddr = CGF.CreateMemTempWithoutCast(RetTy, "tmp"); llvm::TypeSize Size = CGF.CGM.getDataLayout().getTypeAllocSize(CGF.ConvertTypeForMem(RetTy)); - LifetimeSizePtr = CGF.EmitLifetimeStart(Size, RetAllocaAddr.getPointer()); + LifetimeSizePtr = CGF.EmitLifetimeStart(Size, RetAddr.getBasePointer()); if (LifetimeSizePtr) { LifetimeStartInst = cast<llvm::IntrinsicInst>(std::prev(Builder.GetInsertPoint())); @@ -316,7 +323,7 @@ void AggExprEmitter::withReturnValueSlot( "Last insertion wasn't a lifetime.start?"); CGF.pushFullExprCleanup<CodeGenFunction::CallLifetimeEnd>( - NormalEHLifetimeMarker, RetAllocaAddr, LifetimeSizePtr); + NormalEHLifetimeMarker, RetAddr, LifetimeSizePtr); LifetimeEndBlock = CGF.EHStack.stable_begin(); } } @@ -337,7 +344,7 @@ void AggExprEmitter::withReturnValueSlot( // Since we're not guaranteed to be in an ExprWithCleanups, clean up // eagerly. CGF.DeactivateCleanupBlock(LifetimeEndBlock, LifetimeStartInst); - CGF.EmitLifetimeEnd(LifetimeSizePtr, RetAllocaAddr.getPointer()); + CGF.EmitLifetimeEnd(LifetimeSizePtr, RetAddr.getBasePointer()); } } |
