r245267 - Revert "Generating assumption loads of vptr after ctor call (fixed)"

Justin Bogner via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 17 23:58:02 PDT 2015


Yep, looks like two distinct problems. I'm going to revert r245265 as
well and send Piotr the crash repro for the second assertion.

Piotr Padlewski <prazek at google.com> writes:
> Confirm, the assertions are different from the last one.
>
> On Mon, Aug 17, 2015 at 11:45 PM, Justin Bogner via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>     Richard Smith <richard at metafoo.co.uk> writes:
>     > Are you sure it was this change and not r245265?
>    
>     Pretty sure - I ran the crash repro script with tot and it repro'd, then
>     with r245264 reverted and it didn't. That's when I pushed the revert.
>    
>     > On Aug 17, 2015 10:41 PM, "Justin Bogner via cfe-commits" <
>     > cfe-commits at lists.llvm.org> wrote:
>     >
>     >     Author: bogner
>     >     Date: Tue Aug 18 00:40:20 2015
>     >     New Revision: 245267
>     >
>     >     URL: http://llvm.org/viewvc/llvm-project?rev=245267&view=rev
>     >     Log:
>     >     Revert "Generating assumption loads of vptr after ctor call (fixed)"
>     >
>     >     Bootstrap bots were failing:
>     >
>     >     http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_build
>     /6382/
>     >     http://bb.pgr.jp/builders/clang-3stage-i686-linux/builds/2969
>     >
>     >     This reverts r245264.
>     >
>     >     Removed:
>     >         cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp
>     >     Modified:
>     >         cfe/trunk/lib/CodeGen/CGCXXABI.h
>     >         cfe/trunk/lib/CodeGen/CGCall.cpp
>     >         cfe/trunk/lib/CodeGen/CGClass.cpp
>     >         cfe/trunk/lib/CodeGen/CodeGenFunction.h
>     >         cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>     >         cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>     >         cfe/trunk/test/CodeGen/available-externally-hidden.cpp
>     >         cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp
>     >         cfe/trunk/test/CodeGenCXX/template-instantiation.cpp
>     >         cfe/trunk/test/CodeGenCXX/thunks.cpp
>     >         cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp
>     >         cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp
>     >
>     >     Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>     CGCXXABI.h?
>     >     rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
>     >     +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Aug 18 00:40:20 2015
>     >     @@ -346,25 +346,13 @@ public:
>     >        virtual void emitVTableDefinitions(CodeGenVTables &CGVT,
>     >                                           const CXXRecordDecl *RD) = 0;
>     >
>     >     -  /// Checks if ABI requires extra virtual offset for vtable field.
>     >     -  virtual bool
>     >     -  isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
>     >     -                                      CodeGenFunction::VPtr Vptr) =
>     0;
>     >     -
>     >     -  /// Checks if ABI requires to initilize vptrs for given dynamic
>     class.
>     >     -  virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl
>     >     *VTableClass) = 0;
>     >     -
>     >     -  /// Get the address point of the vtable for the given base
>     subobject.
>     >     -  virtual llvm::Constant *
>     >     -  getVTableAddressPoint(BaseSubobject Base,
>     >     -                        const CXXRecordDecl *VTableClass) = 0;
>     >     -
>     >        /// Get the address point of the vtable for the given base
>     subobject
>     >     while
>     >     -  /// building a constructor or a destructor.
>     >     -  virtual llvm::Value *
>     >     -  getVTableAddressPointInStructor(CodeGenFunction &CGF, const
>     >     CXXRecordDecl *RD,
>     >     -                                  BaseSubobject Base,
>     >     -                                  const CXXRecordDecl
>     *NearestVBase) = 0;
>     >     +  /// building a constructor or a destructor. On return,
>     >     NeedsVirtualOffset
>     >     +  /// tells if a virtual base adjustment is needed in order to get
>     the
>     >     offset
>     >     +  /// of the base subobject.
>     >     +  virtual llvm::Value *getVTableAddressPointInStructor(
>     >     +      CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject
>     Base,
>     >     +      const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset)
>     = 0;
>     >
>     >        /// Get the address point of the vtable for the given base
>     subobject
>     >     while
>     >        /// building a constexpr.
>     >
>     >     Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>     CGCall.cpp?
>     >     rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
>     >     +++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Aug 18 00:40:20 2015
>     >     @@ -1412,8 +1412,7 @@ void CodeGenModule::ConstructAttributeLi
>     >
>     >          if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>
>     (TargetDecl)) {
>     >            const FunctionProtoType *FPT = Fn->getType()->getAs
>     >     <FunctionProtoType>();
>     >     -      if (FPT && !isUnresolvedExceptionSpec(FPT->
>     getExceptionSpecType())
>     >     &&
>     >     -          FPT->isNothrow(getContext()))
>     >     +      if (FPT && FPT->isNothrow(getContext()))
>     >              FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
>     >            // Don't use [[noreturn]] or _Noreturn for a call to a
>     virtual
>     >     function.
>     >            // These attributes are not inherited by overloads.
>     >
>     >     Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>     >     CGClass.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
>     >     +++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Aug 18 00:40:20 2015
>     >     @@ -1806,14 +1806,12 @@ void CodeGenFunction::EmitCXXConstructor
>     >                                                   bool ForVirtualBase,
>     >                                                   bool Delegating,
>     llvm::Value
>     >     *This,
>     >                                                   const CXXConstructExpr
>     *E) {
>     >     -  const CXXRecordDecl *ClassDecl = D->getParent();
>     >     -
>     >        // C++11 [class.mfct.non-static]p2:
>     >        //   If a non-static member function of a class X is called for
>     an
>     >     object that
>     >        //   is not of type X, or of a type derived from X, the behavior
>     is
>     >     undefined.
>     >        // FIXME: Provide a source location here.
>     >        EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall,
>     SourceLocation(),
>     >     This,
>     >     -                getContext().getRecordType(ClassDecl));
>     >     +                getContext().getRecordType(D->getParent()));
>     >
>     >        if (D->isTrivial() && D->isDefaultConstructor()) {
>     >          assert(E->getNumArgs() == 0 && "trivial default ctor with
>     args");
>     >     @@ -1829,7 +1827,7 @@ void CodeGenFunction::EmitCXXConstructor
>     >          const Expr *Arg = E->getArg(0);
>     >          QualType SrcTy = Arg->getType();
>     >          llvm::Value *Src = EmitLValue(Arg).getAddress();
>     >     -    QualType DestTy = getContext().getTypeDeclType(ClassDecl);
>     >     +    QualType DestTy = getContext().getTypeDeclType(D->getParent());
>     >          EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);
>     >          return;
>     >        }
>     >     @@ -1852,41 +1850,6 @@ void CodeGenFunction::EmitCXXConstructor
>     >        const CGFunctionInfo &Info =
>     >            CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type,
>     ExtraArgs);
>     >        EmitCall(Info, Callee, ReturnValueSlot(), Args, D);
>     >     -
>     >     -  // Generate vtable assumptions if we're constructing a complete
>     object
>     >     -  // with a vtable.  We don't do this for base subobjects for two
>     >     reasons:
>     >     -  // first, it's incorrect for classes with virtual bases, and
>     second,
>     >     we're
>     >     -  // about to overwrite the vptrs anyway.
>     >     -  if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
>     >     -      ClassDecl->isDynamicClass() && Type != Ctor_Base)
>     >     -    EmitVTableAssumptionLoads(ClassDecl, This);
>     >     -}
>     >     -
>     >     -void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr,
>     >     -                                               llvm::Value *This) {
>     >     -  llvm::Value *VTableGlobal =
>     >     -      CGM.getCXXABI().getVTableAddressPoint(Vptr.Base,
>     Vptr.VTableClass);
>     >     -  if (!VTableGlobal)
>     >     -    return;
>     >     -
>     >     -  // We can just use the base offset in the complete class.
>     >     -  CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset();
>     >     -
>     >     -  if (!NonVirtualOffset.isZero())
>     >     -    This =
>     >     -        ApplyNonVirtualAndVirtualOffset(*this, This,
>     NonVirtualOffset,
>     >     nullptr);
>     >     -
>     >     -  llvm::Value *VPtrValue = GetVTablePtr(This, VTableGlobal->getType
>     ());
>     >     -  llvm::Value *Cmp =
>     >     -      Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables");
>     >     -  Builder.CreateAssumption(Cmp);
>     >     -}
>     >     -
>     >     -void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl
>     >     *ClassDecl,
>     >     -                                                llvm::Value *This)
>     {
>     >     -  if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
>     >     -    for (const VPtr &Vptr : getVTablePointers(ClassDecl))
>     >     -      EmitVTableAssumptionLoad(Vptr, This);
>     >      }
>     >
>     >      void
>     >     @@ -2054,12 +2017,24 @@ void CodeGenFunction::PushDestructorClea
>     >        PushDestructorCleanup(D, Addr);
>     >      }
>     >
>     >     -void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
>     >     +void
>     >     +CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,
>     >     +                                         const CXXRecordDecl
>     >     *NearestVBase,
>     >     +                                         CharUnits
>     >     OffsetFromNearestVBase,
>     >     +                                         const CXXRecordDecl
>     >     *VTableClass) {
>     >     +  const CXXRecordDecl *RD = Base.getBase();
>     >     +
>     >     +  // Don't initialize the vtable pointer if the class is marked
>     with the
>     >     +  // 'novtable' attribute.
>     >     +  if ((RD == VTableClass || RD == NearestVBase) &&
>     >     +      VTableClass->hasAttr<MSNoVTableAttr>())
>     >     +    return;
>     >     +
>     >        // Compute the address point.
>     >     +  bool NeedsVirtualOffset;
>     >        llvm::Value *VTableAddressPoint =
>     >            CGM.getCXXABI().getVTableAddressPointInStructor(
>     >     -          *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase);
>     >     -
>     >     +          *this, VTableClass, Base, NearestVBase,
>     NeedsVirtualOffset);
>     >        if (!VTableAddressPoint)
>     >          return;
>     >
>     >     @@ -2067,15 +2042,17 @@ void CodeGenFunction::InitializeVTablePo
>     >        llvm::Value *VirtualOffset = nullptr;
>     >        CharUnits NonVirtualOffset = CharUnits::Zero();
>     >
>     >     -  if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this,
>     Vptr)) {
>     >     +  if (NeedsVirtualOffset) {
>     >          // We need to use the virtual base offset offset because the
>     virtual
>     >     base
>     >          // might have a different offset in the most derived class.
>     >     -    VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
>     >     -        *this, LoadCXXThis(), Vptr.VTableClass, Vptr.NearestVBase);
>     >     -    NonVirtualOffset = Vptr.OffsetFromNearestVBase;
>     >     +    VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset
>     (*this,
>     >     +                                                             
>     LoadCXXThis
>     >     (),
>     >     +                                                             
>     >     VTableClass,
>     >     +                                                             
>     >     NearestVBase);
>     >     +    NonVirtualOffset = OffsetFromNearestVBase;
>     >        } else {
>     >          // We can just use the base offset in the complete class.
>     >     -    NonVirtualOffset = Vptr.Base.getBaseOffset();
>     >     +    NonVirtualOffset = Base.getBaseOffset();
>     >        }
>     >
>     >        // Apply the offsets.
>     >     @@ -2094,36 +2071,23 @@ void CodeGenFunction::InitializeVTablePo
>     >                ->getPointerTo();
>     >        VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->
>     >     getPointerTo());
>     >        VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint,
>     >     VTablePtrTy);
>     >     -
>     >        llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint,
>     >     VTableField);
>     >        CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr());
>     >      }
>     >
>     >     -CodeGenFunction::VPtrsVector
>     >     -CodeGenFunction::getVTablePointers(const CXXRecordDecl
>     *VTableClass) {
>     >     -  CodeGenFunction::VPtrsVector VPtrsResult;
>     >     -  VisitedVirtualBasesSetTy VBases;
>     >     -  getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()),
>     >     -                    /*NearestVBase=*/nullptr,
>     >     -                    /*OffsetFromNearestVBase=*/CharUnits::Zero(),
>     >     -                    /*BaseIsNonVirtualPrimaryBase=*/false,
>     VTableClass,
>     >     VBases,
>     >     -                    VPtrsResult);
>     >     -  return VPtrsResult;
>     >     -}
>     >     -
>     >     -void CodeGenFunction::getVTablePointers(BaseSubobject Base,
>     >     -                                        const CXXRecordDecl
>     >     *NearestVBase,
>     >     -                                        CharUnits
>     OffsetFromNearestVBase,
>     >     -                                        bool
>     BaseIsNonVirtualPrimaryBase,
>     >     -                                        const CXXRecordDecl
>     *VTableClass,
>     >     -                                        VisitedVirtualBasesSetTy &
>     VBases,
>     >     -                                        VPtrsVector &Vptrs) {
>     >     +void
>     >     +CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,
>     >     +                                          const CXXRecordDecl
>     >     *NearestVBase,
>     >     +                                          CharUnits
>     >     OffsetFromNearestVBase,
>     >     +                                          bool
>     >     BaseIsNonVirtualPrimaryBase,
>     >     +                                          const CXXRecordDecl
>     >     *VTableClass,
>     >     +                                          VisitedVirtualBasesSetTy&
>     >     VBases) {
>     >        // If this base is a non-virtual primary base the address point
>     has
>     >     already
>     >        // been set.
>     >        if (!BaseIsNonVirtualPrimaryBase) {
>     >          // Initialize the vtable pointer for this base.
>     >     -    VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase,
>     >     VTableClass};
>     >     -    Vptrs.push_back(Vptr);
>     >     +    InitializeVTablePointer(Base, NearestVBase,
>     OffsetFromNearestVBase,
>     >     +                            VTableClass);
>     >        }
>     >
>     >        const CXXRecordDecl *RD = Base.getBase();
>     >     @@ -2161,10 +2125,11 @@ void CodeGenFunction::getVTablePointers(
>     >            BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() ==
>     >     BaseDecl;
>     >          }
>     >
>     >     -    getVTablePointers(
>     >     -        BaseSubobject(BaseDecl, BaseOffset),
>     >     -        I.isVirtual() ? BaseDecl : NearestVBase,
>     >     BaseOffsetFromNearestVBase,
>     >     -        BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases,
>     Vptrs);
>     >     +    InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset),
>     >     +                             I.isVirtual() ? BaseDecl :
>     NearestVBase,
>     >     +                             BaseOffsetFromNearestVBase,
>     >     +                             BaseDeclIsNonVirtualPrimaryBase,
>     >     +                             VTableClass, VBases);
>     >        }
>     >      }
>     >
>     >     @@ -2174,9 +2139,11 @@ void CodeGenFunction::InitializeVTablePo
>     >          return;
>     >
>     >        // Initialize the vtable pointers for this class and all of its
>     bases.
>     >     -  if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
>     >     -    for (const VPtr &Vptr : getVTablePointers(RD))
>     >     -      InitializeVTablePointer(Vptr);
>     >     +  VisitedVirtualBasesSetTy VBases;
>     >     +  InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()),
>     >     +                           /*NearestVBase=*/nullptr,
>     >     +                           /*OffsetFromNearestVBase=*/
>     CharUnits::Zero(),
>     >     +                           /*BaseIsNonVirtualPrimaryBase=*/false,
>     RD,
>     >     VBases);
>     >
>     >        if (RD->getNumVBases())
>     >          CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers
>     (*this, RD);
>     >
>     >     Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>     >     CodeGenFunction.h?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
>     >     +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Aug 18 00:40:20 2015
>     >     @@ -1309,27 +1309,21 @@ public:
>     >        void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr
>     *Init,
>     >                                     ArrayRef<VarDecl *> ArrayIndexes);
>     >
>     >     -  /// Struct with all informations about dynamic [sub]class needed
>     to set
>     >     vptr.
>     >     -  struct VPtr {
>     >     -    BaseSubobject Base;
>     >     -    const CXXRecordDecl *NearestVBase;
>     >     -    CharUnits OffsetFromNearestVBase;
>     >     -    const CXXRecordDecl *VTableClass;
>     >     -  };
>     >     -
>     >     -  /// Initialize the vtable pointer of the given subobject.
>     >     -  void InitializeVTablePointer(const VPtr &vptr);
>     >     -
>     >     -  typedef llvm::SmallVector<VPtr, 4> VPtrsVector;
>     >     +  /// InitializeVTablePointer - Initialize the vtable pointer of
>     the
>     >     given
>     >     +  /// subobject.
>     >     +  ///
>     >     +  void InitializeVTablePointer(BaseSubobject Base,
>     >     +                               const CXXRecordDecl *NearestVBase,
>     >     +                               CharUnits OffsetFromNearestVBase,
>     >     +                               const CXXRecordDecl *VTableClass);
>     >
>     >        typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4>
>     >     VisitedVirtualBasesSetTy;
>     >     -  VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass);
>     >     -
>     >     -  void getVTablePointers(BaseSubobject Base, const CXXRecordDecl
>     >     *NearestVBase,
>     >     -                         CharUnits OffsetFromNearestVBase,
>     >     -                         bool BaseIsNonVirtualPrimaryBase,
>     >     -                         const CXXRecordDecl *VTableClass,
>     >     -                         VisitedVirtualBasesSetTy &VBases,
>     VPtrsVector &
>     >     vptrs);
>     >     +  void InitializeVTablePointers(BaseSubobject Base,
>     >     +                                const CXXRecordDecl *NearestVBase,
>     >     +                                CharUnits OffsetFromNearestVBase,
>     >     +                                bool BaseIsNonVirtualPrimaryBase,
>     >     +                                const CXXRecordDecl *VTableClass,
>     >     +                                VisitedVirtualBasesSetTy& VBases);
>     >
>     >        void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
>     >
>     >     @@ -1758,19 +1752,10 @@ public:
>     >        // they are substantially the same.
>     >        void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl
>     *Ctor,
>     >                                              const FunctionArgList &
>     Args);
>     >     -
>     >        void EmitCXXConstructorCall(const CXXConstructorDecl *D,
>     CXXCtorType
>     >     Type,
>     >                                    bool ForVirtualBase, bool Delegating,
>     >                                    llvm::Value *This, const
>     CXXConstructExpr
>     >     *E);
>     >
>     >     -  /// Emit assumption load for all bases. Requires to be be called
>     only
>     >     on
>     >     -  /// most-derived class and not under construction of the object.
>     >     -  void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl,
>     >     -                                 llvm::Value *This);
>     >     -
>     >     -  /// Emit assumption that vptr load == global vtable.
>     >     -  void EmitVTableAssumptionLoad(const VPtr &vptr, llvm::Value
>     *This);
>     >     -
>     >        void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
>     >                                    llvm::Value *This, llvm::Value *Src,
>     >                                    const CXXConstructExpr *E);
>     >
>     >     Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>     >     ItaniumCXXABI.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
>     >     +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Aug 18 00:40:20 2015
>     >     @@ -190,24 +190,10 @@ public:
>     >        void emitVTableDefinitions(CodeGenVTables &CGVT,
>     >                                   const CXXRecordDecl *RD) override;
>     >
>     >     -  bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
>     >     -                                           CodeGenFunction::VPtr
>     Vptr)
>     >     override;
>     >     -
>     >     -  bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)
>     >     override {
>     >     -    return true;
>     >     -  }
>     >     -
>     >     -  llvm::Constant *
>     >     -  getVTableAddressPoint(BaseSubobject Base,
>     >     -                        const CXXRecordDecl *VTableClass) override;
>     >     -
>     >        llvm::Value *getVTableAddressPointInStructor(
>     >            CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
>     >     -      BaseSubobject Base, const CXXRecordDecl *NearestVBase)
>     override;
>     >     -
>     >     -  llvm::Value *getVTableAddressPointInStructorWithVTT(
>     >     -      CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
>     >     -      BaseSubobject Base, const CXXRecordDecl *NearestVBase);
>     >     +      BaseSubobject Base, const CXXRecordDecl *NearestVBase,
>     >     +      bool &NeedsVirtualOffset) override;
>     >
>     >        llvm::Constant *
>     >        getVTableAddressPointForConstExpr(BaseSubobject Base,
>     >     @@ -1390,29 +1376,41 @@ void ItaniumCXXABI::emitVTableDefinition
>     >        CGM.EmitVTableBitSetEntries(VTable, VTLayout);
>     >      }
>     >
>     >     -bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
>     >     -    CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
>     >     -  if (Vptr.NearestVBase == nullptr)
>     >     -    return false;
>     >     -  return NeedsVTTParameter(CGF.CurGD);
>     >     -}
>     >     -
>     >      llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
>     >          CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
>     BaseSubobject
>     >     Base,
>     >     -    const CXXRecordDecl *NearestVBase) {
>     >     +    const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {
>     >     +  bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter
>     (CGF.CurGD);
>     >     +  NeedsVirtualOffset = (NeedsVTTParam && NearestVBase);
>     >     +
>     >     +  llvm::Value *VTableAddressPoint;
>     >     +  if (NeedsVTTParam && (Base.getBase()->getNumVBases() ||
>     NearestVBase))
>     >     {
>     >     +    // Get the secondary vpointer index.
>     >     +    uint64_t VirtualPointerIndex =
>     >     +        CGM.getVTables().getSecondaryVirtualPointerIndex
>     (VTableClass,
>     >     Base);
>     >     +
>     >     +    /// Load the VTT.
>     >     +    llvm::Value *VTT = CGF.LoadCXXVTT();
>     >     +    if (VirtualPointerIndex)
>     >     +      VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT,
>     >     VirtualPointerIndex);
>     >
>     >     -  if ((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &
>     &
>     >     -      NeedsVTTParameter(CGF.CurGD)) {
>     >     -    return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
>     Base,
>     >     -                                                  NearestVBase);
>     >     +    // And load the address point from the VTT.
>     >     +    VTableAddressPoint = CGF.Builder.CreateLoad(VTT);
>     >     +  } else {
>     >     +    llvm::Constant *VTable =
>     >     +        CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits());
>     >     +    uint64_t AddressPoint = CGM.getItaniumVTableContext()
>     >     +                                .getVTableLayout(VTableClass)
>     >     +                                .getAddressPoint(Base);
>     >     +    VTableAddressPoint =
>     >     +        CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0,
>     AddressPoint);
>     >        }
>     >     -  return getVTableAddressPoint(Base, VTableClass);
>     >     +
>     >     +  return VTableAddressPoint;
>     >      }
>     >
>     >     -llvm::Constant *
>     >     -ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
>     >     -                                     const CXXRecordDecl
>     *VTableClass) {
>     >     -  llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
>     CharUnits());
>     >     +llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
>     >     +    BaseSubobject Base, const CXXRecordDecl *VTableClass) {
>     >     +  auto *VTable = getAddrOfVTable(VTableClass, CharUnits());
>     >
>     >        // Find the appropriate vtable within the vtable group.
>     >        uint64_t AddressPoint = CGM.getItaniumVTableContext()
>     >     @@ -1427,30 +1425,6 @@ ItaniumCXXABI::getVTableAddressPoint(Bas
>     >                                                            VTable,
>     Indices);
>     >      }
>     >
>     >     -llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
>     >     -    CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
>     BaseSubobject
>     >     Base,
>     >     -    const CXXRecordDecl *NearestVBase) {
>     >     -  assert((Base.getBase()->getNumVBases() || NearestVBase !=
>     nullptr) &&
>     >     -         NeedsVTTParameter(CGF.CurGD) && "This class doesn't have
>     VTT");
>     >     -
>     >     -  // Get the secondary vpointer index.
>     >     -  uint64_t VirtualPointerIndex =
>     >     -      CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
>     >     Base);
>     >     -
>     >     -  /// Load the VTT.
>     >     -  llvm::Value *VTT = CGF.LoadCXXVTT();
>     >     -  if (VirtualPointerIndex)
>     >     -    VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT,
>     >     VirtualPointerIndex);
>     >     -
>     >     -  // And load the address point from the VTT.
>     >     -  return CGF.Builder.CreateLoad(VTT);
>     >     -}
>     >     -
>     >     -llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
>     >     -    BaseSubobject Base, const CXXRecordDecl *VTableClass) {
>     >     -  return getVTableAddressPoint(Base, VTableClass);
>     >     -}
>     >     -
>     >      llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const
>     CXXRecordDecl
>     >     *RD,
>     >                                                           CharUnits
>     >     VPtrOffset) {
>     >        assert(VPtrOffset.isZero() && "Itanium ABI only supports zero
>     vptr
>     >     offsets");
>     >
>     >     Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
>     >     MicrosoftCXXABI.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
>     >     +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Aug 18 00:40:20
>     2015
>     >     @@ -215,22 +215,10 @@ public:
>     >        void emitVTableDefinitions(CodeGenVTables &CGVT,
>     >                                   const CXXRecordDecl *RD) override;
>     >
>     >     -  bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
>     >     -                                           CodeGenFunction::VPtr
>     Vptr)
>     >     override;
>     >     -
>     >     -  /// Don't initialize vptrs if dynamic class
>     >     -  /// is marked with with the 'novtable' attribute.
>     >     -  bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)
>     >     override {
>     >     -    return !VTableClass->hasAttr<MSNoVTableAttr>();
>     >     -  }
>     >     -
>     >     -  llvm::Constant *
>     >     -  getVTableAddressPoint(BaseSubobject Base,
>     >     -                        const CXXRecordDecl *VTableClass) override;
>     >     -
>     >        llvm::Value *getVTableAddressPointInStructor(
>     >            CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
>     >     -      BaseSubobject Base, const CXXRecordDecl *NearestVBase)
>     override;
>     >     +      BaseSubobject Base, const CXXRecordDecl *NearestVBase,
>     >     +      bool &NeedsVirtualOffset) override;
>     >
>     >        llvm::Constant *
>     >        getVTableAddressPointForConstExpr(BaseSubobject Base,
>     >     @@ -1580,15 +1568,14 @@ void MicrosoftCXXABI::emitVTableDefiniti
>     >        }
>     >      }
>     >
>     >     -bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
>     >     -    CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
>     >     -  return Vptr.NearestVBase != nullptr;
>     >     -}
>     >     -
>     >      llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
>     >          CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
>     BaseSubobject
>     >     Base,
>     >     -    const CXXRecordDecl *NearestVBase) {
>     >     -  llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base,
>     >     VTableClass);
>     >     +    const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {
>     >     +  NeedsVirtualOffset = (NearestVBase != nullptr);
>     >     +
>     >     +  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
>     >     +  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
>     >     +  llvm::GlobalValue *VTableAddressPoint = VFTablesMap[ID];
>     >        if (!VTableAddressPoint) {
>     >          assert(Base.getBase()->getNumVBases() &&
>     >                 !getContext().getASTRecordLayout(Base.getBase
>     ()).hasOwnVFPtr
>     >     ());
>     >     @@ -1603,17 +1590,11 @@ static void mangleVFTableName(MicrosoftM
>     >        MangleContext.mangleCXXVFTable(RD, VFPtr->MangledPath, Out);
>     >      }
>     >
>     >     -llvm::Constant *
>     >     -MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
>     >     -                                       const CXXRecordDecl
>     *VTableClass)
>     >     {
>     >     -  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
>     >     -  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
>     >     -  return VFTablesMap[ID];
>     >     -}
>     >     -
>     >      llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
>     >          BaseSubobject Base, const CXXRecordDecl *VTableClass) {
>     >     -  llvm::Constant *VFTable = getVTableAddressPoint(Base,
>     VTableClass);
>     >     +  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
>     >     +  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
>     >     +  llvm::GlobalValue *VFTable = VFTablesMap[ID];
>     >        assert(VFTable && "Couldn't find a vftable for the given base?");
>     >        return VFTable;
>     >      }
>     >     @@ -1623,7 +1604,6 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
>     >        // getAddrOfVTable may return 0 if asked to get an address of a
>     vtable
>     >     which
>     >        // shouldn't be used in the given record type. We want to cache
>     this
>     >     result in
>     >        // VFTablesMap, thus a simple zero check is not sufficient.
>     >     -
>     >        VFTableIdTy ID(RD, VPtrOffset);
>     >        VTablesMapTy::iterator I;
>     >        bool Inserted;
>     >     @@ -1677,11 +1657,10 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
>     >        if (llvm::GlobalValue *VFTable =
>     >                CGM.getModule().getNamedGlobal(VFTableName)) {
>     >          VFTablesMap[ID] = VFTable;
>     >     -    VTable = VTableAliasIsRequred
>     >     -                 ? cast<llvm::GlobalVariable>(
>     >     -                       cast<llvm::GlobalAlias>(VFTable)->
>     getBaseObject())
>     >     -                 : cast<llvm::GlobalVariable>(VFTable);
>     >     -    return VTable;
>     >     +    return VTableAliasIsRequred
>     >     +               ? cast<llvm::GlobalVariable>(
>     >     +                     cast<llvm::GlobalAlias>(VFTable)->
>     getBaseObject())
>     >     +               : cast<llvm::GlobalVariable>(VFTable);
>     >        }
>     >
>     >        uint64_t NumVTableSlots =
>     >
>     >     Modified: cfe/trunk/test/CodeGen/available-externally-hidden.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/
>     >     available-externally-hidden.cpp?rev=245267&r1=245266&r2=245267&view=
>     diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGen/available-externally-hidden.cpp
>     (original)
>     >     +++ cfe/trunk/test/CodeGen/available-externally-hidden.cpp Tue Aug
>     18
>     >     00:40:20 2015
>     >     @@ -27,6 +27,6 @@ class TestSyncMessageFilter : public Syn
>     >      };
>     >
>     >      int main() {
>     >     -  TestSyncMessageFilter *f = new TestSyncMessageFilter;
>     >     +TestSyncMessageFilter*  f = new TestSyncMessageFilter;
>     >        f->Send(new Message);
>     >      }
>     >
>     >     Modified: cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/
>     >     ctor-globalopt.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp (original)
>     >     +++ cfe/trunk/test/CodeGenCXX/ctor-globalopt.cpp Tue Aug 18 00:40:20
>     2015
>     >     @@ -1,7 +1,7 @@
>     >      // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s |
>     >     FileCheck %s
>     >     -// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s
>     -O2 |
>     >     opt - -S -globalopt -o - | FileCheck %s --check-prefix=O1
>     >     +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s
>     -O1 |
>     >     FileCheck %s --check-prefix=O1
>     >      // RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s |
>     FileCheck
>     >     %s
>     >     -// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s -O2 |
>     opt -
>     >     -S -globalopt -o - | FileCheck %s --check-prefix=O1
>     >     +// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s -O1 |
>     >     FileCheck %s --check-prefix=O1
>     >
>     >      // Check that GlobalOpt can eliminate static constructors for
>     simple
>     >     implicit
>     >      // constructors. This is a targetted integration test to make sure
>     that
>     >     LLVM's
>     >
>     >     Modified: cfe/trunk/test/CodeGenCXX/template-instantiation.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/
>     >     template-instantiation.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGenCXX/template-instantiation.cpp (original)
>     >     +++ cfe/trunk/test/CodeGenCXX/template-instantiation.cpp Tue Aug 18
>     >     00:40:20 2015
>     >     @@ -1,7 +1,5 @@
>     >      // RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=
>     >     x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
>     >
>     >     -// CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE =
>     linkonce_odr
>     >     unnamed_addr constant
>     >     -
>     >      // CHECK: @_ZN7PR100011xE = global
>     >      // CHECK-NOT: @_ZN7PR100014kBarE = external global i32
>     >      //
>     >     @@ -14,6 +12,7 @@
>     >      // CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
>     >      // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x
>     i32]A
>     >
>     >     +// CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE =
>     linkonce_odr
>     >     unnamed_addr constant
>     >
>     >      // CHECK-NOT: _ZTVN5test31SIiEE
>     >      // CHECK-NOT: _ZTSN5test31SIiEE
>     >
>     >     Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/
>     >     thunks.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)
>     >     +++ cfe/trunk/test/CodeGenCXX/thunks.cpp Tue Aug 18 00:40:20 2015
>     >     @@ -1,9 +1,5 @@
>     >     -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables
>     >     -emit-llvm -o %t
>     >     -// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables
>     >     -emit-llvm -o %t.opt -O1 -disable-llvm-optzns
>     >     -// RUN: FileCheck %s < %t
>     >     -// RUN: FileCheck %s < %t.opt
>     >     -// RUN: FileCheck --check-prefix=CHECK-NONOPT %s < %t
>     >     -// RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
>     >     +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables
>     >     -emit-llvm -o - | FileCheck %s
>     >     +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables
>     >     -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s
>     >
>     >      namespace Test1 {
>     >
>     >     @@ -384,25 +380,13 @@ D::~D() {}
>     >
>     >      /**** The following has to go at the end of the file ****/
>     >
>     >     -// checking without opt
>     >     -// CHECK-NONOPT-LABEL: define internal void
>     >     @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(
>     >     -// CHECK-NONOPT-NOT: comdat
>     >     -
>     >      // This is from Test5:
>     >     -// CHECK-NONOPT-LABEL: define linkonce_odr void
>     @_ZTv0_n24_N5Test51B1fEv
>     >     -
>     >     -// This is from Test10:
>     >     -// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
>     >     -// CHECK-NONOPT-LABEL: define linkonce_odr void
>     @_ZThn8_N6Test101C3fooEv
>     >     -
>     >     -// Checking with opt
>     >     -// CHECK-OPT-LABEL: define internal void
>     >     @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous
>     >     namespace)::C"* %this) unnamed_addr #0 align 2
>     >     +// CHECK-LABEL: define internal void
>     @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv
>     >     (
>     >     +// CHECK-NOT: comdat
>     >     +// CHECK-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
>     >
>     >      // This is from Test10:
>     >     -// CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
>     >     -// CHECK-OPT-LABEL: define linkonce_odr void
>     @_ZThn8_N6Test101C3fooEv
>     >     -
>     >     -// This is from Test5:
>     >     -// CHECK-OPT-LABEL: define linkonce_odr void
>     @_ZTv0_n24_N5Test51B1fEv
>     >     +// CHECK-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
>     >     +// CHECK-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
>     >
>     >      // CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} }
>     >
>     >     Modified: cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/
>     >     virtual-base-ctor.cpp?rev=245267&r1=245266&r2=245267&view=diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp (original)
>     >     +++ cfe/trunk/test/CodeGenCXX/virtual-base-ctor.cpp Tue Aug 18
>     00:40:20
>     >     2015
>     >     @@ -1,4 +1,4 @@
>     >     -// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o -
>     -O2 |
>     >     opt - -S -globalopt -o - | FileCheck %s
>     >     +// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o -
>     -O2 |
>     >     FileCheck %s
>     >
>     >      struct B;
>     >      extern B x;
>     >
>     >     Removed: cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/
>     >     vtable-assume-load.cpp?rev=245266&view=auto
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp (original)
>     >     +++ cfe/trunk/test/CodeGenCXX/vtable-assume-load.cpp (removed)
>     >     @@ -1,172 +0,0 @@
>     >     -// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o
>     %t.ll
>     >     -O1 -disable-llvm-optzns -fms-extensions
>     >     -// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll
>     -O1
>     >     -disable-llvm-optzns -fms-extensions
>     >     -
>     >     -// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
>     >     -// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
>     >     -// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
>     >     -// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
>     >     -// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
>     >     -
>     >     -namespace test1 {
>     >     -
>     >     -struct A {
>     >     -  A();
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -struct B : A {
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -void g(A *a) { a->foo(); }
>     >     -
>     >     -// CHECK1-LABEL: define void @_ZN5test14fooAEv()
>     >     -// CHECK1: call void @_ZN5test11AC1Ev(%"struct.test1::A"*
>     >     -// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
>     >     -// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr
>     inbounds
>     >     ([3 x i8*], [3 x i8*]* @_ZTVN5test11AE, i64 0, i64 2)
>     >     -// CHECK1: call void @llvm.assume(i1 %[[CMP]])
>     >     -// CHECK1-LABEL: }
>     >     -
>     >     -void fooA() {
>     >     -  A a;
>     >     -  g(&a);
>     >     -}
>     >     -
>     >     -// CHECK1-LABEL: define void @_ZN5test14fooBEv()
>     >     -// CHECK1: call void @_ZN5test11BC1Ev(%"struct.test1::B"* %{{.*}})
>     >     -// CHECK1: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
>     >     -// CHECK1: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr
>     inbounds
>     >     ([3 x i8*], [3 x i8*]* @_ZTVN5test11BE, i64 0, i64 2)
>     >     -// CHECK1: call void @llvm.assume(i1 %[[CMP]])
>     >     -// CHECK1-LABEL: }
>     >     -
>     >     -void fooB() {
>     >     -  B b;
>     >     -  g(&b);
>     >     -}
>     >     -// there should not be any assumes in the ctor that calls base ctor
>     >     -// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev
>     >     (%"struct.test1::B"*
>     >     -// CHECK1-NOT: @llvm.assume(
>     >     -// CHECK1-LABEL: }
>     >     -}
>     >     -namespace test2 {
>     >     -struct A {
>     >     -  A();
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -struct B {
>     >     -  B();
>     >     -  virtual void bar();
>     >     -};
>     >     -
>     >     -struct C : A, B {
>     >     -  C();
>     >     -  virtual void foo();
>     >     -};
>     >     -void g(A *a) { a->foo(); }
>     >     -void h(B *b) { b->bar(); }
>     >     -
>     >     -// CHECK2-LABEL: define void @_ZN5test24testEv()
>     >     -// CHECK2: call void @_ZN5test21CC1Ev(%"struct.test2::C"*
>     >     -// CHECK2: %[[VTABLE:.*]] = load i8**, i8*** {{.*}}
>     >     -// CHECK2: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr
>     inbounds
>     >     ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 2)
>     >     -// CHECK2: call void @llvm.assume(i1 %[[CMP]])
>     >     -
>     >     -// CHECK2: %[[V2:.*]] = bitcast %"struct.test2::C"* %{{.*}} to i8*
>     >     -// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, i8* %
>     [[V2]], i64
>     >     8
>     >     -// CHECK2: %[[V3:.*]] = bitcast i8* %[[ADD_PTR]] to i8***
>     >     -// CHECK2: %[[VTABLE2:.*]] = load i8**, i8*** %[[V3]]
>     >     -// CHECK2: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr
>     >     inbounds ([6 x i8*], [6 x i8*]* @_ZTVN5test21CE, i64 0, i64 5)
>     >     -// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
>     >     -
>     >     -// CHECK2: call void @_ZN5test21gEPNS_1AE(
>     >     -// CHECK2-LABEL: }
>     >     -
>     >     -void test() {
>     >     -  C c;
>     >     -  g(&c);
>     >     -  h(&c);
>     >     -}
>     >     -}
>     >     -
>     >     -namespace test3 {
>     >     -struct A {
>     >     -  A();
>     >     -};
>     >     -
>     >     -struct B : A {
>     >     -  B();
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -struct C : virtual A, B {
>     >     -  C();
>     >     -  virtual void foo();
>     >     -};
>     >     -void g(B *a) { a->foo(); }
>     >     -
>     >     -// CHECK3-LABEL: define void @_ZN5test34testEv()
>     >     -// CHECK3: call void @_ZN5test31CC1Ev(%"struct.test3::C"*
>     >     -// CHECK3: %[[CMP:.*]] = icmp eq i8** %{{.*}}, getelementptr
>     inbounds ([4
>     >     x i8*], [4 x i8*]* @_ZTVN5test31CE, i64 0, i64 3)
>     >     -// CHECK3: call void @llvm.assume(i1 %[[CMP]])
>     >     -// CHECK3-LABLEL: }
>     >     -void test() {
>     >     -  C c;
>     >     -  g(&c);
>     >     -}
>     >     -} // test3
>     >     -
>     >     -namespace test4 {
>     >     -struct A {
>     >     -  A();
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -struct B : virtual A {
>     >     -  B();
>     >     -  virtual void foo();
>     >     -};
>     >     -struct C : B {
>     >     -  C();
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -void g(C *c) { c->foo(); }
>     >     -
>     >     -// CHECK4-LABEL: define void @_ZN5test44testEv()
>     >     -// CHECK4: call void @_ZN5test41CC1Ev(%"struct.test4::C"*
>     >     -// CHECK4: %[[VTABLE:.*]] = load i8**, i8*** %{{.*}}
>     >     -// CHECK4: %[[CMP:.*]] = icmp eq i8** %[[VTABLE]], getelementptr
>     inbounds
>     >     ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)
>     >     -// CHECK4: call void @llvm.assume(i1 %[[CMP]]
>     >     -
>     >     -// CHECK4: %[[VTABLE2:.*]] = load i8**, i8*** %{{.*}}
>     >     -// CHECK4: %[[CMP2:.*]] = icmp eq i8** %[[VTABLE2]], getelementptr
>     >     inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5test41CE, i64 0, i64 4)
>     >     -// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
>     >     -// CHECK4-LABEL: }
>     >     -
>     >     -void test() {
>     >     -  C c;
>     >     -  g(&c);
>     >     -}
>     >     -} // test4
>     >     -
>     >     -namespace test5 {
>     >     -
>     >     -struct __declspec(novtable) S {
>     >     -  virtual void foo();
>     >     -};
>     >     -
>     >     -void g(S &s) { s.foo(); }
>     >     -
>     >     -// if struct has novtable specifier, then we can't generate assumes
>     >     -// CHECK-MS-LABEL: define void @"\01?test at test5@@YAXXZ"()
>     >     -// CHECK-MS: call x86_thiscallcc %"struct.test5::S"* @"\01??
>     >     0S at test5@@QAE at XZ"(
>     >     -// CHECK-MS-NOT: @llvm.assume
>     >     -// CHECK-MS-LABEL: }
>     >     -
>     >     -void test() {
>     >     -  S s;
>     >     -  g(s);
>     >     -}
>     >     -
>     >     -} // test5
>     >
>     >     Modified: cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp
>     >     URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/
>     >     vtable-available-externally.cpp?rev=245267&r1=245266&r2=245267&view=
>     diff
>     >     ====================================================================
>     ======
>     >     ====
>     >     --- cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp
>     (original)
>     >     +++ cfe/trunk/test/CodeGenCXX/vtable-available-externally.cpp Tue
>     Aug 18
>     >     00:40:20 2015
>     >     @@ -182,8 +182,8 @@ void f() {
>     >      namespace Test9 {
>     >      // all virtual functions are outline, so we can assume that it will
>     >      // be generated in translation unit where foo is defined
>     >     -// CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally
>     unnamed_addr
>     >     constant
>     >     -// CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally
>     unnamed_addr
>     >     constant
>     >     +// CHECK-TEST9: @_ZTVN5Test91AE = available_externally unnamed_addr
>     >     constant
>     >     +// CHECK-TEST9: @_ZTVN5Test91BE = available_externally unnamed_addr
>     >     constant
>     >      struct A {
>     >        virtual void foo();
>     >        virtual void bar();
>     >     @@ -206,7 +206,7 @@ void g() {
>     >      namespace Test10 {
>     >
>     >      // because A's key function is defined here, vtable is generated in
>     this
>     >     TU
>     >     -// CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
>     >     +// CHECK-TEST10: @_ZTVN6Test101AE = unnamed_addr constant
>     >      struct A {
>     >        virtual void foo();
>     >        virtual void bar();
>     >     @@ -214,14 +214,14 @@ struct A {
>     >      void A::foo() {}
>     >
>     >      // Because key function is inline we will generate vtable as
>     linkonce_odr
>     >     -// CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr
>     >     constant
>     >     +// CHECK-TEST10: @_ZTVN6Test101DE = linkonce_odr unnamed_addr
>     constant
>     >      struct D : A {
>     >        void bar();
>     >      };
>     >      inline void D::bar() {}
>     >
>     >      // because B has outline key function then we can refer to
>     >     -// CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally
>     unnamed_addr
>     >     constant
>     >     +// CHECK-TEST10: @_ZTVN6Test101BE = available_externally
>     unnamed_addr
>     >     constant
>     >      struct B : A {
>     >        void foo();
>     >        void bar();
>     >     @@ -230,7 +230,7 @@ struct B : A {
>     >      // C's key function (car) is outline, but C has inline virtual
>     function
>     >     so we
>     >      // can't guarantee that we will be able to refer to bar from name
>     >      // so (at the moment) we can't emit vtable available_externally
>     >     -// CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr
>     constant
>     >     +// CHECK-TEST10: @_ZTVN6Test101CE = external unnamed_addr constant
>     >      struct C : A {
>     >        void bar() {}               // defined in body - not key function
>     >        virtual inline void gar();  // inline in body - not key function
>     >     @@ -238,7 +238,7 @@ struct C : A {
>     >      };
>     >
>     >      // no key function, vtable will be generated everywhere it will be
>     used
>     >     -// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr
>     >     constant
>     >     +// CHECK-TEST10: @_ZTVN6Test101EE = linkonce_odr unnamed_addr
>     constant
>     >      struct E : A {};
>     >
>     >      void g(A& a) {
>     >
>     >     _______________________________________________
>     >     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


More information about the cfe-commits mailing list