r329342 - PR36992: do not store beyond the dsize of a class object unless we know

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 6 13:09:44 PDT 2018


Hopefully r329449 will fix this.

On 6 April 2018 at 12:37, Richard Smith <richard at metafoo.co.uk> wrote:

> Thanks, I see the problem.
>
> On Fri, 6 Apr 2018, 11:56 via cfe-commits, <cfe-commits at 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-bounces at lists.llvm.org] On
>> Behalf Of
>> > Richard Smith via cfe-commits
>> > Sent: Thursday, April 05, 2018 13:53
>> > To: cfe-commits at 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 at lists.llvm.org
>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180406/a18c9d2a/attachment-0001.html>


More information about the cfe-commits mailing list