r261767 - Add whole-program vtable optimization feature to Clang.

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 25 19:12:29 PST 2016


(I don't understand why this flag needs to exist, but) I've implemented a
fix in r261960.

Peter

On Thu, Feb 25, 2016 at 06:50:52PM -0800, Steven Wu wrote:
> Hi Peter
> 
> I notice after this commit, I can no longer use cmake option -DCLANG_TOOL_DRIVER_BUILD=OFF to choose not to build and link the clang driver. When using -DCLANG_TOOL_DRIVER_BUILD=OFF, clang target will not exist so cmake will error on the line:
> > +add_dependencies(clang vtables_blacklist)
> 
> Is it possible to move this line to tools/driver/CMakeLists.txt?
> 
> Thanks
> 
> Steven
> 
> 
> > On Feb 24, 2016, at 12:46 PM, Peter Collingbourne via cfe-commits <cfe-commits at lists.llvm.org> wrote:
> > 
> > Author: pcc
> > Date: Wed Feb 24 14:46:36 2016
> > New Revision: 261767
> > 
> > URL: http://llvm.org/viewvc/llvm-project?rev=261767&view=rev
> > Log:
> > Add whole-program vtable optimization feature to Clang.
> > 
> > This patch introduces the -fwhole-program-vtables flag, which enables the
> > whole-program vtable optimization feature (D16795) in Clang.
> > 
> > Differential Revision: http://reviews.llvm.org/D16821
> > 
> > Added:
> >    cfe/trunk/runtime/vtables_blacklist.txt
> >    cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp
> >      - copied, changed from r261762, cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp
> >    cfe/trunk/test/CodeGenCXX/bitsets.cpp
> >      - copied, changed from r261762, cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp
> >    cfe/trunk/test/Driver/Inputs/resource_dir/vtables_blacklist.txt
> >    cfe/trunk/test/Driver/whole-program-vtables.c
> > Removed:
> >    cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp
> >    cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp
> > Modified:
> >    cfe/trunk/docs/UsersManual.rst
> >    cfe/trunk/include/clang/Driver/Options.td
> >    cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> >    cfe/trunk/include/clang/Frontend/CodeGenOptions.h
> >    cfe/trunk/lib/CodeGen/CGClass.cpp
> >    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> >    cfe/trunk/lib/CodeGen/CGVTables.cpp
> >    cfe/trunk/lib/CodeGen/CodeGenFunction.h
> >    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >    cfe/trunk/lib/CodeGen/CodeGenModule.h
> >    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
> >    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> >    cfe/trunk/lib/Driver/Tools.cpp
> >    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> >    cfe/trunk/runtime/CMakeLists.txt
> > 
> > Modified: cfe/trunk/docs/UsersManual.rst
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/docs/UsersManual.rst (original)
> > +++ cfe/trunk/docs/UsersManual.rst Wed Feb 24 14:46:36 2016
> > @@ -1053,6 +1053,21 @@ are listed below.
> >    the behavior of sanitizers in the ``cfi`` group to allow checking
> >    of cross-DSO virtual and indirect calls.
> > 
> > +.. option:: -fwhole-program-vtables
> > +
> > +   Enable whole-program vtable optimizations, such as single-implementation
> > +   devirtualization and virtual constant propagation. Requires ``-flto``.
> > +
> > +   By default, the compiler will assume that all type hierarchies are
> > +   closed except those in the ``std`` namespace, the ``stdext`` namespace
> > +   and classes with the ``__declspec(uuid())`` attribute.
> > +
> > +.. option:: -fwhole-program-vtables-blacklist=path
> > +
> > +   Allows the user to specify the path to a list of additional classes to
> > +   blacklist from whole-program vtable optimizations. This list is in the
> > +   :ref:`CFI blacklist <cfi-blacklist>` format.
> > +
> > .. option:: -fno-assume-sane-operator-new
> > 
> >    Don't assume that the C++'s new operator is sane.
> > 
> > Modified: cfe/trunk/include/clang/Driver/Options.td
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/include/clang/Driver/Options.td (original)
> > +++ cfe/trunk/include/clang/Driver/Options.td Wed Feb 24 14:46:36 2016
> > @@ -1124,6 +1124,13 @@ def fvisibility_inlines_hidden : Flag<["
> > def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>,
> >   HelpText<"Give global types 'default' visibility and global functions and "
> >            "variables 'hidden' visibility by default">;
> > +def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Group>,
> > +  Flags<[CC1Option]>,
> > +  HelpText<"Enables whole-program vtable optimization. Requires -flto">;
> > +def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>;
> > +def fwhole_program_vtables_blacklist_EQ : Joined<["-"], "fwhole-program-vtables-blacklist=">,
> > +  Group<f_Group>, Flags<[CC1Option]>,
> > +  HelpText<"Path to a blacklist file for whole-program vtable optimization">;
> > def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
> >   HelpText<"Treat signed integer overflow as two's complement">;
> > def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
> > 
> > Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
> > +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Wed Feb 24 14:46:36 2016
> > @@ -179,6 +179,9 @@ CODEGENOPT(DebugExplicitImport, 1, 0)  /
> > 
> > CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
> > 
> > +CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply whole-program
> > +                                      ///  vtable optimization.
> > +
> > /// The user specified number of registers to be used for integral arguments,
> > /// or 0 if unspecified.
> > VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
> > 
> > Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.h?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/include/clang/Frontend/CodeGenOptions.h (original)
> > +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.h Wed Feb 24 14:46:36 2016
> > @@ -201,6 +201,9 @@ public:
> >   /// \brief A list of all -fno-builtin-* function names (e.g., memset).
> >   std::vector<std::string> NoBuiltinFuncs;
> > 
> > +  /// List of blacklist files for the whole-program vtable optimization feature.
> > +  std::vector<std::string> WholeProgramVTablesBlacklistFiles;
> > +
> > public:
> >   // Define accessors/mutators for code generation options of enumeration type.
> > #define CODEGENOPT(Name, Bits, Default)
> > 
> > Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Feb 24 14:46:36 2016
> > @@ -2485,15 +2485,35 @@ LeastDerivedClassWithSameLayout(const CX
> >       RD->bases_begin()->getType()->getAsCXXRecordDecl());
> > }
> > 
> > -void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXMethodDecl *MD,
> > +void CodeGenFunction::EmitBitSetCodeForVCall(const CXXRecordDecl *RD,
> > +                                             llvm::Value *VTable,
> > +                                             SourceLocation Loc) {
> > +  if (CGM.getCodeGenOpts().WholeProgramVTables &&
> > +      !CGM.IsBitSetBlacklistedRecord(RD)) {
> > +    llvm::Metadata *MD =
> > +        CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
> > +    llvm::Value *BitSetName =
> > +        llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
> > +
> > +    llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
> > +    llvm::Value *BitSetTest =
> > +        Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test),
> > +                           {CastedVTable, BitSetName});
> > +    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), BitSetTest);
> > +  }
> > +
> > +  if (SanOpts.has(SanitizerKind::CFIVCall))
> > +    EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc);
> > +}
> > +
> > +void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
> >                                                 llvm::Value *VTable,
> >                                                 CFITypeCheckKind TCK,
> >                                                 SourceLocation Loc) {
> > -  const CXXRecordDecl *ClassDecl = MD->getParent();
> >   if (!SanOpts.has(SanitizerKind::CFICastStrict))
> > -    ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
> > +    RD = LeastDerivedClassWithSameLayout(RD);
> > 
> > -  EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
> > +  EmitVTablePtrCheck(RD, VTable, TCK, Loc);
> > }
> > 
> > void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T,
> > @@ -2545,7 +2565,7 @@ void CodeGenFunction::EmitVTablePtrCheck
> >                                          llvm::Value *VTable,
> >                                          CFITypeCheckKind TCK,
> >                                          SourceLocation Loc) {
> > -  if (CGM.IsCFIBlacklistedRecord(RD))
> > +  if (CGM.IsBitSetBlacklistedRecord(RD))
> >     return;
> > 
> >   SanitizerScope SanScope(this);
> > 
> > Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Feb 24 14:46:36 2016
> > @@ -259,7 +259,8 @@ RValue CodeGenFunction::EmitCXXMemberOrO
> >     if (SanOpts.has(SanitizerKind::CFINVCall) &&
> >         MD->getParent()->isDynamicClass()) {
> >       llvm::Value *VTable = GetVTablePtr(This, Int8PtrTy, MD->getParent());
> > -      EmitVTablePtrCheckForCall(MD, VTable, CFITCK_NVCall, CE->getLocStart());
> > +      EmitVTablePtrCheckForCall(MD->getParent(), VTable, CFITCK_NVCall,
> > +                                CE->getLocStart());
> >     }
> > 
> >     if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
> > 
> > Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Wed Feb 24 14:46:36 2016
> > @@ -898,21 +898,34 @@ void CodeGenModule::EmitDeferredVTables(
> >   DeferredVTables.clear();
> > }
> > 
> > -bool CodeGenModule::IsCFIBlacklistedRecord(const CXXRecordDecl *RD) {
> > -  if (RD->hasAttr<UuidAttr>() &&
> > -      getContext().getSanitizerBlacklist().isBlacklistedType("attr:uuid"))
> > -    return true;
> > +bool CodeGenModule::NeedVTableBitSets() {
> > +  return getCodeGenOpts().WholeProgramVTables ||
> > +         getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) ||
> > +         getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) ||
> > +         getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) ||
> > +         getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast);
> > +}
> > 
> > -  return getContext().getSanitizerBlacklist().isBlacklistedType(
> > -      RD->getQualifiedNameAsString());
> > +bool CodeGenModule::IsBitSetBlacklistedRecord(const CXXRecordDecl *RD) {
> > +  std::string TypeName = RD->getQualifiedNameAsString();
> > +  auto isInBlacklist = [&](const SanitizerBlacklist &BL) {
> > +    if (RD->hasAttr<UuidAttr>() && BL.isBlacklistedType("attr:uuid"))
> > +      return true;
> > +
> > +    return BL.isBlacklistedType(TypeName);
> > +  };
> > +
> > +  return isInBlacklist(WholeProgramVTablesBlacklist) ||
> > +         ((LangOpts.Sanitize.has(SanitizerKind::CFIVCall) ||
> > +           LangOpts.Sanitize.has(SanitizerKind::CFINVCall) ||
> > +           LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) ||
> > +           LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast)) &&
> > +          isInBlacklist(getContext().getSanitizerBlacklist()));
> > }
> > 
> > void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
> >                                             const VTableLayout &VTLayout) {
> > -  if (!LangOpts.Sanitize.has(SanitizerKind::CFIVCall) &&
> > -      !LangOpts.Sanitize.has(SanitizerKind::CFINVCall) &&
> > -      !LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) &&
> > -      !LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast))
> > +  if (!NeedVTableBitSets())
> >     return;
> > 
> >   CharUnits PointerWidth =
> > @@ -922,7 +935,7 @@ void CodeGenModule::EmitVTableBitSetEntr
> >   std::vector<BSEntry> BitsetEntries;
> >   // Create a bit set entry for each address point.
> >   for (auto &&AP : VTLayout.getAddressPoints()) {
> > -    if (IsCFIBlacklistedRecord(AP.first.getBase()))
> > +    if (IsBitSetBlacklistedRecord(AP.first.getBase()))
> >       continue;
> > 
> >     BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second));
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Feb 24 14:46:36 2016
> > @@ -1401,7 +1401,7 @@ public:
> > 
> >   /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
> >   /// If vptr CFI is enabled, emit a check that VTable is valid.
> > -  void EmitVTablePtrCheckForCall(const CXXMethodDecl *MD, llvm::Value *VTable,
> > +  void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable,
> >                                  CFITypeCheckKind TCK, SourceLocation Loc);
> > 
> >   /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for
> > @@ -1409,6 +1409,12 @@ public:
> >   void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable,
> >                           CFITypeCheckKind TCK, SourceLocation Loc);
> > 
> > +  /// If whole-program virtual table optimization is enabled, emit an assumption
> > +  /// that VTable is a member of the type's bitset. Or, if vptr CFI is enabled,
> > +  /// emit a check that VTable is a member of the type's bitset.
> > +  void EmitBitSetCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable,
> > +                              SourceLocation Loc);
> > +
> >   /// CanDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given
> >   /// expr can be devirtualized.
> >   bool CanDevirtualizeMemberFunctionCall(const Expr *Base,
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Feb 24 14:46:36 2016
> > @@ -97,7 +97,9 @@ CodeGenModule::CodeGenModule(ASTContext
> >       NSConcreteStackBlock(nullptr), BlockObjectAssign(nullptr),
> >       BlockObjectDispose(nullptr), BlockDescriptorType(nullptr),
> >       GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr),
> > -      LifetimeEndFn(nullptr), SanitizerMD(new SanitizerMetadata(*this)) {
> > +      LifetimeEndFn(nullptr), SanitizerMD(new SanitizerMetadata(*this)),
> > +      WholeProgramVTablesBlacklist(CGO.WholeProgramVTablesBlacklistFiles,
> > +                                   C.getSourceManager()) {
> > 
> >   // Initialize the type cache.
> >   llvm::LLVMContext &LLVMContext = M.getContext();
> > 
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Feb 24 14:46:36 2016
> > @@ -489,6 +489,8 @@ private:
> >   /// MDNodes.
> >   llvm::DenseMap<QualType, llvm::Metadata *> MetadataIdMap;
> > 
> > +  SanitizerBlacklist WholeProgramVTablesBlacklist;
> > +
> > public:
> >   CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts,
> >                 const PreprocessorOptions &ppopts,
> > @@ -1108,9 +1110,12 @@ public:
> >   /// \param D Threadprivate declaration.
> >   void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
> > 
> > -  /// Returns whether the given record is blacklisted from control flow
> > -  /// integrity checks.
> > -  bool IsCFIBlacklistedRecord(const CXXRecordDecl *RD);
> > +  /// Returns whether we need bit sets attached to vtables.
> > +  bool NeedVTableBitSets();
> > +
> > +  /// Returns whether the given record is blacklisted from whole-program
> > +  /// transformations (i.e. CFI or whole-program vtable optimization).
> > +  bool IsBitSetBlacklistedRecord(const CXXRecordDecl *RD);
> > 
> >   /// Emit bit set entries for the given vtable using the given layout if
> >   /// vptr CFI is enabled.
> > 
> > Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Wed Feb 24 14:46:36 2016
> > @@ -1602,9 +1602,7 @@ llvm::Value *ItaniumCXXABI::getVirtualFu
> >   auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
> >   llvm::Value *VTable = CGF.GetVTablePtr(This, Ty, MethodDecl->getParent());
> > 
> > -  if (CGF.SanOpts.has(SanitizerKind::CFIVCall))
> > -    CGF.EmitVTablePtrCheckForCall(MethodDecl, VTable,
> > -                                  CodeGenFunction::CFITCK_VCall, Loc);
> > +  CGF.EmitBitSetCodeForVCall(MethodDecl->getParent(), VTable, Loc);
> > 
> >   uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
> >   llvm::Value *VFuncPtr =
> > 
> > Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Feb 24 14:46:36 2016
> > @@ -1503,10 +1503,7 @@ void MicrosoftCXXABI::EmitDestructorCall
> > void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
> >                                               const CXXRecordDecl *RD,
> >                                               llvm::GlobalVariable *VTable) {
> > -  if (!getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) &&
> > -      !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) &&
> > -      !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) &&
> > -      !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast))
> > +  if (!CGM.NeedVTableBitSets())
> >     return;
> > 
> >   llvm::NamedMDNode *BitsetsMD =
> > @@ -1522,13 +1519,13 @@ void MicrosoftCXXABI::emitVTableBitSetEn
> >           : CharUnits::Zero();
> > 
> >   if (Info->PathToBaseWithVPtr.empty()) {
> > -    if (!CGM.IsCFIBlacklistedRecord(RD))
> > +    if (!CGM.IsBitSetBlacklistedRecord(RD))
> >       CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
> >     return;
> >   }
> > 
> >   // Add a bitset entry for the least derived base belonging to this vftable.
> > -  if (!CGM.IsCFIBlacklistedRecord(Info->PathToBaseWithVPtr.back()))
> > +  if (!CGM.IsBitSetBlacklistedRecord(Info->PathToBaseWithVPtr.back()))
> >     CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
> >                                 Info->PathToBaseWithVPtr.back());
> > 
> > @@ -1548,12 +1545,12 @@ void MicrosoftCXXABI::emitVTableBitSetEn
> >       Offset = VBI->second.VBaseOffset;
> >     if (!Offset.isZero())
> >       return;
> > -    if (!CGM.IsCFIBlacklistedRecord(DerivedRD))
> > +    if (!CGM.IsBitSetBlacklistedRecord(DerivedRD))
> >       CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, DerivedRD);
> >   }
> > 
> >   // Finally do the same for the most derived class.
> > -  if (Info->FullOffsetInMDC.isZero() && !CGM.IsCFIBlacklistedRecord(RD))
> > +  if (Info->FullOffsetInMDC.isZero() && !CGM.IsBitSetBlacklistedRecord(RD))
> >     CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
> > }
> > 
> > @@ -1822,9 +1819,9 @@ llvm::Value *MicrosoftCXXABI::getVirtual
> > 
> >   MicrosoftVTableContext::MethodVFTableLocation ML =
> >       CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
> > -  if (CGF.SanOpts.has(SanitizerKind::CFIVCall))
> > -    CGF.EmitVTablePtrCheck(getClassAtVTableLocation(getContext(), GD, ML),
> > -                           VTable, CodeGenFunction::CFITCK_VCall, Loc);
> > +  if (CGM.NeedVTableBitSets())
> > +    CGF.EmitBitSetCodeForVCall(getClassAtVTableLocation(getContext(), GD, ML),
> > +                               VTable, Loc);
> > 
> >   llvm::Value *VFuncPtr =
> >       Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
> > 
> > Modified: cfe/trunk/lib/Driver/Tools.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Driver/Tools.cpp (original)
> > +++ cfe/trunk/lib/Driver/Tools.cpp Wed Feb 24 14:46:36 2016
> > @@ -4270,6 +4270,32 @@ void Clang::ConstructJob(Compilation &C,
> >     CmdArgs.push_back("-ffunction-sections");
> >   }
> > 
> > +  if (Args.hasArg(options::OPT_fwhole_program_vtables,
> > +                  options::OPT_fno_whole_program_vtables, false)) {
> > +    if (!D.isUsingLTO())
> > +      D.Diag(diag::err_drv_argument_only_allowed_with)
> > +          << "-fwhole-program-vtables"
> > +          << "-flto";
> > +    CmdArgs.push_back("-fwhole-program-vtables");
> > +
> > +    clang::SmallString<64> Path(D.ResourceDir);
> > +    llvm::sys::path::append(Path, "vtables_blacklist.txt");
> > +    if (llvm::sys::fs::exists(Path)) {
> > +      SmallString<64> BlacklistOpt("-fwhole-program-vtables-blacklist=");
> > +      BlacklistOpt += Path.str();
> > +      CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
> > +    }
> > +
> > +    for (const Arg *A :
> > +         Args.filtered(options::OPT_fwhole_program_vtables_blacklist_EQ)) {
> > +      A->claim();
> > +      if (!llvm::sys::fs::exists(A->getValue()))
> > +        D.Diag(clang::diag::err_drv_no_such_file) << A->getValue();
> > +    }
> > +
> > +    Args.AddAllArgs(CmdArgs, options::OPT_fwhole_program_vtables_blacklist_EQ);
> > +  }
> > +
> >   if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
> >                    UseSeparateSections)) {
> >     CmdArgs.push_back("-fdata-sections");
> > 
> > Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> > +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Feb 24 14:46:36 2016
> > @@ -441,6 +441,9 @@ static bool ParseCodeGenArgs(CodeGenOpti
> >   Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags);
> >   Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
> >   Opts.EmitCodeView = Args.hasArg(OPT_gcodeview);
> > +  Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
> > +  Opts.WholeProgramVTablesBlacklistFiles =
> > +      Args.getAllArgValues(OPT_fwhole_program_vtables_blacklist_EQ);
> >   Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
> >   Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
> >   Opts.DebugExplicitImport = Triple.isPS4CPU(); 
> > 
> > Modified: cfe/trunk/runtime/CMakeLists.txt
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/runtime/CMakeLists.txt?rev=261767&r1=261766&r2=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/runtime/CMakeLists.txt (original)
> > +++ cfe/trunk/runtime/CMakeLists.txt Wed Feb 24 14:46:36 2016
> > @@ -134,3 +134,13 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND E
> >       VERBATIM)
> >   endif()
> > endif()
> > +
> > +set(src "${CMAKE_CURRENT_SOURCE_DIR}/vtables_blacklist.txt")
> > +set(dst "${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/vtables_blacklist.txt")
> > +add_custom_command(OUTPUT ${dst}
> > +                   DEPENDS ${src}
> > +                   COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
> > +                   COMMENT "Copying vtables blacklist")
> > +add_custom_target(vtables_blacklist DEPENDS ${dst})
> > +add_dependencies(clang vtables_blacklist)
> > +install(FILES ${src} DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
> > 
> > Added: cfe/trunk/runtime/vtables_blacklist.txt
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/runtime/vtables_blacklist.txt?rev=261767&view=auto
> > ==============================================================================
> > --- cfe/trunk/runtime/vtables_blacklist.txt (added)
> > +++ cfe/trunk/runtime/vtables_blacklist.txt Wed Feb 24 14:46:36 2016
> > @@ -0,0 +1,8 @@
> > +# Standard library types.
> > +type:std::*
> > +
> > +# The stdext namespace contains Microsoft standard library extensions.
> > +type:stdext::*
> > +
> > +# Types with a uuid attribute, i.e. COM types.
> > +type:attr:uuid
> > 
> > Copied: cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp (from r261762, cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp)
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp?p2=cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp&p1=cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp&r1=261762&r2=261767&rev=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp Wed Feb 24 14:46:36 2016
> > @@ -1,7 +1,9 @@
> > // RUN: echo "type:attr:uuid" > %t.txt
> > // RUN: %clang_cc1 -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOUUID %s
> > +// RUN: %clang_cc1 -fms-extensions -fwhole-program-vtables -fwhole-program-vtables-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOUUID %s
> > // RUN: echo "type:std::*" > %t.txt
> > // RUN: %clang_cc1 -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
> > +// RUN: %clang_cc1 -fms-extensions -fwhole-program-vtables -fwhole-program-vtables-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
> > 
> > struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) S1 {
> >   virtual void f();
> > 
> > Copied: cfe/trunk/test/CodeGenCXX/bitsets.cpp (from r261762, cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp)
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/bitsets.cpp?p2=cfe/trunk/test/CodeGenCXX/bitsets.cpp&p1=cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp&r1=261762&r2=261767&rev=261767&view=diff
> > ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/bitsets.cpp Wed Feb 24 14:46:36 2016
> > @@ -1,7 +1,12 @@
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=ITANIUM-NDIAG --check-prefix=NDIAG %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
> > -// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS --check-prefix=NDIAG %s
> > +// Tests for the cfi-vcall feature:
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=ITANIUM --check-prefix=ITANIUM-NDIAG --check-prefix=NDIAG %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
> > +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CFI --check-prefix=MS --check-prefix=NDIAG %s
> > +
> > +// Tests for the whole-program-vtables feature:
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=ITANIUM %s
> > +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fwhole-program-vtables -emit-llvm -o - %s | FileCheck --check-prefix=VTABLE-OPT --check-prefix=MS %s
> > 
> > // MS: @[[VTA:[0-9]*]] {{.*}} comdat($"\01??_7A@@6B@")
> > // MS: @[[VTB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6B0@@")
> > @@ -53,9 +58,9 @@ void D::f() {
> > void D::h() {
> > }
> > 
> > -// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}cfi-vcall.cpp\00", align 1
> > +// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}bitsets.cpp\00", align 1
> > // DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" }
> > -// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { i8, { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }* } { i8 0, { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+23]], i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]] }
> > +// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { i8, { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }* } { i8 0, { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+24]], i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]] }
> > 
> > // ITANIUM: define void @_Z2afP1A
> > // MS: define void @"\01?af@@YAXPEAUA@@@Z"
> > @@ -63,10 +68,11 @@ void af(A *a) {
> >   // ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"_ZTS1A")
> >   // MS: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"?AUA@@")
> >   // DIAG-NEXT: [[VTVALID0:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT]], metadata !"all-vtables")
> > -  // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]]
> > -  // CHECK-NEXT: {{^$}}
> > +  // VTABLE-OPT: call void @llvm.assume(i1 [[P]])
> > +  // CFI-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]]
> > +  // CFI-NEXT: {{^$}}
> > 
> > -  // CHECK: [[TRAPBB]]
> > +  // CFI: [[TRAPBB]]
> >   // NDIAG-NEXT: call void @llvm.trap()
> >   // NDIAG-NEXT: unreachable
> >   // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64
> > @@ -76,8 +82,8 @@ void af(A *a) {
> >   // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
> >   // DIAG-RECOVER-NEXT: br label %[[CONTBB]]
> > 
> > -  // CHECK: [[CONTBB]]
> > -  // CHECK: call void %
> > +  // CFI: [[CONTBB]]
> > +  // CFI: call void %
> >   a->f();
> > }
> > 
> > @@ -109,7 +115,7 @@ void dh1(D *d) {
> > // MS: define internal void @"\01?df2@@YAXPEAUD@?A@@@Z"
> > __attribute__((no_sanitize("cfi")))
> > void df2(D *d) {
> > -  // CHECK-NOT: call i1 @llvm.bitset.test
> > +  // CFI-NOT: call i1 @llvm.bitset.test
> >   d->f();
> > }
> > 
> > @@ -117,7 +123,7 @@ void df2(D *d) {
> > // MS: define internal void @"\01?df3@@YAXPEAUD@?A@@@Z"
> > __attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall")))
> > void df3(D *d) {
> > -  // CHECK-NOT: call i1 @llvm.bitset.test
> > +  // CFI-NOT: call i1 @llvm.bitset.test
> >   d->f();
> > }
> > 
> > 
> > Removed: cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp?rev=261766&view=auto
> > ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp (removed)
> > @@ -1,30 +0,0 @@
> > -// RUN: echo "type:attr:uuid" > %t.txt
> > -// RUN: %clang_cc1 -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOUUID %s
> > -// RUN: echo "type:std::*" > %t.txt
> > -// RUN: %clang_cc1 -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
> > -
> > -struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) S1 {
> > -  virtual void f();
> > -};
> > -
> > -namespace std {
> > -
> > -struct S2 {
> > -  virtual void f();
> > -};
> > -
> > -}
> > -
> > -// CHECK: define{{.*}}s1f
> > -// NOSTD: llvm.bitset.test
> > -// NOUUID-NOT: llvm.bitset.test
> > -void s1f(S1 *s1) {
> > -  s1->f();
> > -}
> > -
> > -// CHECK: define{{.*}}s2f
> > -// NOSTD-NOT: llvm.bitset.test
> > -// NOUUID: llvm.bitset.test
> > -void s2f(std::S2 *s2) {
> > -  s2->f();
> > -}
> > 
> > Removed: cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp?rev=261766&view=auto
> > ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-vcall.cpp (removed)
> > @@ -1,205 +0,0 @@
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=ITANIUM-NDIAG --check-prefix=NDIAG %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=ITANIUM-DIAG --check-prefix=DIAG --check-prefix=DIAG-ABORT %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=ITANIUM --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s
> > -// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=MS --check-prefix=NDIAG %s
> > -
> > -// MS: @[[VTA:[0-9]*]] {{.*}} comdat($"\01??_7A@@6B@")
> > -// MS: @[[VTB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6B0@@")
> > -// MS: @[[VTAinB:[0-9]*]] {{.*}} comdat($"\01??_7B@@6BA@@@")
> > -// MS: @[[VTAinC:[0-9]*]] {{.*}} comdat($"\01??_7C@@6B@")
> > -// MS: @[[VTBinD:[0-9]*]] {{.*}} comdat($"\01??_7D@?A@@6BB@@@")
> > -// MS: @[[VTAinBinD:[0-9]*]] {{.*}} comdat($"\01??_7D@?A@@6BA@@@")
> > -// MS: @[[VTFA:[0-9]*]] {{.*}} comdat($"\01??_7FA@?1??foo@@YAXXZ at 6B@")
> > -
> > -struct A {
> > -  A();
> > -  virtual void f();
> > -};
> > -
> > -struct B : virtual A {
> > -  B();
> > -  virtual void g();
> > -  virtual void h();
> > -};
> > -
> > -struct C : virtual A {
> > -  C();
> > -};
> > -
> > -namespace {
> > -
> > -struct D : B, C {
> > -  D();
> > -  virtual void f();
> > -  virtual void h();
> > -};
> > -
> > -}
> > -
> > -A::A() {}
> > -B::B() {}
> > -C::C() {}
> > -D::D() {}
> > -
> > -void A::f() {
> > -}
> > -
> > -void B::g() {
> > -}
> > -
> > -void D::f() {
> > -}
> > -
> > -void D::h() {
> > -}
> > -
> > -// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}cfi-vcall.cpp\00", align 1
> > -// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" }
> > -// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { i8, { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }* } { i8 0, { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+23]], i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]] }
> > -
> > -// ITANIUM: define void @_Z2afP1A
> > -// MS: define void @"\01?af@@YAXPEAUA@@@Z"
> > -void af(A *a) {
> > -  // ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"_ZTS1A")
> > -  // MS: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"?AUA@@")
> > -  // DIAG-NEXT: [[VTVALID0:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT]], metadata !"all-vtables")
> > -  // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]]
> > -  // CHECK-NEXT: {{^$}}
> > -
> > -  // CHECK: [[TRAPBB]]
> > -  // NDIAG-NEXT: call void @llvm.trap()
> > -  // NDIAG-NEXT: unreachable
> > -  // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64
> > -  // DIAG-NEXT: [[VTVALID:%[^ ]*]] = zext i1 [[VTVALID0]] to i64
> > -  // DIAG-ABORT-NEXT: call void @__ubsan_handle_cfi_check_fail_abort(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
> > -  // DIAG-ABORT-NEXT: unreachable
> > -  // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_check_fail(i8* getelementptr inbounds ({{.*}} @[[BADTYPESTATIC]], i32 0, i32 0), i64 [[VTINT]], i64 [[VTVALID]])
> > -  // DIAG-RECOVER-NEXT: br label %[[CONTBB]]
> > -
> > -  // CHECK: [[CONTBB]]
> > -  // CHECK: call void %
> > -  a->f();
> > -}
> > -
> > -// ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE
> > -// MS: define internal void @"\01?df1@@YAXPEAUD@?A@@@Z"
> > -void df1(D *d) {
> > -  // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
> > -  // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"?AUA@@")
> > -  d->f();
> > -}
> > -
> > -// ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE
> > -// MS: define internal void @"\01?dg1@@YAXPEAUD@?A@@@Z"
> > -void dg1(D *d) {
> > -  // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
> > -  // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"?AUB@@")
> > -  d->g();
> > -}
> > -
> > -// ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE
> > -// MS: define internal void @"\01?dh1@@YAXPEAUD@?A@@@Z"
> > -void dh1(D *d) {
> > -  // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata ![[DTYPE]])
> > -  // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
> > -  d->h();
> > -}
> > -
> > -// ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE
> > -// MS: define internal void @"\01?df2@@YAXPEAUD@?A@@@Z"
> > -__attribute__((no_sanitize("cfi")))
> > -void df2(D *d) {
> > -  // CHECK-NOT: call i1 @llvm.bitset.test
> > -  d->f();
> > -}
> > -
> > -// ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE
> > -// MS: define internal void @"\01?df3@@YAXPEAUD@?A@@@Z"
> > -__attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall")))
> > -void df3(D *d) {
> > -  // CHECK-NOT: call i1 @llvm.bitset.test
> > -  d->f();
> > -}
> > -
> > -D d;
> > -
> > -void foo() {
> > -  df1(&d);
> > -  dg1(&d);
> > -  dh1(&d);
> > -  df2(&d);
> > -  df3(&d);
> > -
> > -  struct FA : A {
> > -    void f() {}
> > -  } fa;
> > -  af(&fa);
> > -}
> > -
> > -namespace test2 {
> > -
> > -struct A {
> > -  virtual void m_fn1();
> > -};
> > -struct B {
> > -  virtual void m_fn2();
> > -};
> > -struct C : B, A {};
> > -struct D : C {
> > -  void m_fn1();
> > -};
> > -
> > -// ITANIUM: define void @_ZN5test21fEPNS_1DE
> > -// MS: define void @"\01?f at test2@@YAXPEAUD at 1@@Z"
> > -void f(D *d) {
> > -  // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"_ZTSN5test21DE")
> > -  // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"?AUA at test2@@")
> > -  d->m_fn1();
> > -}
> > -
> > -}
> > -
> > -// Check for the expected number of elements (15 or 23 respectively).
> > -// MS-NDIAG: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){9}]]}
> > -// MS-DIAG: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){15}]]}
> > -// ITANIUM-NDIAG: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){14}]]}
> > -// ITANIUM-DIAG: !llvm.bitsets = !{[[X:[^,]*(,[^,]*){23}]]}
> > -
> > -// ITANIUM-DAG: !{!"_ZTS1A", [3 x i8*]* @_ZTV1A, i64 16}
> > -// ITANIUM-DIAG-DAG: !{!"all-vtables", [3 x i8*]* @_ZTV1A, i64 16}
> > -// ITANIUM-DAG: !{!"_ZTS1A", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
> > -// ITANIUM-DIAG-DAG: !{!"all-vtables", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1B", [7 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1A", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64}
> > -// ITANIUM-DIAG-DAG: !{!"all-vtables", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64}
> > -// ITANIUM-DAG: !{!"_ZTS1C", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1A", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
> > -// ITANIUM-DIAG-DAG: !{!"all-vtables", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1B", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1C", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 88}
> > -// ITANIUM-DIAG-DAG: !{!"all-vtables", [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 88}
> > -// ITANIUM-DAG: !{![[DTYPE]], [12 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1A", [7 x i8*]* @_ZTV1B, i64 32}
> > -// ITANIUM-DIAG-DAG: !{!"all-vtables", [7 x i8*]* @_ZTV1B, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1B", [7 x i8*]* @_ZTV1B, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1A", [5 x i8*]* @_ZTV1C, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1C", [5 x i8*]* @_ZTV1C, i64 32}
> > -// ITANIUM-DAG: !{!"_ZTS1A", [3 x i8*]* @_ZTVZ3foovE2FA, i64 16}
> > -// ITANIUM-DAG: !{!{{[0-9]+}}, [3 x i8*]* @_ZTVZ3foovE2FA, i64 16}
> > -
> > -// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTA]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [2 x i8*]* @[[VTA]], i64 8}
> > -// MS-DAG: !{!"?AUB@@", [3 x i8*]* @[[VTB]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [3 x i8*]* @[[VTB]], i64 8}
> > -// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTAinB]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [2 x i8*]* @[[VTAinB]], i64 8}
> > -// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTAinC]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [2 x i8*]* @[[VTAinC]], i64 8}
> > -// MS-DAG: !{!"?AUB@@", [3 x i8*]* @[[VTBinD]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [3 x i8*]* @[[VTBinD]], i64 8}
> > -// MS-DAG: !{![[DTYPE]], [3 x i8*]* @[[VTBinD]], i64 8}
> > -// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTAinBinD]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [2 x i8*]* @[[VTAinBinD]], i64 8}
> > -// MS-DAG: !{!"?AUA@@", [2 x i8*]* @[[VTFA]], i64 8}
> > -// MS-DIAG-DAG: !{!"all-vtables", [2 x i8*]* @[[VTFA]], i64 8}
> > -// MS-DAG: !{!{{[0-9]+}}, [2 x i8*]* @[[VTFA]], i64 8}
> > 
> > Added: cfe/trunk/test/Driver/Inputs/resource_dir/vtables_blacklist.txt
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/Inputs/resource_dir/vtables_blacklist.txt?rev=261767&view=auto
> > ==============================================================================
> >    (empty)
> > 
> > Added: cfe/trunk/test/Driver/whole-program-vtables.c
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/whole-program-vtables.c?rev=261767&view=auto
> > ==============================================================================
> > --- cfe/trunk/test/Driver/whole-program-vtables.c (added)
> > +++ cfe/trunk/test/Driver/whole-program-vtables.c Wed Feb 24 14:46:36 2016
> > @@ -0,0 +1,11 @@
> > +// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables -### %s 2>&1 | FileCheck --check-prefix=NO-LTO %s
> > +// NO-LTO: invalid argument '-fwhole-program-vtables' only allowed with '-flto'
> > +
> > +// RUN: %clang -target x86_64-unknown-linux -resource-dir=%S/Inputs/resource_dir -flto -fwhole-program-vtables -### -c %s 2>&1 | FileCheck --check-prefix=BLACKLIST %s
> > +// BLACKLIST: "-fwhole-program-vtables-blacklist={{.*}}vtables_blacklist.txt"
> > +
> > +// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables-blacklist=nonexistent.txt -flto -fwhole-program-vtables -### -c %s 2>&1 | FileCheck --check-prefix=NON-EXISTENT-BLACKLIST %s
> > +// NON-EXISTENT-BLACKLIST: no such file or directory: 'nonexistent.txt'
> > +
> > +// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables-blacklist=%S/Inputs/resource_dir/vtables_blacklist.txt -flto -fwhole-program-vtables -### -c %s 2>&1 | FileCheck --check-prefix=CUSTOM-BLACKLIST %s
> > +// CUSTOM-BLACKLIST: "-fwhole-program-vtables-blacklist={{.*}}Inputs/resource_dir/vtables_blacklist.txt"
> > 
> > 
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> 
> 

-- 
Peter


More information about the cfe-commits mailing list