diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-04-05 20:52:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-04-05 20:52:58 +0000 |
commit | e78fac5126cfab4c9bf35d3a478239b38825b17b (patch) | |
tree | 38f6360237fd9031ed0bbdae18629979e7774f5a /clang/lib/CodeGen/CGClass.cpp | |
parent | c233ae8004dfa6aa2c420fe16d15bc3f28ed4ac1 (diff) | |
download | bcm5719-llvm-e78fac5126cfab4c9bf35d3a478239b38825b17b.tar.gz bcm5719-llvm-e78fac5126cfab4c9bf35d3a478239b38825b17b.zip |
PR36992: do not store beyond the dsize of a class object unless we know
the tail padding is not reused.
We track on the AggValueSlot (and through a couple of other
initialization actions) whether we're dealing with an object that might
share its tail padding with some other object, so that we can avoid
emitting stores into the tail padding if that's the case. We still
widen stores into tail padding when we can do so.
Differential Revision: https://reviews.llvm.org/D45306
llvm-svn: 329342
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 4ba5c06099a..fb09b4d17a7 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -555,10 +555,12 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, BaseClassDecl, isBaseVirtual); AggValueSlot AggSlot = - AggValueSlot::forAddr(V, Qualifiers(), - AggValueSlot::IsDestructed, - AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased); + AggValueSlot::forAddr( + V, Qualifiers(), + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased, + CGF.overlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual)); CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); @@ -647,7 +649,8 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); // Copy the aggregate. - CGF.EmitAggregateCopy(LHS, Src, FieldType, LHS.isVolatileQualified()); + CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.overlapForFieldInit(Field), + LHS.isVolatileQualified()); // Ensure that we destroy the objects if an exception is thrown later in // the constructor. QualType::DestructionKind dtorKind = FieldType.isDestructedType(); @@ -677,10 +680,12 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS, break; case TEK_Aggregate: { AggValueSlot Slot = - AggValueSlot::forLValue(LHS, - AggValueSlot::IsDestructed, - AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased); + AggValueSlot::forLValue( + LHS, + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased, + overlapForFieldInit(Field)); EmitAggExpr(Init, Slot); break; } @@ -911,15 +916,15 @@ namespace { } CharUnits getMemcpySize(uint64_t FirstByteOffset) const { + ASTContext &Ctx = CGF.getContext(); unsigned LastFieldSize = - LastField->isBitField() ? - LastField->getBitWidthValue(CGF.getContext()) : - CGF.getContext().getTypeSize(LastField->getType()); - uint64_t MemcpySizeBits = - LastFieldOffset + LastFieldSize - FirstByteOffset + - CGF.getContext().getCharWidth() - 1; - CharUnits MemcpySize = - CGF.getContext().toCharUnitsFromBits(MemcpySizeBits); + LastField->isBitField() + ? LastField->getBitWidthValue(Ctx) + : Ctx.toBits( + Ctx.getTypeInfoDataSizeInChars(LastField->getType()).first); + uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize - + FirstByteOffset + Ctx.getCharWidth() - 1; + CharUnits MemcpySize = Ctx.toCharUnitsFromBits(MemcpySizeBits); return MemcpySize; } @@ -1960,7 +1965,8 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, } EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false, - /*Delegating=*/false, curAddr, E); + /*Delegating=*/false, curAddr, E, + AggValueSlot::DoesNotOverlap); } // Go to the next element. @@ -1995,7 +2001,8 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, - const CXXConstructExpr *E) { + const CXXConstructExpr *E, + AggValueSlot::Overlap_t Overlap) { CallArgList Args; // Push the this ptr. @@ -2011,7 +2018,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, LValue Src = EmitLValue(Arg); QualType DestTy = getContext().getTypeDeclType(D->getParent()); LValue Dest = MakeAddrLValue(This, DestTy); - EmitAggregateCopyCtor(Dest, Src); + EmitAggregateCopyCtor(Dest, Src, Overlap); return; } @@ -2023,7 +2030,8 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(), /*ParamsToSkip*/ 0, Order); - EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args); + EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args, + Overlap); } static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, @@ -2055,7 +2063,8 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, bool Delegating, Address This, - CallArgList &Args) { + CallArgList &Args, + AggValueSlot::Overlap_t Overlap) { const CXXRecordDecl *ClassDecl = D->getParent(); // C++11 [class.mfct.non-static]p2: @@ -2082,7 +2091,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, LValue SrcLVal = MakeAddrLValue(Src, SrcTy); QualType DestTy = getContext().getTypeDeclType(ClassDecl); LValue DestLVal = MakeAddrLValue(This, DestTy); - EmitAggregateCopyCtor(DestLVal, SrcLVal); + EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap); return; } @@ -2171,7 +2180,7 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall( } EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false, - This, Args); + This, Args, AggValueSlot::MayOverlap); } void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall( @@ -2267,7 +2276,8 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1), E->getConstructor(), /*ParamsToSkip*/ 1); - EmitCXXConstructorCall(D, Ctor_Complete, false, false, This, Args); + EmitCXXConstructorCall(D, Ctor_Complete, false, false, This, Args, + AggValueSlot::MayOverlap); } void @@ -2302,7 +2312,8 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, } EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false, - /*Delegating=*/true, This, DelegateArgs); + /*Delegating=*/true, This, DelegateArgs, + AggValueSlot::MayOverlap); } namespace { @@ -2333,7 +2344,8 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor AggValueSlot::forAddr(ThisPtr, Qualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased); + AggValueSlot::IsNotAliased, + AggValueSlot::MayOverlap); EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); |