Thanks a lot! Steven
> On Feb 25, 2016, at 7:12 PM, Peter Collingbourne <pe...@pcc.me.uk> wrote: > > (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@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@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@test2@@YAXPEAUD@1@@Z" >>> -void f(D *d) { >>> - // ITANIUM: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, >>> metadata !"_ZTSN5test21DE") >>> - // MS: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata >>> !"?AUA@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@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >> > > -- > Peter _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits