Thanks, I see the problem. On Fri, 6 Apr 2018, 11:56 via cfe-commits, <cfe-commits@lists.llvm.org> wrote:
> Hi Richard, > > I don't know if you are aware, but the test you added in this commit, > tail-padding.cpp is currently failing on one of the ARM bots. Can you take > a look? > > > http://lab.llvm.org:8011/builders/clang-cmake-armv7-selfhost-neon/builds/178 > > ******************** TEST 'Clang :: CodeGenCXX/tail-padding.cpp' FAILED > ******************** > Script: > -- > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/stage2/bin/clang > -cc1 -internal-isystem > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/stage2/lib/clang/7.0.0/include > -nostdsysteminc -triple armv7l-unknown-linux-gnueabihf -emit-llvm -o - > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/llvm/tools/clang/test/CodeGenCXX/tail-padding.cpp > | > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/stage2/bin/FileCheck > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/llvm/tools/clang/test/CodeGenCXX/tail-padding.cpp > -- > Exit Code: 1 > > Command Output (stderr): > -- > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/llvm/tools/clang/test/CodeGenCXX/tail-padding.cpp:8:47: > warning: static_assert with no message is a C++17 extension > static_assert(sizeof(C) == sizeof(void*) + 8); > ^ > , "" > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/llvm/tools/clang/test/CodeGenCXX/tail-padding.cpp:25:46: > warning: static_assert with no message is a C++17 extension > static_assert(sizeof(C) > sizeof(void*) + 8); > ^ > , "" > 2 warnings generated. > /home/buildslave/buildslave/clang-cmake-armv7-selfhost-neon/llvm/tools/clang/test/CodeGenCXX/tail-padding.cpp:12:12: > error: expected string not found in input > // CHECK: call void @_ZN8Implicit1AC2ERKS0_( > ^ > <stdin>:78:66: note: scanning from here > define linkonce_odr %"struct.Implicit::C"* > @_ZN8Implicit1CC1EOS0_(%"struct.Implicit::C"* returned %this, > %"struct.Implicit::C"* dereferenceable(12)) unnamed_addr #0 comdat align 2 { > ^ > <stdin>:97:28: note: possible intended match here > %call = call %"struct.Implicit::A"* > @_ZN8Implicit1AC2ERKS0_(%"struct.Implicit::A"* %3, %"struct.Implicit::A"* > dereferenceable(1) %8) > ^ > > -- > > ******************** > > Douglas Yung > > > -----Original Message----- > > From: cfe-commits [mailto:cfe-commits-boun...@lists.llvm.org] On Behalf > Of > > Richard Smith via cfe-commits > > Sent: Thursday, April 05, 2018 13:53 > > To: cfe-commits@lists.llvm.org > > Subject: r329342 - PR36992: do not store beyond the dsize of a class > object > > unless we know > > > > Author: rsmith > > Date: Thu Apr 5 13:52:58 2018 > > New Revision: 329342 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=329342&view=rev > > Log: > > 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 > > > > Added: > > cfe/trunk/test/CodeGenCXX/tail-padding.cpp > > Modified: > > cfe/trunk/lib/CodeGen/CGAtomic.cpp > > cfe/trunk/lib/CodeGen/CGBlocks.cpp > > cfe/trunk/lib/CodeGen/CGCall.cpp > > cfe/trunk/lib/CodeGen/CGClass.cpp > > cfe/trunk/lib/CodeGen/CGDecl.cpp > > cfe/trunk/lib/CodeGen/CGDeclCXX.cpp > > cfe/trunk/lib/CodeGen/CGExpr.cpp > > cfe/trunk/lib/CodeGen/CGExprAgg.cpp > > cfe/trunk/lib/CodeGen/CGExprCXX.cpp > > cfe/trunk/lib/CodeGen/CGObjC.cpp > > cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp > > cfe/trunk/lib/CodeGen/CGStmt.cpp > > cfe/trunk/lib/CodeGen/CGValue.h > > cfe/trunk/lib/CodeGen/CodeGenFunction.h > > cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > > > > Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=329342&r1=329341&r2=329342&view > > =diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGAtomic.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp Thu Apr 5 13:52:58 2018 > > @@ -1513,7 +1513,8 @@ void AtomicInfo::emitCopyIntoMemory(RVal > > getAtomicType()); > > bool IsVolatile = rvalue.isVolatileQualified() || > > LVal.isVolatileQualified(); > > - CGF.EmitAggregateCopy(Dest, Src, getAtomicType(), IsVolatile); > > + CGF.EmitAggregateCopy(Dest, Src, getAtomicType(), > > + AggValueSlot::DoesNotOverlap, IsVolatile); > > return; > > } > > > > @@ -2008,6 +2009,7 @@ void CodeGenFunction::EmitAtomicInit(Exp > > AggValueSlot::IsNotDestructed, > > > AggValueSlot::DoesNotNeedGCBarriers, > > AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap, > > Zeroed ? AggValueSlot::IsZeroed > : > > > AggValueSlot::IsNotZeroed); > > > > > > Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=329342&r1=329341&r2=329342&view > > =diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Apr 5 13:52:58 2018 > > @@ -929,7 +929,8 @@ llvm::Value *CodeGenFunction::EmitBlockL > > AggValueSlot::forAddr(blockField, Qualifiers(), > > AggValueSlot::IsDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap); > > EmitAggExpr(copyExpr, Slot); > > } else { > > EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr); > > > > Modified: cfe/trunk/lib/CodeGen/CGCall.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=329342&r1=329341&r2=329342&view=d > > iff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Apr 5 13:52:58 2018 > > @@ -3018,7 +3018,8 @@ static AggValueSlot createPlaceholderSlo > > Ty.getQualifiers(), > > AggValueSlot::IsNotDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap); > > } > > > > void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, @@ -3486,7 > > +3487,8 @@ RValue CallArg::getRValue(CodeGenFunctio > > if (!HasLV) > > return RV; > > LValue Copy = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty), Ty); > > - CGF.EmitAggregateCopy(Copy, LV, Ty, LV.isVolatile()); > > + CGF.EmitAggregateCopy(Copy, LV, Ty, AggValueSlot::DoesNotOverlap, > > + LV.isVolatile()); > > IsUsed = true; > > return RValue::getAggregate(Copy.getAddress()); > > } > > @@ -3500,7 +3502,8 @@ void CallArg::copyInto(CodeGenFunction & > > else { > > auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress(); > > LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty); > > - CGF.EmitAggregateCopy(Dst, SrcLV, Ty, > > + // We assume that call args are never copied into subobjects. > > + CGF.EmitAggregateCopy(Dst, SrcLV, Ty, AggValueSlot::DoesNotOverlap, > > HasLV ? LV.isVolatileQualified() > > : RV.isVolatileQualified()); > > } > > > > Modified: cfe/trunk/lib/CodeGen/CGClass.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=329342&r1=329341&r2=329342&view= > > diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Apr 5 13:52:58 2018 > > @@ -555,10 +555,12 @@ static void EmitBaseInitializer(CodeGenF > > 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(CodeGe > > 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::EmitInitializerFor > > 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::EmitCXXAggrConstru > > } > > > > 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::EmitCXXConstructor > > 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::EmitCXXConstructor > > 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::EmitCXXConstructor > > 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::EmitCXXConstructor > > 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::EmitCXXConstructor > > 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::EmitInheritedCXXCo > > } > > > > EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, > /*Delegating*/false, > > - This, Args); > > + This, Args, AggValueSlot::MayOverlap); > > } > > > > void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall( > > @@ -2267,7 +2276,8 @@ CodeGenFunction::EmitSynthesizedCXXCopyC > > 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::EmitDelegateCXXConstruc > > } > > > > EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false, > > - /*Delegating=*/true, This, DelegateArgs); > > + /*Delegating=*/true, This, DelegateArgs, > > + AggValueSlot::MayOverlap); > > } > > > > namespace { > > @@ -2333,7 +2344,8 @@ CodeGenFunction::EmitDelegatingCXXConstr > > AggValueSlot::forAddr(ThisPtr, Qualifiers(), > > AggValueSlot::IsDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::MayOverlap); > > > > EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); > > > > > > Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=329342&r1=329341&r2=329342&view=d > > iff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Apr 5 13:52:58 2018 > > @@ -1416,17 +1416,17 @@ void CodeGenFunction::EmitAutoVarInit(co > > } > > } > > > > -/// Emit an expression as an initializer for a variable at the given > -/// > > location. The expression is not necessarily the normal -/// initializer > for > > the variable, and the address is not necessarily > > +/// Emit an expression as an initializer for an object (variable, > > +field, etc.) /// at the given location. The expression is not > > +necessarily the normal /// initializer for the object, and the address > > +is not necessarily > > /// its normal location. > > /// > > /// \param init the initializing expression -/// \param var the > variable to > > act as if we're initializing > > +/// \param D the object to act as if we're initializing > > /// \param loc the address to initialize; its type is a pointer > > -/// to the LLVM mapping of the variable's type > > +/// to the LLVM mapping of the object's type > > /// \param alignment the alignment of the address -/// \param > capturedByInit > > true if the variable is a __block variable > > +/// \param capturedByInit true if \p D is a __block variable > > /// whose address is potentially changed by the initializer > > void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl > *D, > > LValue lvalue, bool > capturedByInit) { @@ > > -1454,11 +1454,17 @@ void CodeGenFunction::EmitExprAsInit(con > > if (type->isAtomicType()) { > > EmitAtomicInit(const_cast<Expr*>(init), lvalue); > > } else { > > + AggValueSlot::Overlap_t Overlap = AggValueSlot::MayOverlap; > > + if (isa<VarDecl>(D)) > > + Overlap = AggValueSlot::DoesNotOverlap; > > + else if (auto *FD = dyn_cast<FieldDecl>(D)) > > + Overlap = overlapForFieldInit(FD); > > // TODO: how can we delay here if D is captured by its > initializer? > > EmitAggExpr(init, AggValueSlot::forLValue(lvalue, > > > AggValueSlot::IsDestructed, > > > AggValueSlot::DoesNotNeedGCBarriers, > > - > AggValueSlot::IsNotAliased)); > > + > AggValueSlot::IsNotAliased, > > + Overlap)); > > } > > return; > > } > > > > Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=329342&r1=329341&r2=329342&vie > > w=diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Thu Apr 5 13:52:58 2018 > > @@ -53,7 +53,8 @@ static void EmitDeclInit(CodeGenFunction > > case TEK_Aggregate: > > CGF.EmitAggExpr(Init, > > AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, > > > > AggValueSlot::DoesNotNeedGCBarriers, > > - > > AggValueSlot::IsNotAliased)); > > + > AggValueSlot::IsNotAliased, > > + > > + AggValueSlot::DoesNotOverlap)); > > return; > > } > > llvm_unreachable("bad evaluation kind"); > > > > Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=329342&r1=329341&r2=329342&view=d > > iff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Apr 5 13:52:58 2018 > > @@ -214,7 +214,8 @@ void CodeGenFunction::EmitAnyExprToMem(c > > EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals, > > > > AggValueSlot::IsDestructed_t(IsInit), > > > AggValueSlot::DoesNotNeedGCBarriers, > > - > > AggValueSlot::IsAliased_t(!IsInit))); > > + > AggValueSlot::IsAliased_t(!IsInit), > > + AggValueSlot::MayOverlap)); > > return; > > } > > > > @@ -432,7 +433,8 @@ EmitMaterializeTemporaryExpr(const Mater > > E->getType().getQualifiers(), > > AggValueSlot::IsDestructed, > > > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased)); > > + AggValueSlot::IsNotAliased, > > + > > + AggValueSlot::DoesNotOverlap)); > > break; > > } > > } > > > > Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=329342&r1=329341&r2=329342&vie > > w=diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Apr 5 13:52:58 2018 > > @@ -337,7 +337,8 @@ void AggExprEmitter::EmitFinalDestCopy(Q > > > > AggValueSlot srcAgg = > > AggValueSlot::forLValue(src, AggValueSlot::IsDestructed, > > - needsGC(type), AggValueSlot::IsAliased); > > + needsGC(type), AggValueSlot::IsAliased, > > + AggValueSlot::MayOverlap); > > EmitCopy(type, Dest, srcAgg); > > } > > > > @@ -348,7 +349,7 @@ void AggExprEmitter::EmitFinalDestCopy(Q > > void AggExprEmitter::EmitCopy(QualType type, const AggValueSlot &dest, > > const AggValueSlot &src) { > > if (dest.requiresGCollection()) { > > - CharUnits sz = CGF.getContext().getTypeSizeInChars(type); > > + CharUnits sz = dest.getPreferredSize(CGF.getContext(), type); > > llvm::Value *size = llvm::ConstantInt::get(CGF.SizeTy, > sz.getQuantity()); > > CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, > > > dest.getAddress(), @@ - > > 362,7 +363,7 @@ void AggExprEmitter::EmitCopy(QualType t > > // the two sides. > > LValue DestLV = CGF.MakeAddrLValue(dest.getAddress(), type); > > LValue SrcLV = CGF.MakeAddrLValue(src.getAddress(), type); > > - CGF.EmitAggregateCopy(DestLV, SrcLV, type, > > + CGF.EmitAggregateCopy(DestLV, SrcLV, type, dest.mayOverlap(), > > dest.isVolatile() || src.isVolatile()); } > > > > @@ -759,6 +760,7 @@ void AggExprEmitter::VisitCastExpr(CastE > > > valueDest.isExternallyDestructed(), > > > valueDest.requiresGCollection(), > > > valueDest.isPotentiallyAliased(), > > + AggValueSlot::DoesNotOverlap, > > AggValueSlot::IsZeroed); > > } > > > > @@ -986,7 +988,8 @@ void AggExprEmitter::VisitBinAssign(cons > > EmitCopy(E->getLHS()->getType(), > > AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, > > needsGC(E->getLHS()->getType()), > > - AggValueSlot::IsAliased), > > + AggValueSlot::IsAliased, > > + AggValueSlot::MayOverlap), > > Dest); > > return; > > } > > @@ -1007,7 +1010,8 @@ void AggExprEmitter::VisitBinAssign(cons > > AggValueSlot LHSSlot = > > AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, > > needsGC(E->getLHS()->getType()), > > - AggValueSlot::IsAliased); > > + AggValueSlot::IsAliased, > > + AggValueSlot::MayOverlap); > > // A non-volatile aggregate destination might have volatile member. > > if (!LHSSlot.isVolatile() && > > CGF.hasVolatileMember(E->getLHS()->getType())) > > @@ -1185,6 +1189,7 @@ AggExprEmitter::EmitInitializationToLVal > > > AggValueSlot::IsDestructed, > > > AggValueSlot::DoesNotNeedGCBarriers, > > > AggValueSlot::IsNotAliased, > > + > > + AggValueSlot::MayOverlap, > > Dest.isZeroed())); > > return; > > case TEK_Scalar: > > @@ -1283,11 +1288,12 @@ void AggExprEmitter::VisitInitListExpr(I > > Address V = CGF.GetAddressOfDirectBaseInCompleteClass( > > Dest.getAddress(), CXXRD, BaseRD, > > /*isBaseVirtual*/ false); > > - AggValueSlot AggSlot = > > - AggValueSlot::forAddr(V, Qualifiers(), > > - AggValueSlot::IsDestructed, > > - AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot AggSlot = AggValueSlot::forAddr( > > + V, Qualifiers(), > > + AggValueSlot::IsDestructed, > > + AggValueSlot::DoesNotNeedGCBarriers, > > + AggValueSlot::IsNotAliased, > > + CGF.overlapForBaseInit(CXXRD, BaseRD, Base.isVirtual())); > > CGF.EmitAggExpr(E->getInit(curInitIndex++), AggSlot); > > > > if (QualType::DestructionKind dtorKind = @@ -1468,7 +1474,9 @@ > void > > AggExprEmitter::VisitArrayInitLoopE > > // If the subexpression is an ArrayInitLoopExpr, share its > cleanup. > > auto elementSlot = AggValueSlot::forLValue( > > elementLV, AggValueSlot::IsDestructed, > > - AggValueSlot::DoesNotNeedGCBarriers, > AggValueSlot::IsNotAliased); > > + AggValueSlot::DoesNotNeedGCBarriers, > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap); > > AggExprEmitter(CGF, elementSlot, false) > > .VisitArrayInitLoopExpr(InnerLoop, outerBegin); > > } else > > @@ -1584,7 +1592,7 @@ static void CheckAggExprForMemSetUse(Agg > > } > > > > // If the type is 16-bytes or smaller, prefer individual stores over > > memset. > > - CharUnits Size = CGF.getContext().getTypeSizeInChars(E->getType()); > > + CharUnits Size = Slot.getPreferredSize(CGF.getContext(), > > + E->getType()); > > if (Size <= CharUnits::fromQuantity(16)) > > return; > > > > @@ -1630,13 +1638,37 @@ LValue CodeGenFunction::EmitAggExprToLVa > > LValue LV = MakeAddrLValue(Temp, E->getType()); > > EmitAggExpr(E, AggValueSlot::forLValue(LV, > AggValueSlot::IsNotDestructed, > > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased)); > > + AggValueSlot::IsNotAliased, > > + > > + AggValueSlot::DoesNotOverlap)); > > return LV; > > } > > > > -void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, > > - QualType Ty, bool isVolatile, > > - bool isAssignment) { > > +AggValueSlot::Overlap_t CodeGenFunction::overlapForBaseInit( > > + const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool > > +IsVirtual) { > > + // Virtual bases are initialized first, in address order, so there's > > +never > > + // any overlap during their initialization. > > + // > > + // FIXME: Under P0840, this is no longer true: the tail padding of a > > +vbase > > + // of a field could be reused by a vbase of a containing class. > > + if (IsVirtual) > > + return AggValueSlot::DoesNotOverlap; > > + > > + // If the base class is laid out entirely within the nvsize of the > > + derived // class, its tail padding cannot yet be initialized, so we > > + can issue // stores at the full width of the base class. > > + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); > > + if (Layout.getBaseClassOffset(BaseRD) + > > + getContext().getASTRecordLayout(BaseRD).getSize() <= > > + Layout.getNonVirtualSize()) > > + return AggValueSlot::DoesNotOverlap; > > + > > + // The tail padding may contain values we need to preserve. > > + return AggValueSlot::MayOverlap; > > +} > > + > > +void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, > QualType Ty, > > + AggValueSlot::Overlap_t > MayOverlap, > > + bool isVolatile) { > > assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); > > > > Address DestPtr = Dest.getAddress(); > > @@ -1669,12 +1701,11 @@ void CodeGenFunction::EmitAggregateCopy( > > // implementation handles this case safely. If there is a libc that > does > > not > > // safely handle this, we can add a target hook. > > > > - // Get data size info for this aggregate. If this is an assignment, > > - // don't copy the tail padding, because we might be assigning into a > > - // base subobject where the tail padding is claimed. Otherwise, > > - // copying it is fine. > > + // Get data size info for this aggregate. Don't copy the tail padding > > + if this // might be a potentially-overlapping subobject, since the > > + tail padding might // be occupied by a different object. Otherwise, > copying > > it is fine. > > std::pair<CharUnits, CharUnits> TypeInfo; > > - if (isAssignment) > > + if (MayOverlap) > > TypeInfo = getContext().getTypeInfoDataSizeInChars(Ty); > > else > > TypeInfo = getContext().getTypeInfoInChars(Ty); > > @@ -1686,22 +1717,11 @@ void CodeGenFunction::EmitAggregateCopy( > > getContext().getAsArrayType(Ty))) { > > QualType BaseEltTy; > > SizeVal = emitArrayLength(VAT, BaseEltTy, DestPtr); > > - TypeInfo = getContext().getTypeInfoDataSizeInChars(BaseEltTy); > > - std::pair<CharUnits, CharUnits> LastElementTypeInfo; > > - if (!isAssignment) > > - LastElementTypeInfo = > getContext().getTypeInfoInChars(BaseEltTy); > > + TypeInfo = getContext().getTypeInfoInChars(BaseEltTy); > > assert(!TypeInfo.first.isZero()); > > SizeVal = Builder.CreateNUWMul( > > SizeVal, > > llvm::ConstantInt::get(SizeTy, TypeInfo.first.getQuantity())); > > - if (!isAssignment) { > > - SizeVal = Builder.CreateNUWSub( > > - SizeVal, > > - llvm::ConstantInt::get(SizeTy, > TypeInfo.first.getQuantity())); > > - SizeVal = Builder.CreateNUWAdd( > > - SizeVal, llvm::ConstantInt::get( > > - SizeTy, > LastElementTypeInfo.first.getQuantity())); > > - } > > } > > } > > if (!SizeVal) { > > > > Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=329342&r1=329341&r2=329342&vie > > w=diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Apr 5 13:52:58 2018 > > @@ -279,7 +279,10 @@ RValue CodeGenFunction::EmitCXXMemberOrO > > const Expr *Arg = *CE->arg_begin(); > > LValue RHS = EmitLValue(Arg); > > LValue Dest = MakeAddrLValue(This.getAddress(), Arg->getType()); > > - EmitAggregateCopy(Dest, RHS, Arg->getType()); > > + // This is the MSVC p->Ctor::Ctor(...) extension. We assume > that's > > + // constructing a new complete object of type Ctor. > > + EmitAggregateCopy(Dest, RHS, Arg->getType(), > > + AggValueSlot::DoesNotOverlap); > > return RValue::get(This.getPointer()); > > } > > llvm_unreachable("unknown trivial member function"); @@ -631,7 > +634,7 > > @@ CodeGenFunction::EmitCXXConstructExpr(co > > > > // Call the constructor. > > EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating, > > - Dest.getAddress(), E); > > + Dest.getAddress(), E, Dest.mayOverlap()); > > } > > } > > > > @@ -933,7 +936,8 @@ static llvm::Value *EmitCXXNewAllocSize( } > > > > static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr > *Init, > > - QualType AllocType, Address NewPtr) > { > > + QualType AllocType, Address NewPtr, > > + AggValueSlot::Overlap_t MayOverlap) > > + { > > // FIXME: Refactor with EmitExprAsInit. > > switch (CGF.getEvaluationKind(AllocType)) { > > case TEK_Scalar: > > @@ -949,7 +953,8 @@ static void StoreAnyExprIntoOneUnit(Code > > = AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(), > > AggValueSlot::IsDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot::IsNotAliased, > > + MayOverlap); > > CGF.EmitAggExpr(Init, Slot); > > return; > > } > > @@ -1018,7 +1023,8 @@ void CodeGenFunction::EmitNewArrayInitia > > AggValueSlot::forAddr(CurPtr, ElementType.getQualifiers(), > > AggValueSlot::IsDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap); > > EmitAggExpr(ILE->getInit(0), Slot); > > > > // Move past these elements. > > @@ -1083,7 +1089,8 @@ void CodeGenFunction::EmitNewArrayInitia > > // an array, and we have an array filler, we can fold together > the two > > // initialization loops. > > StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), > > - ILE->getInit(i)->getType(), CurPtr); > > + ILE->getInit(i)->getType(), CurPtr, > > + AggValueSlot::DoesNotOverlap); > > CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(), > > Builder.getSize(1), > > "array.exp.next"), @@ - > > 1236,7 +1243,8 @@ void CodeGenFunction::EmitNewArrayInitia > > } > > > > // Emit the initializer into this element. > > - StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr); > > + StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr, > > + AggValueSlot::DoesNotOverlap); > > > > // Leave the Cleanup if we entered one. > > if (CleanupDominator) { > > @@ -1267,7 +1275,8 @@ static void EmitNewInitializer(CodeGenFu > > CGF.EmitNewArrayInitializer(E, ElementType, ElementTy, NewPtr, > > NumElements, > > AllocSizeWithoutCookie); > > else if (const Expr *Init = E->getInitializer()) > > - StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr); > > + StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr, > > + AggValueSlot::DoesNotOverlap); > > } > > > > /// Emit a call to an operator new or operator delete function, as > implicitly > > > > Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=329342&r1=329341&r2=329342&view=d > > iff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Thu Apr 5 13:52:58 2018 > > @@ -1013,8 +1013,9 @@ CodeGenFunction::generateObjCGetterBody( > > // that's not necessarily the same as "on the stack", so > > // we still potentially need objc_memmove_collectable. > > EmitAggregateCopy(/* Dest= */ MakeAddrLValue(ReturnValue, > ivarType), > > - /* Src= */ LV, ivarType); > > - return; } > > + /* Src= */ LV, ivarType, > overlapForReturnValue()); > > + return; > > + } > > case TEK_Scalar: { > > llvm::Value *value; > > if (propType->isReferenceType()) { @@ -1439,7 +1440,8 @@ void > > CodeGenFunction::GenerateObjCCtorDt > > EmitAggExpr(IvarInit->getInit(), > > AggValueSlot::forLValue(LV, > AggValueSlot::IsDestructed, > > > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased)); > > + AggValueSlot::IsNotAliased, > > + > > + AggValueSlot::DoesNotOverlap)); > > } > > // constructor returns 'self'. > > CodeGenTypes &Types = CGM.getTypes(); @@ -3381,7 +3383,8 @@ > > CodeGenFunction::GenerateObjCAtomicGette > > Qualifiers(), > > AggValueSlot::IsDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased)); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap)); > > > > FinishFunction(); > > HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); > > > > Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=329342&r1=329341&r2=3293 > > 42&view=diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Apr 5 13:52:58 2018 > > @@ -4793,7 +4793,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFun > > CGF.getNaturalTypeAlignment(SharedsTy)); > > LValue Dest = CGF.MakeAddrLValue(KmpTaskSharedsPtr, SharedsTy); > > LValue Src = CGF.MakeAddrLValue(Shareds, SharedsTy); > > - CGF.EmitAggregateCopy(Dest, Src, SharedsTy); > > + CGF.EmitAggregateCopy(Dest, Src, SharedsTy, > > + AggValueSlot::DoesNotOverlap); > > } > > // Emit initial values for private copies (if any). > > TaskResultTy Result; > > > > Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=329342&r1=329341&r2=329342&view=d > > iff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original) > > +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Apr 5 13:52:58 2018 > > @@ -1007,7 +1007,7 @@ void CodeGenFunction::EmitReturnOfRValue > > } else if (RV.isAggregate()) { > > LValue Dest = MakeAddrLValue(ReturnValue, Ty); > > LValue Src = MakeAddrLValue(RV.getAggregateAddress(), Ty); > > - EmitAggregateCopy(Dest, Src, Ty); > > + EmitAggregateCopy(Dest, Src, Ty, overlapForReturnValue()); > > } else { > > EmitStoreOfComplex(RV.getComplexVal(), MakeAddrLValue(ReturnValue, > Ty), > > /*init*/ true); > > @@ -1085,11 +1085,12 @@ void CodeGenFunction::EmitReturnStmt(con > > /*isInit*/ true); > > break; > > case TEK_Aggregate: > > - EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, > > - Qualifiers(), > > - AggValueSlot::IsDestructed, > > - > > AggValueSlot::DoesNotNeedGCBarriers, > > - > AggValueSlot::IsNotAliased)); > > + EmitAggExpr(RV, AggValueSlot::forAddr( > > + ReturnValue, Qualifiers(), > > + AggValueSlot::IsDestructed, > > + AggValueSlot::DoesNotNeedGCBarriers, > > + AggValueSlot::IsNotAliased, > > + overlapForReturnValue())); > > break; > > } > > } > > > > Modified: cfe/trunk/lib/CodeGen/CGValue.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CGValue.h?rev=329342&r1=329341&r2=329342&view=di > > ff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CGValue.h (original) > > +++ cfe/trunk/lib/CodeGen/CGValue.h Thu Apr 5 13:52:58 2018 > > @@ -472,17 +472,25 @@ class AggValueSlot { > > /// evaluating an expression which constructs such an object. > > bool AliasedFlag : 1; > > > > + /// This is set to true if the tail padding of this slot might > > + overlap /// another object that may have already been initialized > > + (and whose /// value must be preserved by this initialization). If > > + so, we may only /// store up to the dsize of the type. Otherwise we > > + can widen stores to /// the size of the type. > > + bool OverlapFlag : 1; > > + > > public: > > enum IsAliased_t { IsNotAliased, IsAliased }; > > enum IsDestructed_t { IsNotDestructed, IsDestructed }; > > enum IsZeroed_t { IsNotZeroed, IsZeroed }; > > + enum Overlap_t { DoesNotOverlap, MayOverlap }; > > enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; > > > > /// ignored - Returns an aggregate value slot indicating that the > > /// aggregate value is being ignored. > > static AggValueSlot ignored() { > > return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed, > > - DoesNotNeedGCBarriers, IsNotAliased); > > + DoesNotNeedGCBarriers, IsNotAliased, > > + DoesNotOverlap); > > } > > > > /// forAddr - Make a slot for an aggregate value. > > @@ -500,6 +508,7 @@ public: > > IsDestructed_t isDestructed, > > NeedsGCBarriers_t needsGC, > > IsAliased_t isAliased, > > + Overlap_t mayOverlap, > > IsZeroed_t isZeroed = IsNotZeroed) { > > AggValueSlot AV; > > if (addr.isValid()) { > > @@ -514,6 +523,7 @@ public: > > AV.ObjCGCFlag = needsGC; > > AV.ZeroedFlag = isZeroed; > > AV.AliasedFlag = isAliased; > > + AV.OverlapFlag = mayOverlap; > > return AV; > > } > > > > @@ -521,9 +531,10 @@ public: > > IsDestructed_t isDestructed, > > NeedsGCBarriers_t needsGC, > > IsAliased_t isAliased, > > + Overlap_t mayOverlap, > > IsZeroed_t isZeroed = IsNotZeroed) { > > - return forAddr(LV.getAddress(), > > - LV.getQuals(), isDestructed, needsGC, isAliased, > > isZeroed); > > + return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, > needsGC, > > + isAliased, mayOverlap, isZeroed); > > } > > > > IsDestructed_t isExternallyDestructed() const { @@ -571,6 +582,10 @@ > > public: > > return IsAliased_t(AliasedFlag); > > } > > > > + Overlap_t mayOverlap() const { > > + return Overlap_t(OverlapFlag); > > + } > > + > > RValue asRValue() const { > > if (isIgnored()) { > > return RValue::getIgnored(); > > @@ -583,6 +598,14 @@ public: > > IsZeroed_t isZeroed() const { > > return IsZeroed_t(ZeroedFlag); > > } > > + > > + /// Get the preferred size to use when storing a value to this slot. > > + This /// is the type size unless that might overlap another object, > > + in which /// case it's the dsize. > > + CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const { > > + return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(Type).first > > + : Ctx.getTypeSizeInChars(Type); } > > }; > > > > } // end namespace CodeGen > > > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=329342&r1=329341&r2=329342 > > &view=diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) > > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Apr 5 13:52:58 2018 > > @@ -2061,7 +2061,8 @@ public: > > T.getQualifiers(), > > AggValueSlot::IsNotDestructed, > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap); > > } > > > > /// Emit a cast to void* in the appropriate address space. > > @@ -2118,28 +2119,52 @@ public: > > } > > return false; > > } > > - /// EmitAggregateCopy - Emit an aggregate assignment. > > - /// > > - /// The difference to EmitAggregateCopy is that tail padding is not > copied. > > - /// This is required for correctness when assigning non-POD > structures in > > C++. > > + > > + /// Determine whether a return value slot may overlap some other > object. > > + AggValueSlot::Overlap_t overlapForReturnValue() { > > + // FIXME: Assuming no overlap here breaks guaranteed copy elision > for > > base > > + // class subobjects. These cases may need to be revisited depending > on > > the > > + // resolution of the relevant core issue. > > + return AggValueSlot::DoesNotOverlap; } > > + > > + /// Determine whether a field initialization may overlap some other > object. > > + AggValueSlot::Overlap_t overlapForFieldInit(const FieldDecl *FD) { > > + // FIXME: These cases can result in overlap as a result of P0840R0's > > + // [[no_unique_address]] attribute. We can still infer NoOverlap in > the > > + // presence of that attribute if the field is within the nvsize of > its > > + // containing class, because non-virtual subobjects are initialized > in > > + // address order. > > + return AggValueSlot::DoesNotOverlap; } > > + > > + /// Determine whether a base class initialization may overlap some > > + other /// object. > > + AggValueSlot::Overlap_t overlapForBaseInit(const CXXRecordDecl *RD, > > + const CXXRecordDecl > *BaseRD, > > + bool IsVirtual); > > + > > + /// Emit an aggregate assignment. > > void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) { > > bool IsVolatile = hasVolatileMember(EltTy); > > - EmitAggregateCopy(Dest, Src, EltTy, IsVolatile, /* isAssignment= */ > > true); > > + EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, > > + IsVolatile); > > } > > > > - void EmitAggregateCopyCtor(LValue Dest, LValue Src) { > > - EmitAggregateCopy(Dest, Src, Src.getType(), > > - /* IsVolatile= */ false, /* IsAssignment= */ > false); > > + void EmitAggregateCopyCtor(LValue Dest, LValue Src, > > + AggValueSlot::Overlap_t MayOverlap) { > > + EmitAggregateCopy(Dest, Src, Src.getType(), MayOverlap); > > } > > > > /// EmitAggregateCopy - Emit an aggregate copy. > > /// > > - /// \param isVolatile - True iff either the source or the destination > is > > - /// volatile. > > - /// \param isAssignment - If false, allow padding to be copied. This > often > > - /// yields more efficient. > > + /// \param isVolatile \c true iff either the source or the > destination is > > + /// volatile. > > + /// \param MayOverlap Whether the tail padding of the destination > might be > > + /// occupied by some other object. More efficient code can > often be > > + /// generated if not. > > void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, > > - bool isVolatile = false, bool isAssignment = > false); > > + AggValueSlot::Overlap_t MayOverlap, > > + bool isVolatile = false); > > > > /// GetAddrOfLocalVar - Return the address of a local variable. > > Address GetAddrOfLocalVar(const VarDecl *VD) { @@ -2303,11 +2328,13 @@ > > public: > > > > void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType > Type, > > bool ForVirtualBase, bool Delegating, > > - Address This, const CXXConstructExpr *E); > > + Address This, const CXXConstructExpr *E, > > + AggValueSlot::Overlap_t Overlap); > > > > void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType > Type, > > bool ForVirtualBase, bool Delegating, > > - Address This, CallArgList &Args); > > + Address This, CallArgList &Args, > > + AggValueSlot::Overlap_t Overlap); > > > > /// Emit assumption load for all bases. Requires to be be called only > on > > /// most-derived class and not under construction of the object. > > > > Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > > URL: http://llvm.org/viewvc/llvm- > > > project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=329342&r1=329341&r2=329342 > > &view=diff > > > ============================================================================== > > --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) > > +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Apr 5 13:52:58 2018 > > @@ -3896,7 +3896,7 @@ static void InitCatchParam(CodeGenFuncti > > caughtExnAlignment); > > LValue Dest = CGF.MakeAddrLValue(ParamAddr, CatchType); > > LValue Src = CGF.MakeAddrLValue(adjustedExn, CatchType); > > - CGF.EmitAggregateCopy(Dest, Src, CatchType); > > + CGF.EmitAggregateCopy(Dest, Src, CatchType, > > + AggValueSlot::DoesNotOverlap); > > return; > > } > > > > @@ -3923,7 +3923,8 @@ static void InitCatchParam(CodeGenFuncti > > AggValueSlot::forAddr(ParamAddr, Qualifiers(), > > AggValueSlot::IsNotDestructed, > > > AggValueSlot::DoesNotNeedGCBarriers, > > - AggValueSlot::IsNotAliased)); > > + AggValueSlot::IsNotAliased, > > + AggValueSlot::DoesNotOverlap)); > > > > // Leave the terminate scope. > > CGF.EHStack.popTerminate(); > > > > Added: cfe/trunk/test/CodeGenCXX/tail-padding.cpp > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/tail- > > padding.cpp?rev=329342&view=auto > > > ============================================================================== > > --- cfe/trunk/test/CodeGenCXX/tail-padding.cpp (added) > > +++ cfe/trunk/test/CodeGenCXX/tail-padding.cpp Thu Apr 5 13:52:58 2018 > > @@ -0,0 +1,34 @@ > > +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | > > +FileCheck %s > > + > > +// PR36992 > > +namespace Implicit { > > + struct A { char c; A(const A&); }; > > + struct B { int n; char c[3]; ~B(); }; > > + struct C : B, virtual A {}; > > + static_assert(sizeof(C) == sizeof(void*) + 8); > > + C f(C c) { return c; } > > + > > + // CHECK: define {{.*}} @_ZN8Implicit1CC1EOS0_ > > + // CHECK: call void @_ZN8Implicit1AC2ERKS0_( > > + // Note: this must memcpy 7 bytes, not 8, to avoid trampling over the > > virtual base class. > > + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* > > +{{.*}}, i64 7, i1 false) > > + // CHECK: store i32 {{.*}} @_ZTVN8Implicit1CE } > > + > > +namespace InitWithinNVSize { > > + // This is the same as the previous test, except that the A base lies > > + // entirely within the nvsize of C. This makes it valid to copy at > > +the > > + // full width. > > + struct A { char c; A(const A&); }; > > + struct B { int n; char c[3]; ~B(); }; > > + struct C : B, virtual A { char x; }; > > + static_assert(sizeof(C) > sizeof(void*) + 8); > > + C f(C c) { return c; } > > + > > + // CHECK: define {{.*}} @_ZN16InitWithinNVSize1CC1EOS0_ > > + // CHECK: call void @_ZN16InitWithinNVSize1AC2ERKS0_( > > + // This copies over the 'C::x' member, but that's OK because we've not > > initialized it yet. > > + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* > > +{{.*}}, i64 8, i1 false) > > + // CHECK: store i32 {{.*}} @_ZTVN16InitWithinNVSize1CE > > + // CHECK: store i8 > > +} > > > > > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits@lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits