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