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