r267784 - Rework interface for bitset-using features to use a notion of LTO visibility.

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 28 10:16:41 PDT 2016


Sorry about that. I had a separate patch to fix the compiler-rt tests, but
I forgot to commit it. I committed that patch in r267902 and re-applied my
change in r267903.

Peter

On Thu, Apr 28, 2016 at 5:21 AM, Benjamin Kramer <benny.kra at gmail.com>
wrote:

> I'm seeing lots of compiler-rt CFI tests failing after this change.
> Apparently none of the buildbots have a configuration where both the
> gold plugin and compiler-rt is built and tested, log attached. I
> reverted this and the follow-ups in r267871.
>
> On Wed, Apr 27, 2016 at 10:39 PM, Peter Collingbourne via cfe-commits
> <cfe-commits at lists.llvm.org> wrote:
> > Author: pcc
> > Date: Wed Apr 27 15:39:53 2016
> > New Revision: 267784
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=267784&view=rev
> > Log:
> > Rework interface for bitset-using features to use a notion of LTO
> visibility.
> >
> > Bitsets, and the compiler features they rely on (vtable opt, CFI),
> > only have visibility within the LTO'd part of the linkage unit.
> Therefore,
> > only enable these features for classes with hidden LTO visibility. This
> > notion is based on object file visibility or (on Windows)
> > dllimport/dllexport attributes.
> >
> > We provide the [[clang::lto_visibility_public]] attribute to override the
> > compiler's LTO visibility inference in cases where the class is defined
> > in the non-LTO'd part of the linkage unit, or where the ABI supports
> > calling classes derived from abstract base classes with hidden visibility
> > in other linkage units (e.g. COM on Windows).
> >
> > If the cross-DSO CFI mode is enabled, bitset checks are emitted even for
> > classes with public LTO visibility, as that mode uses a separate
> mechanism
> > to cause bitsets to be exported.
> >
> > This mechanism replaces the whole-program-vtables blacklist, so remove
> the
> > -fwhole-program-vtables-blacklist flag.
> >
> > Because __declspec(uuid()) now implies [[clang::lto_visibility_public]],
> the
> > support for the special attr:uuid blacklist entry is removed.
> >
> > Differential Revision: http://reviews.llvm.org/D18635
> >
> > Added:
> >     cfe/trunk/docs/LTOVisibility.rst
> >     cfe/trunk/test/CodeGenCXX/bitset-inference.cpp
> >     cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp
> >     cfe/trunk/test/SemaCXX/attr-lto-visibility-public.cpp
> > Removed:
> >     cfe/trunk/runtime/vtables_blacklist.txt
> >     cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp
> > Modified:
> >     cfe/trunk/docs/ControlFlowIntegrity.rst
> >     cfe/trunk/docs/UsersManual.rst
> >     cfe/trunk/docs/index.rst
> >     cfe/trunk/include/clang/Basic/Attr.td
> >     cfe/trunk/include/clang/Basic/AttrDocs.td
> >     cfe/trunk/include/clang/Driver/CC1Options.td
> >     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/CGVTables.cpp
> >     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >     cfe/trunk/lib/CodeGen/CodeGenModule.h
> >     cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> >     cfe/trunk/lib/Driver/SanitizerArgs.cpp
> >     cfe/trunk/lib/Driver/Tools.cpp
> >     cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> >     cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> >     cfe/trunk/runtime/CMakeLists.txt
> >     cfe/trunk/test/CodeGenCXX/bitsets.cpp
> >     cfe/trunk/test/CodeGenCXX/cfi-cast.cpp
> >     cfe/trunk/test/CodeGenCXX/cfi-cross-dso.cpp
> >     cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp
> >     cfe/trunk/test/CodeGenCXX/cfi-nvcall.cpp
> >     cfe/trunk/test/CodeGenCXX/cfi-stats.cpp
> >     cfe/trunk/test/Driver/cl-runtime-flags.c
> >     cfe/trunk/test/Driver/fsanitize.c
> >     cfe/trunk/test/Driver/whole-program-vtables.c
> >     cfe/trunk/test/Frontend/dependency-gen.c
> >     cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
> >
> > Modified: cfe/trunk/docs/ControlFlowIntegrity.rst
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ControlFlowIntegrity.rst?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/docs/ControlFlowIntegrity.rst (original)
> > +++ cfe/trunk/docs/ControlFlowIntegrity.rst Wed Apr 27 15:39:53 2016
> > @@ -25,13 +25,25 @@ As currently implemented, all schemes re
> >  so it is required to specify ``-flto``, and the linker used must
> support LTO,
> >  for example via the `gold plugin`_.
> >
> > -To allow the checks to be implemented efficiently, the program must be
> > -structured such that certain object files are compiled with CFI
> > +To allow the checks to be implemented efficiently, the program must
> > +be structured such that certain object files are compiled with CFI
> >  enabled, and are statically linked into the program. This may preclude
> > -the use of shared libraries in some cases. Experimental support for
> > -:ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that
> > -does not have these requirements. This cross-DSO support has unstable
> > -ABI at this time.
> > +the use of shared libraries in some cases.
> > +
> > +The compiler will only produce CFI checks for a class if it can infer
> hidden
> > +LTO visibility for that class. LTO visibility is a property of a class
> that
> > +is inferred from flags and attributes. For more details, see the
> documentation
> > +for :doc:`LTO visibility <LTOVisibility>`.
> > +
> > +The ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags
> > +require that a ``-fvisibility=`` flag also be specified. This is
> because the
> > +default visibility setting is ``-fvisibility=default``, which would
> disable
> > +CFI checks for classes without visibility attributes. Most users will
> want
> > +to specify ``-fvisibility=hidden``, which enables CFI checks for such
> classes.
> > +
> > +Experimental support for :ref:`cross-DSO control flow integrity
> > +<cfi-cross-dso>` exists that does not require classes to have hidden LTO
> > +visibility. This cross-DSO support has unstable ABI at this time.
> >
> >  .. _gold plugin: http://llvm.org/docs/GoldPlugin.html
> >
> > @@ -233,11 +245,6 @@ A :doc:`SanitizerSpecialCaseList` can be
> >  source files, functions and types using the ``src``, ``fun`` and
> ``type``
> >  entity types.
> >
> > -In addition, if a type has a ``uuid`` attribute and the blacklist
> contains
> > -the type entry ``attr:uuid``, CFI checks are suppressed for that type.
> This
> > -allows all COM types to be easily blacklisted, which is useful as COM
> types
> > -are typically defined outside of the linked program.
> > -
> >  .. code-block:: bash
> >
> >      # Suppress checking for code in a file.
> > @@ -247,8 +254,6 @@ are typically defined outside of the lin
> >      fun:*MyFooBar*
> >      # Ignore all types in the standard library.
> >      type:std::*
> > -    # Ignore all types with a uuid attribute.
> > -    type:attr:uuid
> >
> >  .. _cfi-cross-dso:
> >
> > @@ -260,6 +265,11 @@ flow integrity mode, which allows all CF
> >  apply across DSO boundaries. As in the regular CFI, each DSO must be
> >  built with ``-flto``.
> >
> > +Normally, CFI checks will only be performed for classes that have
> hidden LTO
> > +visibility. With this flag enabled, the compiler will emit cross-DSO CFI
> > +checks for all classes, except for those which appear in the CFI
> blacklist
> > +or which use a ``no_sanitize`` attribute.
> > +
> >  Design
> >  ======
> >
> >
> > Added: cfe/trunk/docs/LTOVisibility.rst
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LTOVisibility.rst?rev=267784&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/docs/LTOVisibility.rst (added)
> > +++ cfe/trunk/docs/LTOVisibility.rst Wed Apr 27 15:39:53 2016
> > @@ -0,0 +1,111 @@
> > +==============
> > +LTO Visibility
> > +==============
> > +
> > +*LTO visibility* is a property of an entity that specifies whether it
> can be
> > +referenced from outside the current LTO unit. A *linkage unit* is a set
> of
> > +translation units linked together into an executable or DSO, and a
> linkage
> > +unit's *LTO unit* is the subset of the linkage unit that is linked
> together
> > +using link-time optimization; in the case where LTO is not being used,
> the
> > +linkage unit's LTO unit is empty. Each linkage unit has only a single
> LTO unit.
> > +
> > +The LTO visibility of a class is used by the compiler to determine which
> > +classes the virtual function call optimization and control flow
> integrity
> > +features apply to. These features use whole-program information, so they
> > +require the entire class hierarchy to be visible in order to work
> correctly.
> > +
> > +If any translation unit in the program uses either of the virtual
> function
> > +call optimization or control flow integrity features, it is effectively
> an
> > +ODR violation to define a class with hidden LTO visibility in multiple
> linkage
> > +units. A class with public LTO visibility may be defined in multiple
> linkage
> > +units, but the tradeoff is that the virtual function call optimization
> and
> > +control flow integrity features can only be applied to classes with
> hidden LTO
> > +visibility. A class's LTO visibility is treated as an ODR-relevant
> property
> > +of its definition, so it must be consistent between translation units.
> > +
> > +In translation units built with LTO, LTO visibility is based on symbol
> > +visibility or, on the Windows platform, the dllimport and dllexport
> > +attributes. When targeting non-Windows platforms, classes with a
> visibility
> > +other than hidden visibility receive public LTO visibility. When
> targeting
> > +Windows, classes with dllimport or dllexport attributes receive public
> LTO
> > +visibility. All other classes receive hidden LTO visibility. Classes
> with
> > +internal linkage (e.g. classes declared in unnamed namespaces) also
> receive
> > +hidden LTO visibility.
> > +
> > +A class defined in a translation unit built without LTO receives public
> > +LTO visibility regardless of its object file visibility, linkage or
> other
> > +attributes.
> > +
> > +This mechanism will produce the correct result in most cases, but there
> are
> > +two cases where it may wrongly infer hidden LTO visibility.
> > +
> > +1. As a corollary of the above rules, if a linkage unit is produced
> from a
> > +   combination of LTO object files and non-LTO object files, any hidden
> > +   visibility class defined in both a translation unit built with LTO
> and
> > +   a translation unit built without LTO must be defined with public LTO
> > +   visibility in order to avoid an ODR violation.
> > +
> > +2. Some ABIs provide the ability to define an abstract base class
> without
> > +   visibility attributes in multiple linkage units and have virtual
> calls
> > +   to derived classes in other linkage units work correctly. One
> example of
> > +   this is COM on Windows platforms. If the ABI allows this, any base
> class
> > +   used in this way must be defined with public LTO visibility.
> > +
> > +Classes that fall into either of these categories can be marked up with
> the
> > +``[[clang::lto_visibility_public]]`` attribute. To specifically handle
> the
> > +COM case, classes with the ``__declspec(uuid())`` attribute receive
> public
> > +LTO visibility. On Windows platforms, clang-cl's ``/MT`` and ``/MTd``
> > +flags statically link the program against a prebuilt standard library;
> > +these flags imply public LTO visibility for every class declared in the
> > +``std`` and ``stdext`` namespaces.
> > +
> > +Example
> > +=======
> > +
> > +The following example shows how LTO visibility works in practice in
> several
> > +cases involving two linkage units, ``main`` and ``dso.so``.
> > +
> > +.. code-block:: none
> > +
> > +    +-----------------------------------------------------------+
> +----------------------------------------------------+
> > +    | main (clang++ -fvisibility=hidden):                       |  |
> dso.so (clang++ -fvisibility=hidden):              |
> > +    |                                                           |  |
>                                                 |
> > +    |  +-----------------------------------------------------+  |  |
> struct __attribute__((visibility("default"))) C { |
> > +    |  | LTO unit (clang++ -fvisibility=hidden -flto):       |  |  |
> virtual void f();                               |
> > +    |  |                                                     |  |  |
> }                                                 |
> > +    |  |  struct A { ... };                                  |  |  |
> void C::f() {}                                    |
> > +    |  |  struct [[clang::lto_visibility_public]] B { ... }; |  |  |
> struct D {                                        |
> > +    |  |  struct __attribute__((visibility("default"))) C {  |  |  |
> virtual void g() = 0;                           |
> > +    |  |    virtual void f();                                |  |  |
> };                                                |
> > +    |  |  };                                                 |  |  |
> struct E : D {                                    |
> > +    |  |  struct [[clang::lto_visibility_public]] D {        |  |  |
> virtual void g() { ... }                        |
> > +    |  |    virtual void g() = 0;                            |  |  |
> };                                                |
> > +    |  |  };                                                 |  |  |
> __attribute__(visibility("default"))) D *mkE() {  |
> > +    |  |                                                     |  |  |
> return new E;                                   |
> > +    |  +-----------------------------------------------------+  |  |
> }                                                 |
> > +    |                                                           |  |
>                                                 |
> > +    |  struct B { ... };                                        |
> +----------------------------------------------------+
> > +    |                                                           |
> > +    +-----------------------------------------------------------+
> > +
> > +We will now describe the LTO visibility of each of the classes defined
> in
> > +these linkage units.
> > +
> > +Class ``A`` is not defined outside of ``main``'s LTO unit, so it can
> have
> > +hidden LTO visibility. This is inferred from the object file visibility
> > +specified on the command line.
> > +
> > +Class ``B`` is defined in ``main``, both inside and outside its LTO
> unit. The
> > +definition outside the LTO unit has public LTO visibility, so the
> definition
> > +inside the LTO unit must also have public LTO visibility in order to
> avoid
> > +an ODR violation.
> > +
> > +Class ``C`` is defined in both ``main`` and ``dso.so`` and therefore
> must
> > +have public LTO visibility. This is correctly inferred from the
> ``visibility``
> > +attribute.
> > +
> > +Class ``D`` is an abstract base class with a derived class ``E`` defined
> > +in ``dso.so``.  This is an example of the COM scenario; the definition
> of
> > +``D`` in ``main``'s LTO unit must have public LTO visibility in order
> to be
> > +compatible with the definition of ``D`` in ``dso.so``, which is
> observable
> > +by calling the function ``mkE``.
> >
> > Modified: cfe/trunk/docs/UsersManual.rst
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/docs/UsersManual.rst (original)
> > +++ cfe/trunk/docs/UsersManual.rst Wed Apr 27 15:39:53 2016
> > @@ -1056,17 +1056,8 @@ are listed below.
> >  .. 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.
> > +   devirtualization and virtual constant propagation, for classes with
> > +   :doc:`hidden LTO visibility <LTOVisibility>`. Requires ``-flto``.
> >
> >  .. option:: -fno-assume-sane-operator-new
> >
> >
> > Modified: cfe/trunk/docs/index.rst
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/index.rst?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/docs/index.rst (original)
> > +++ cfe/trunk/docs/index.rst Wed Apr 27 15:39:53 2016
> > @@ -31,6 +31,7 @@ Using Clang as a Compiler
> >     SanitizerStats
> >     SanitizerSpecialCaseList
> >     ControlFlowIntegrity
> > +   LTOVisibility
> >     SafeStack
> >     Modules
> >     MSVCCompatibility
> >
> > Modified: cfe/trunk/include/clang/Basic/Attr.td
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Basic/Attr.td (original)
> > +++ cfe/trunk/include/clang/Basic/Attr.td Wed Apr 27 15:39:53 2016
> > @@ -1611,6 +1611,12 @@ def WeakRef : InheritableAttr {
> >    let Documentation = [Undocumented];
> >  }
> >
> > +def LTOVisibilityPublic : InheritableAttr {
> > +  let Spellings = [CXX11<"clang", "lto_visibility_public">];
> > +  let Subjects = SubjectList<[Record]>;
> > +  let Documentation = [LTOVisibilityDocs];
> > +}
> > +
> >  def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86>
> {
> >    // NOTE: If you add any additional spellings, ARMInterrupt's,
> >    // MSP430Interrupt's and MipsInterrupt's spellings must match.
> >
> > Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
> > +++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Apr 27 15:39:53 2016
> > @@ -2380,3 +2380,10 @@ The ``ifunc`` attribute may only be used
> >  Not all targets support this attribute.  ELF targets support this
> attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or
> higher.  Non-ELF targets currently do not support this attribute.
> >    }];
> >  }
> > +
> > +def LTOVisibilityDocs : Documentation {
> > +  let Category = DocCatType;
> > +  let Content = [{
> > +See :doc:`LTOVisibility`.
> > +  }];
> > +}
> >
> > Modified: cfe/trunk/include/clang/Driver/CC1Options.td
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Driver/CC1Options.td (original)
> > +++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Apr 27 15:39:53 2016
> > @@ -282,6 +282,9 @@ def fprofile_instrument_path_EQ : Joined
> >  def fprofile_instrument_use_path_EQ :
> >      Joined<["-"], "fprofile-instrument-use-path=">,
> >      HelpText<"Specify the profile path in PGO use compilation">;
> > +def flto_visibility_public_std:
> > +    Flag<["-"], "flto-visibility-public-std">,
> > +    HelpText<"Use public LTO visibility for classes in std and stdext
> namespaces">;
> >
> >
> //===----------------------------------------------------------------------===//
> >  // Dependency Output Options
> >
> > Modified: cfe/trunk/include/clang/Driver/Options.td
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Driver/Options.td (original)
> > +++ cfe/trunk/include/clang/Driver/Options.td Wed Apr 27 15:39:53 2016
> > @@ -1152,9 +1152,6 @@ def fwhole_program_vtables : Flag<["-"],
> >    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=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
> > +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Wed Apr 27
> 15:39:53 2016
> > @@ -187,6 +187,10 @@ CODEGENOPT(EmitLLVMUseLists, 1, 0) ///<
> >  CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply
> whole-program
> >                                        ///  vtable optimization.
> >
> > +/// Whether to use public LTO visibility for entities in std and stdext
> > +/// namespaces. This is enabled by clang-cl's /MT and /MTd flags.
> > +CODEGENOPT(LTOVisibilityPublicStd, 1, 0)
> > +
> >  /// 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=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Frontend/CodeGenOptions.h (original)
> > +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.h Wed Apr 27
> 15:39:53 2016
> > @@ -199,9 +199,6 @@ 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=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Apr 27 15:39:53 2016
> > @@ -2489,7 +2489,7 @@ void CodeGenFunction::EmitBitSetCodeForV
> >                                               llvm::Value *VTable,
> >                                               SourceLocation Loc) {
> >    if (CGM.getCodeGenOpts().WholeProgramVTables &&
> > -      !CGM.IsBitSetBlacklistedRecord(RD)) {
> > +      CGM.HasHiddenLTOVisibility(RD)) {
> >      llvm::Metadata *MD =
> >
> CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
> >      llvm::Value *BitSetName =
> > @@ -2565,7 +2565,12 @@ void CodeGenFunction::EmitVTablePtrCheck
> >                                           llvm::Value *VTable,
> >                                           CFITypeCheckKind TCK,
> >                                           SourceLocation Loc) {
> > -  if (CGM.IsBitSetBlacklistedRecord(RD))
> > +  if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
> > +      !CGM.HasHiddenLTOVisibility(RD))
> > +    return;
> > +
> > +  std::string TypeName = RD->getQualifiedNameAsString();
> > +  if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName))
> >      return;
> >
> >    SanitizerScope SanScope(this);
> >
> > Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Wed Apr 27 15:39:53 2016
> > @@ -902,34 +902,43 @@ void CodeGenModule::EmitDeferredVTables(
> >    DeferredVTables.clear();
> >  }
> >
> > -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);
> > -}
> > +bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
> > +  LinkageInfo LV = RD->getLinkageAndVisibility();
> > +  if (!isExternallyVisible(LV.getLinkage()))
> > +    return true;
> > +
> > +  if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
> > +    return false;
> > +
> > +  if (getTriple().isOSBinFormatCOFF()) {
> > +    if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
> > +      return false;
> > +  } else {
> > +    if (LV.getVisibility() != HiddenVisibility)
> > +      return false;
> > +  }
> > +
> > +  if (getCodeGenOpts().LTOVisibilityPublicStd) {
> > +    const DeclContext *DC = RD;
> > +    while (1) {
> > +      auto *D = cast<Decl>(DC);
> > +      DC = DC->getParent();
> > +      if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
> > +        if (auto *ND = dyn_cast<NamespaceDecl>(D))
> > +          if (const IdentifierInfo *II = ND->getIdentifier())
> > +            if (II->isStr("std") || II->isStr("stdext"))
> > +              return false;
> > +        break;
> > +      }
> > +    }
> > +  }
> >
> > -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()));
> > +  return true;
> >  }
> >
> >  void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable
> *VTable,
> >                                              const VTableLayout
> &VTLayout) {
> > -  if (!NeedVTableBitSets())
> > +  if (!getCodeGenOpts().PrepareForLTO)
> >      return;
> >
> >    CharUnits PointerWidth =
> > @@ -938,12 +947,8 @@ void CodeGenModule::EmitVTableBitSetEntr
> >    typedef std::pair<const CXXRecordDecl *, unsigned> BSEntry;
> >    std::vector<BSEntry> BitsetEntries;
> >    // Create a bit set entry for each address point.
> > -  for (auto &&AP : VTLayout.getAddressPoints()) {
> > -    if (IsBitSetBlacklistedRecord(AP.first.getBase()))
> > -      continue;
> > -
> > +  for (auto &&AP : VTLayout.getAddressPoints())
> >      BitsetEntries.push_back(std::make_pair(AP.first.getBase(),
> AP.second));
> > -  }
> >
> >    // Sort the bit set entries for determinism.
> >    std::sort(BitsetEntries.begin(), BitsetEntries.end(),
> >
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Apr 27 15:39:53 2016
> > @@ -88,9 +88,7 @@ CodeGenModule::CodeGenModule(ASTContext
> >        PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M),
> Diags(diags),
> >        Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
> >        VMContext(M.getContext()), Types(*this), VTables(*this),
> > -      SanitizerMD(new SanitizerMetadata(*this)),
> > -
> WholeProgramVTablesBlacklist(CGO.WholeProgramVTablesBlacklistFiles,
> > -                                   C.getSourceManager()) {
> > +      SanitizerMD(new SanitizerMetadata(*this)) {
> >
> >    // 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=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Apr 27 15:39:53 2016
> > @@ -490,8 +490,6 @@ private:
> >    /// MDNodes.
> >    llvm::DenseMap<QualType, llvm::Metadata *> MetadataIdMap;
> >
> > -  SanitizerBlacklist WholeProgramVTablesBlacklist;
> > -
> >  public:
> >    CodeGenModule(ASTContext &C, const HeaderSearchOptions
> &headersearchopts,
> >                  const PreprocessorOptions &ppopts,
> > @@ -1115,12 +1113,10 @@ public:
> >    void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
> >                                 CodeGenFunction *CGF = nullptr);
> >
> > -  /// 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);
> > +  /// Returns whether the given record has hidden LTO visibility and
> therefore
> > +  /// may participate in (single-module) CFI and whole-program vtable
> > +  /// optimization.
> > +  bool HasHiddenLTOVisibility(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/MicrosoftCXXABI.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Apr 27 15:39:53 2016
> > @@ -1503,7 +1503,7 @@ void MicrosoftCXXABI::EmitDestructorCall
> >  void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
> >                                                const CXXRecordDecl *RD,
> >                                                llvm::GlobalVariable
> *VTable) {
> > -  if (!CGM.NeedVTableBitSets())
> > +  if (!CGM.getCodeGenOpts().PrepareForLTO)
> >      return;
> >
> >    llvm::NamedMDNode *BitsetsMD =
> > @@ -1519,15 +1519,13 @@ void MicrosoftCXXABI::emitVTableBitSetEn
> >            : CharUnits::Zero();
> >
> >    if (Info->PathToBaseWithVPtr.empty()) {
> > -    if (!CGM.IsBitSetBlacklistedRecord(RD))
> > -      CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
> > +    CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
> >      return;
> >    }
> >
> >    // Add a bitset entry for the least derived base belonging to this
> vftable.
> > -  if (!CGM.IsBitSetBlacklistedRecord(Info->PathToBaseWithVPtr.back()))
> > -    CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
> > -                                Info->PathToBaseWithVPtr.back());
> > +  CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
> > +                              Info->PathToBaseWithVPtr.back());
> >
> >    // Add a bitset entry for each derived class that is laid out at the
> same
> >    // offset as the least derived base.
> > @@ -1545,12 +1543,11 @@ void MicrosoftCXXABI::emitVTableBitSetEn
> >        Offset = VBI->second.VBaseOffset;
> >      if (!Offset.isZero())
> >        return;
> > -    if (!CGM.IsBitSetBlacklistedRecord(DerivedRD))
> > -      CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
> DerivedRD);
> > +    CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
> DerivedRD);
> >    }
> >
> >    // Finally do the same for the most derived class.
> > -  if (Info->FullOffsetInMDC.isZero() &&
> !CGM.IsBitSetBlacklistedRecord(RD))
> > +  if (Info->FullOffsetInMDC.isZero())
> >      CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
> >  }
> >
> > @@ -1819,7 +1816,7 @@ llvm::Value *MicrosoftCXXABI::getVirtual
> >
> >    MicrosoftVTableContext::MethodVFTableLocation ML =
> >        CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
> > -  if (CGM.NeedVTableBitSets())
> > +  if (CGM.getCodeGenOpts().PrepareForLTO)
> >      CGF.EmitBitSetCodeForVCall(getClassAtVTableLocation(getContext(),
> GD, ML),
> >                                 VTable, Loc);
> >
> >
> > Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original)
> > +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Wed Apr 27 15:39:53 2016
> > @@ -39,6 +39,7 @@ enum : SanitizerMask {
> >    TrappingSupported =
> >        (Undefined & ~Vptr) | UnsignedIntegerOverflow | LocalBounds | CFI,
> >    TrappingDefault = CFI,
> > +  CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
> >  };
> >
> >  enum CoverageFeature {
> > @@ -560,6 +561,14 @@ SanitizerArgs::SanitizerArgs(const ToolC
> >    LinkCXXRuntimes =
> >        Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) ||
> D.CCCIsCXX();
> >
> > +  // Require -fvisibility= flag on non-Windows if vptr CFI is enabled.
> > +  if ((Kinds & CFIClasses) && !TC.getTriple().isOSWindows() &&
> > +      !Args.hasArg(options::OPT_fvisibility_EQ)) {
> > +    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
> > +        << lastArgumentForMask(D, Args, Kinds & CFIClasses)
> > +        << "-fvisibility=";
> > +  }
> > +
> >    // Finally, initialize the set of available and recoverable
> sanitizers.
> >    Sanitizers.Mask |= Kinds;
> >    RecoverableSanitizers.Mask |= RecoverableKinds;
> >
> > Modified: cfe/trunk/lib/Driver/Tools.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Driver/Tools.cpp (original)
> > +++ cfe/trunk/lib/Driver/Tools.cpp Wed Apr 27 15:39:53 2016
> > @@ -4429,32 +4429,6 @@ void Clang::ConstructJob(Compilation &C,
> >      CmdArgs.push_back("-ffunction-sections");
> >    }
> >
> > -  if (Args.hasFlag(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");
> > @@ -5785,6 +5759,17 @@ void Clang::ConstructJob(Compilation &C,
> >        CmdArgs.push_back(I->getFilename());
> >      }
> >
> > +  bool WholeProgramVTables =
> > +      Args.hasFlag(options::OPT_fwhole_program_vtables,
> > +                   options::OPT_fno_whole_program_vtables, false);
> > +  if (WholeProgramVTables) {
> > +    if (!D.isUsingLTO())
> > +      D.Diag(diag::err_drv_argument_only_allowed_with)
> > +          << "-fwhole-program-vtables"
> > +          << "-flto";
> > +    CmdArgs.push_back("-fwhole-program-vtables");
> > +  }
> > +
> >    // Finally add the compile command to the compilation.
> >    if (Args.hasArg(options::OPT__SLASH_fallback) &&
> >        Output.getType() == types::TY_Object &&
> > @@ -6048,11 +6033,13 @@ void Clang::AddClangCLArgs(const ArgList
> >      if (Args.hasArg(options::OPT__SLASH_LDd))
> >        CmdArgs.push_back("-D_DEBUG");
> >      CmdArgs.push_back("-D_MT");
> > +    CmdArgs.push_back("-flto-visibility-public-std");
> >      FlagForCRT = "--dependent-lib=libcmt";
> >      break;
> >    case options::OPT__SLASH_MTd:
> >      CmdArgs.push_back("-D_DEBUG");
> >      CmdArgs.push_back("-D_MT");
> > +    CmdArgs.push_back("-flto-visibility-public-std");
> >      FlagForCRT = "--dependent-lib=libcmtd";
> >      break;
> >    default:
> >
> > Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> > +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Apr 27 15:39:53
> 2016
> > @@ -482,8 +482,7 @@ static bool ParseCodeGenArgs(CodeGenOpti
> >    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.LTOVisibilityPublicStd =
> Args.hasArg(OPT_flto_visibility_public_std);
> >    Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
> >    Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
> >    Opts.DebugExplicitImport = Triple.isPS4CPU();
> >
> > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Apr 27 15:39:53 2016
> > @@ -5749,6 +5749,9 @@ static void ProcessDeclAttribute(Sema &S
> >    case AttributeList::AT_InternalLinkage:
> >      handleInternalLinkageAttr(S, D, Attr);
> >      break;
> > +  case AttributeList::AT_LTOVisibilityPublic:
> > +    handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, Attr);
> > +    break;
> >
> >    // Microsoft attributes:
> >    case AttributeList::AT_MSNoVTable:
> >
> > Modified: cfe/trunk/runtime/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/runtime/CMakeLists.txt?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/runtime/CMakeLists.txt (original)
> > +++ cfe/trunk/runtime/CMakeLists.txt Wed Apr 27 15:39:53 2016
> > @@ -148,16 +148,3 @@ 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})
> > -set_target_properties(vtables_blacklist PROPERTIES FOLDER "Misc")
> > -if(TARGET clang)
> > -  add_dependencies(clang vtables_blacklist)
> > -endif()
> > -install(FILES ${src} DESTINATION
> lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
> >
> > Removed: cfe/trunk/runtime/vtables_blacklist.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/runtime/vtables_blacklist.txt?rev=267783&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/runtime/vtables_blacklist.txt (original)
> > +++ cfe/trunk/runtime/vtables_blacklist.txt (removed)
> > @@ -1,8 +0,0 @@
> > -# 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
> >
> > Removed: cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp?rev=267783&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/bitset-blacklist.cpp (removed)
> > @@ -1,32 +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: %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();
> > -};
> > -
> > -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();
> > -}
> >
> > Added: cfe/trunk/test/CodeGenCXX/bitset-inference.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/bitset-inference.cpp?rev=267784&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/bitset-inference.cpp (added)
> > +++ cfe/trunk/test/CodeGenCXX/bitset-inference.cpp Wed Apr 27 15:39:53
> 2016
> > @@ -0,0 +1,107 @@
> > +// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -std=c++11
> -fms-extensions -fvisibility hidden -fwhole-program-vtables -emit-llvm -o -
> %s | FileCheck --check-prefix=ITANIUM %s
> > +// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11
> -fms-extensions -fwhole-program-vtables -emit-llvm -o - %s | FileCheck
> --check-prefix=MS --check-prefix=MS-STD %s
> > +// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc -std=c++11
> -fms-extensions -fwhole-program-vtables -flto-visibility-public-std
> -emit-llvm -o - %s | FileCheck --check-prefix=MS --check-prefix=MS-NOSTD %s
> > +
> > +struct C1 {
> > +  virtual void f();
> > +};
> > +
> > +struct __attribute__((visibility("default"))) C2 {
> > +  virtual void f();
> > +};
> > +
> > +struct __declspec(dllexport) C3 {
> > +  virtual void f();
> > +};
> > +
> > +struct __declspec(dllimport) C4 {
> > +  virtual void f();
> > +};
> > +
> > +struct [[clang::lto_visibility_public]] C5 {
> > +  virtual void f();
> > +};
> > +
> > +struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) C6 {
> > +  virtual void f();
> > +};
> > +
> > +namespace std {
> > +
> > +struct C7 {
> > +  virtual void f();
> > +  struct C8 {
> > +    virtual void f();
> > +  };
> > +};
> > +
> > +}
> > +
> > +extern "C++" {
> > +
> > +namespace stdext {
> > +
> > +struct C9 {
> > +  virtual void f();
> > +};
> > +
> > +}
> > +
> > +}
> > +
> > +namespace other {
> > +
> > +struct C10 {
> > +  virtual void f();
> > +};
> > +
> > +}
> > +
> > +namespace {
> > +
> > +struct C11 {
> > +  virtual void f();
> > +};
> > +
> > +}
> > +
> > +void f(C1 *c1, C2 *c2, C3 *c3, C4 *c4, C5 *c5, C6 *c6, std::C7 *c7,
> > +       std::C7::C8 *c8, stdext::C9 *c9, other::C10 *c10) {
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTS2C1"
> > +  // MS: bitset.test{{.*}}!"?AUC1@@"
> > +  c1->f();
> > +  // ITANIUM-NOT: bitset.test{{.*}}!"_ZTS2C2"
> > +  // MS: bitset.test{{.*}}!"?AUC2@@"
> > +  c2->f();
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTS2C3"
> > +  // MS-NOT: bitset.test{{.*}}!"?AUC3@@"
> > +  c3->f();
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTS2C4"
> > +  // MS-NOT: bitset.test{{.*}}!"?AUC4@@"
> > +  c4->f();
> > +  // ITANIUM-NOT: bitset.test{{.*}}!"_ZTS2C5"
> > +  // MS-NOT: bitset.test{{.*}}!"?AUC5@@"
> > +  c5->f();
> > +  // ITANIUM-NOT: bitset.test{{.*}}!"_ZTS2C6"
> > +  // MS-NOT: bitset.test{{.*}}!"?AUC6@@"
> > +  c6->f();
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTSSt2C7"
> > +  // MS-STD: bitset.test{{.*}}!"?AUC7 at std@@"
> > +  // MS-NOSTD-NOT: bitset.test{{.*}}!"?AUC7 at std@@"
> > +  c7->f();
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTSNSt2C72C8E"
> > +  // MS-STD: bitset.test{{.*}}!"?AUC8 at C7@std@@"
> > +  // MS-NOSTD-NOT: bitset.test{{.*}}!"?AUC8 at C7@std@@"
> > +  c8->f();
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTSN6stdext2C9E"
> > +  // MS-STD: bitset.test{{.*}}!"?AUC9 at stdext@@"
> > +  // MS-NOSTD-NOT: bitset.test{{.*}}!"?AUC9 at stdext@@"
> > +  c9->f();
> > +  // ITANIUM: bitset.test{{.*}}!"_ZTSN5other3C10E"
> > +  // MS: bitset.test{{.*}}!"?AUC10 at other@@"
> > +  c10->f();
> > +  // ITANIUM: bitset.test{{.*}}!{{[0-9]}}
> > +  // MS: bitset.test{{.*}}!{{[0-9]}}
> > +  C11 *c11;
> > +  c11->f();
> > +}
> >
> > Modified: cfe/trunk/test/CodeGenCXX/bitsets.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/bitsets.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/bitsets.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/bitsets.cpp Wed Apr 27 15:39:53 2016
> > @@ -1,12 +1,12 @@
> >  // 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
> > +// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility
> hidden -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 -flto -triple x86_64-unknown-linux -fvisibility
> hidden -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 -flto -triple x86_64-unknown-linux -fvisibility
> hidden -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 -flto -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
> > +// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux -fvisibility
> hidden -fwhole-program-vtables -emit-llvm -o - %s | FileCheck
> --check-prefix=VTABLE-OPT --check-prefix=ITANIUM %s
> > +// RUN: %clang_cc1 -flto -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@@")
> > @@ -62,7 +62,7 @@ void D::h() {
> >  // 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+24]], i32 3 }, {
> i16, i16, [4 x i8] }* @[[TYPE]] }
> >
> > -// ITANIUM: define void @_Z2afP1A
> > +// ITANIUM: define hidden void @_Z2afP1A
> >  // MS: define void @"\01?af@@YAXPEAUA@@@Z"
> >  void af(A *a) {
> >    // ITANIUM: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^
> ]*]], metadata !"_ZTS1A")
> > @@ -155,7 +155,7 @@ struct D : C {
> >    void m_fn1();
> >  };
> >
> > -// ITANIUM: define void @_ZN5test21fEPNS_1DE
> > +// ITANIUM: define hidden 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")
> >
> > Added: cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp?rev=267784&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp (added)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-blacklist.cpp Wed Apr 27 15:39:53 2016
> > @@ -0,0 +1,29 @@
> > +// RUN: %clang_cc1 -fvisibility hidden -fms-extensions
> -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK
> --check-prefix=NOBL %s
> > +// RUN: echo "type:std::*" > %t.txt
> > +// RUN: %clang_cc1 -fvisibility hidden -fms-extensions
> -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s |
> FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
> > +
> > +struct S1 {
> > +  virtual void f();
> > +};
> > +
> > +namespace std {
> > +
> > +struct S2 {
> > +  virtual void f();
> > +};
> > +
> > +}
> > +
> > +// CHECK: define{{.*}}s1f
> > +// NOBL: llvm.bitset.test
> > +// NOSTD: llvm.bitset.test
> > +void s1f(S1 *s1) {
> > +  s1->f();
> > +}
> > +
> > +// CHECK: define{{.*}}s2f
> > +// NOBL: llvm.bitset.test
> > +// NOSTD-NOT: llvm.bitset.test
> > +void s2f(std::S2 *s2) {
> > +  s2->f();
> > +}
> >
> > Modified: cfe/trunk/test/CodeGenCXX/cfi-cast.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-cast.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-cast.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-cast.cpp Wed Apr 27 15:39:53 2016
> > @@ -1,6 +1,6 @@
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++11
> -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o
> - %s | FileCheck -check-prefix=CHECK-DCAST %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++11
> -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm
> -o - %s | FileCheck -check-prefix=CHECK-UCAST %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++11
> -fsanitize=cfi-unrelated-cast,cfi-cast-strict
> -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s |
> FileCheck -check-prefix=CHECK-UCAST-STRICT %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden
> -std=c++11 -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast
> -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden
> -std=c++11 -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast
> -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden
> -std=c++11 -fsanitize=cfi-unrelated-cast,cfi-cast-strict
> -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s |
> FileCheck -check-prefix=CHECK-UCAST-STRICT %s
> >
> >  // In this test the main thing we are searching for is something like
> >  // 'metadata !"1B"' where "1B" is the mangled name of the class we are
> > @@ -17,7 +17,7 @@ struct B : A {
> >
> >  struct C : A {};
> >
> > -// CHECK-DCAST-LABEL: define void @_Z3abpP1A
> > +// CHECK-DCAST-LABEL: define hidden void @_Z3abpP1A
> >  void abp(A *a) {
> >    // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^
> ]*}}, metadata !"_ZTS1B")
> >    // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label
> %[[TRAPBB:[^ ,]*]]
> > @@ -31,7 +31,7 @@ void abp(A *a) {
> >    (void)static_cast<B*>(a);
> >  }
> >
> > -// CHECK-DCAST-LABEL: define void @_Z3abrR1A
> > +// CHECK-DCAST-LABEL: define hidden void @_Z3abrR1A
> >  void abr(A &a) {
> >    // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^
> ]*}}, metadata !"_ZTS1B")
> >    // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label
> %[[TRAPBB:[^ ,]*]]
> > @@ -45,7 +45,7 @@ void abr(A &a) {
> >    (void)static_cast<B&>(a);
> >  }
> >
> > -// CHECK-DCAST-LABEL: define void @_Z4abrrO1A
> > +// CHECK-DCAST-LABEL: define hidden void @_Z4abrrO1A
> >  void abrr(A &&a) {
> >    // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^
> ]*}}, metadata !"_ZTS1B")
> >    // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label
> %[[TRAPBB:[^ ,]*]]
> > @@ -59,7 +59,7 @@ void abrr(A &&a) {
> >    (void)static_cast<B&&>(a);
> >  }
> >
> > -// CHECK-UCAST-LABEL: define void @_Z3vbpPv
> > +// CHECK-UCAST-LABEL: define hidden void @_Z3vbpPv
> >  void vbp(void *p) {
> >    // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^
> ]*}}, metadata !"_ZTS1B")
> >    // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label
> %[[TRAPBB:[^ ,]*]]
> > @@ -73,7 +73,7 @@ void vbp(void *p) {
> >    (void)static_cast<B*>(p);
> >  }
> >
> > -// CHECK-UCAST-LABEL: define void @_Z3vbrRc
> > +// CHECK-UCAST-LABEL: define hidden void @_Z3vbrRc
> >  void vbr(char &r) {
> >    // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^
> ]*}}, metadata !"_ZTS1B")
> >    // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label
> %[[TRAPBB:[^ ,]*]]
> > @@ -87,7 +87,7 @@ void vbr(char &r) {
> >    (void)reinterpret_cast<B&>(r);
> >  }
> >
> > -// CHECK-UCAST-LABEL: define void @_Z4vbrrOc
> > +// CHECK-UCAST-LABEL: define hidden void @_Z4vbrrOc
> >  void vbrr(char &&r) {
> >    // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^
> ]*}}, metadata !"_ZTS1B")
> >    // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label
> %[[TRAPBB:[^ ,]*]]
> > @@ -101,32 +101,32 @@ void vbrr(char &&r) {
> >    (void)reinterpret_cast<B&&>(r);
> >  }
> >
> > -// CHECK-UCAST-LABEL: define void @_Z3vcpPv
> > -// CHECK-UCAST-STRICT-LABEL: define void @_Z3vcpPv
> > +// CHECK-UCAST-LABEL: define hidden void @_Z3vcpPv
> > +// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3vcpPv
> >  void vcp(void *p) {
> >    // CHECK-UCAST: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata
> !"_ZTS1A")
> >    // CHECK-UCAST-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}},
> metadata !"_ZTS1C")
> >    (void)static_cast<C*>(p);
> >  }
> >
> > -// CHECK-UCAST-LABEL: define void @_Z3bcpP1B
> > -// CHECK-UCAST-STRICT-LABEL: define void @_Z3bcpP1B
> > +// CHECK-UCAST-LABEL: define hidden void @_Z3bcpP1B
> > +// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z3bcpP1B
> >  void bcp(B *p) {
> >    // CHECK-UCAST: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata
> !"_ZTS1A")
> >    // CHECK-UCAST-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}},
> metadata !"_ZTS1C")
> >    (void)(C *)p;
> >  }
> >
> > -// CHECK-UCAST-LABEL: define void @_Z8bcp_callP1B
> > -// CHECK-UCAST-STRICT-LABEL: define void @_Z8bcp_callP1B
> > +// CHECK-UCAST-LABEL: define hidden void @_Z8bcp_callP1B
> > +// CHECK-UCAST-STRICT-LABEL: define hidden void @_Z8bcp_callP1B
> >  void bcp_call(B *p) {
> >    // CHECK-UCAST: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata
> !"_ZTS1A")
> >    // CHECK-UCAST-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}},
> metadata !"_ZTS1C")
> >    ((C *)p)->f();
> >  }
> >
> > -// CHECK-UCAST-LABEL: define i32 @_Z6a_callP1A
> > -// CHECK-UCAST-STRICT-LABEL: define i32 @_Z6a_callP1A
> > +// CHECK-UCAST-LABEL: define hidden i32 @_Z6a_callP1A
> > +// CHECK-UCAST-STRICT-LABEL: define hidden i32 @_Z6a_callP1A
> >  int a_call(A *a) {
> >    // CHECK-UCAST-NOT: @llvm.bitset.test
> >    // CHECK-UCAST-STRICT-NOT: @llvm.bitset.test
> >
> > Modified: cfe/trunk/test/CodeGenCXX/cfi-cross-dso.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-cross-dso.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-cross-dso.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-cross-dso.cpp Wed Apr 27 15:39:53 2016
> > @@ -1,5 +1,5 @@
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall
> -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck
> --check-prefix=CHECK --check-prefix=ITANIUM %s
> > -// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsanitize=cfi-vcall
> -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck
> --check-prefix=CHECK --check-prefix=MS %s
> > +// RUN: %clang_cc1 -flto -triple x86_64-unknown-linux
> -fsanitize=cfi-vcall -fsanitize-cfi-cross-dso -emit-llvm -o - %s |
> FileCheck --check-prefix=CHECK --check-prefix=ITANIUM %s
> > +// RUN: %clang_cc1 -flto -triple x86_64-pc-windows-msvc
> -fsanitize=cfi-vcall  -fsanitize-cfi-cross-dso -emit-llvm -o - %s |
> FileCheck --check-prefix=CHECK --check-prefix=MS %s
> >
> >  struct A {
> >    A();
> >
> > Modified: cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-ms-rtti.cpp Wed Apr 27 15:39:53 2016
> > @@ -1,5 +1,5 @@
> > -// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s
> -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
> > -// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 %s
> -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
> > +// RUN: %clang_cc1 -flto -emit-llvm -o - -triple=x86_64-pc-win32 %s
> -fsanitize=cfi-vcall | FileCheck --check-prefix=RTTI %s
> > +// RUN: %clang_cc1 -flto -emit-llvm -o - -triple=x86_64-pc-win32 %s
> -fsanitize=cfi-vcall -fno-rtti-data | FileCheck --check-prefix=NO-RTTI %s
> >
> >  struct A {
> >    A();
> >
> > Modified: cfe/trunk/test/CodeGenCXX/cfi-nvcall.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-nvcall.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-nvcall.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-nvcall.cpp Wed Apr 27 15:39:53 2016
> > @@ -1,5 +1,5 @@
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-nvcall
> -emit-llvm -o - %s | FileCheck %s
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux
> -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck
> --check-prefix=CHECK-STRICT %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden
> -fsanitize=cfi-nvcall -emit-llvm -o - %s | FileCheck %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden
> -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck
> --check-prefix=CHECK-STRICT %s
> >
> >  struct A {
> >    virtual void f();
> >
> > Modified: cfe/trunk/test/CodeGenCXX/cfi-stats.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cfi-stats.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenCXX/cfi-stats.cpp (original)
> > +++ cfe/trunk/test/CodeGenCXX/cfi-stats.cpp Wed Apr 27 15:39:53 2016
> > @@ -1,4 +1,4 @@
> > -// RUN: %clang_cc1 -triple x86_64-unknown-linux
> -fsanitize=cfi-vcall,cfi-nvcall,cfi-derived-cast,cfi-unrelated-cast,cfi-icall
> -fsanitize-stats -emit-llvm -o - %s | FileCheck %s
> > +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden
> -fsanitize=cfi-vcall,cfi-nvcall,cfi-derived-cast,cfi-unrelated-cast,cfi-icall
> -fsanitize-stats -emit-llvm -o - %s | FileCheck %s
> >
> >  // CHECK: [[STATS:@[^ ]*]] = internal global { i8*, i32, [5 x [2 x
> i8*]] } { i8* null, i32 5, [5 x [2 x i8*]]
> >  // CHECK: {{\[\[}}2 x i8*] zeroinitializer,
> >
> > Modified: cfe/trunk/test/Driver/cl-runtime-flags.c
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-runtime-flags.c?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Driver/cl-runtime-flags.c (original)
> > +++ cfe/trunk/test/Driver/cl-runtime-flags.c Wed Apr 27 15:39:53 2016
> > @@ -13,6 +13,7 @@
> >  // CHECK-MT-NOT: "-D_DEBUG"
> >  // CHECK-MT: "-D_MT"
> >  // CHECK-MT-NOT: "-D_DLL"
> > +// CHECK-MT: "-flto-visibility-public-std"
> >  // CHECK-MT: "--dependent-lib=libcmt"
> >  // CHECK-MT: "--dependent-lib=oldnames"
> >
> > @@ -21,6 +22,7 @@
> >  // CHECK-MTd: "-D_DEBUG"
> >  // CHECK-MTd: "-D_MT"
> >  // CHECK-MTd-NOT: "-D_DLL"
> > +// CHECK-MTd: "-flto-visibility-public-std"
> >  // CHECK-MTd: "--dependent-lib=libcmtd"
> >  // CHECK-MTd: "--dependent-lib=oldnames"
> >
> >
> > Modified: cfe/trunk/test/Driver/fsanitize.c
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Driver/fsanitize.c (original)
> > +++ cfe/trunk/test/Driver/fsanitize.c Wed Apr 27 15:39:53 2016
> > @@ -291,21 +291,27 @@
> >
> >
> >
> > -// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -c %s -###
> 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
> > -// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=cfi -flto -c %s
> -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
> > -// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-derived-cast
> -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-DCAST
> > -// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi-unrelated-cast
> -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-UCAST
> > -// RUN: %clang -target x86_64-linux-gnu -flto -fsanitize=cfi-nvcall -c
> %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NVCALL
> > -// RUN: %clang -target x86_64-linux-gnu -flto -fsanitize=cfi-vcall -c
> %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-VCALL
> > +// RUN: %clang -target x86_64-linux-gnu -fvisibility=hidden
> -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
> > +// RUN: %clang -target x86_64-apple-darwin10 -fvisibility=hidden
> -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
> > +// RUN: %clang -target x86_64-linux-gnu -fvisibility=hidden
> -fsanitize=cfi-derived-cast -flto -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-DCAST
> > +// RUN: %clang -target x86_64-linux-gnu -fvisibility=hidden
> -fsanitize=cfi-unrelated-cast -flto -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-UCAST
> > +// RUN: %clang -target x86_64-linux-gnu -flto -fvisibility=hidden
> -fsanitize=cfi-nvcall -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-NVCALL
> > +// RUN: %clang -target x86_64-linux-gnu -flto -fvisibility=hidden
> -fsanitize=cfi-vcall -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-VCALL
> >  // CHECK-CFI:
> -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall
> >  // CHECK-CFI-DCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast
> >  // CHECK-CFI-UCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-unrelated-cast
> >  // CHECK-CFI-NVCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-nvcall
> >  // CHECK-CFI-VCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-vcall
> >
> > -// RUN: %clang -target x86_64-linux-gnu -flto
> -fsanitize=cfi-derived-cast -fno-lto -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-NOLTO
> > +// RUN: %clang -target x86_64-linux-gnu -fvisibility=hidden -flto
> -fsanitize=cfi-derived-cast -fno-lto -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-NOLTO
> >  // CHECK-CFI-NOLTO: '-fsanitize=cfi-derived-cast' only allowed with
> '-flto'
> >
> > +// RUN: %clang -target x86_64-linux-gnu -flto
> -fsanitize=cfi-derived-cast -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-NOVIS
> > +// CHECK-CFI-NOVIS: '-fsanitize=cfi-derived-cast' only allowed with
> '-fvisibility='
> > +
> > +// RUN: %clang -target x86_64-pc-win32 -flto
> -fsanitize=cfi-derived-cast -c %s -### 2>&1 | FileCheck %s
> --check-prefix=CHECK-CFI-NOVIS-WIN
> > +// CHECK-CFI-NOVIS-WIN-NOT: only allowed with
> > +
> >  // RUN: %clang -target mips-unknown-linux -fsanitize=cfi-icall %s -###
> 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-ICALL-MIPS
> >  // CHECK-CFI-ICALL-MIPS: unsupported option '-fsanitize=cfi-icall' for
> target 'mips-unknown-linux'
> >
> >
> > Modified: cfe/trunk/test/Driver/whole-program-vtables.c
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/whole-program-vtables.c?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Driver/whole-program-vtables.c (original)
> > +++ cfe/trunk/test/Driver/whole-program-vtables.c Wed Apr 27 15:39:53
> 2016
> > @@ -1,11 +1,2 @@
> >  // 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"
> >
> > Modified: cfe/trunk/test/Frontend/dependency-gen.c
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/dependency-gen.c?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Frontend/dependency-gen.c (original)
> > +++ cfe/trunk/test/Frontend/dependency-gen.c Wed Apr 27 15:39:53 2016
> > @@ -21,7 +21,7 @@
> >  // RUN: %clang -MD -MF - %s -fsyntax-only -I ./ | FileCheck
> -check-prefix=CHECK-SIX %s
> >  // CHECK-SIX: {{ }}x.h
> >  // RUN: echo "fun:foo" > %t.blacklist
> > -// RUN: %clang -MD -MF - %s -fsyntax-only -fsanitize=cfi-vcall -flto
> -fsanitize-blacklist=%t.blacklist -I ./ | FileCheck
> -check-prefix=CHECK-SEVEN %s
> > +// RUN: %clang -MD -MF - %s -fsyntax-only -fsanitize=cfi-vcall -flto
> -fvisibility=hidden -fsanitize-blacklist=%t.blacklist -I ./ | FileCheck
> -check-prefix=CHECK-SEVEN %s
> >  // CHECK-SEVEN: .blacklist
> >  // CHECK-SEVEN: {{ }}x.h
> >  #ifndef INCLUDE_FLAG_TEST
> >
> > Added: cfe/trunk/test/SemaCXX/attr-lto-visibility-public.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-lto-visibility-public.cpp?rev=267784&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/SemaCXX/attr-lto-visibility-public.cpp (added)
> > +++ cfe/trunk/test/SemaCXX/attr-lto-visibility-public.cpp Wed Apr 27
> 15:39:53 2016
> > @@ -0,0 +1,14 @@
> > +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
> > +
> > +int i [[clang::lto_visibility_public]]; // expected-warning
> {{'lto_visibility_public' attribute only applies to struct, union or class}}
> > +typedef int t [[clang::lto_visibility_public]]; // expected-warning
> {{'lto_visibility_public' attribute only applies to struct, union or class}}
> > +[[clang::lto_visibility_public]] void f(); // expected-warning
> {{'lto_visibility_public' attribute only applies to struct, union or class}}
> > +void f() [[clang::lto_visibility_public]]; // expected-error
> {{'lto_visibility_public' attribute cannot be applied to types}}
> > +
> > +struct [[clang::lto_visibility_public]] s1 {
> > +  int i [[clang::lto_visibility_public]]; // expected-warning
> {{'lto_visibility_public' attribute only applies to struct, union or class}}
> > +  [[clang::lto_visibility_public]] void f(); // expected-warning
> {{'lto_visibility_public' attribute only applies to struct, union or class}}
> > +};
> > +
> > +struct [[clang::lto_visibility_public(1)]] s2 { // expected-error
> {{'lto_visibility_public' attribute takes no arguments}}
> > +};
> >
> > Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=267784&r1=267783&r2=267784&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
> > +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Wed Apr 27 15:39:53
> 2016
> > @@ -2524,6 +2524,7 @@ static std::string CalculateDiagnostic(c
> >      case ObjCProtocol | ObjCInterface:
> >        return "ExpectedObjectiveCInterfaceOrProtocol";
> >      case Field | Var: return "ExpectedFieldOrGlobalVar";
> > +    case GenericRecord | Namespace: return "ExpectedRecordOrNamespace";
> >    }
> >
> >    PrintFatalError(S.getLoc(),
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>



-- 
-- 
Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160428/22073e5f/attachment-0001.html>


More information about the cfe-commits mailing list