[compiler-rt] r241745 - CFI: Get check-cfi passing on Windows.

Peter Collingbourne peter at pcc.me.uk
Wed Jul 8 15:10:35 PDT 2015


Author: pcc
Date: Wed Jul  8 17:10:34 2015
New Revision: 241745

URL: http://llvm.org/viewvc/llvm-project?rev=241745&view=rev
Log:
CFI: Get check-cfi passing on Windows.

Specifically:

- Start using %expect_crash.

- Provide an implementation of __ubsan::getDynamicTypeInfoFromVtable
  for the Microsoft C++ ABI. This is all that is needed for CFI
  diagnostics; UBSan's -fsanitize=vptr also requires an implementation of
  __ubsan::checkDynamicType.

- Build the sanitizer runtimes against the release version of the C
  runtime, even in debug builds.

- Accommodate demangling differences in tests.

Differential Revision: http://reviews.llvm.org/D11029

Added:
    compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
      - copied, changed from r241571, compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc
    compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
Modified:
    compiler-rt/trunk/CMakeLists.txt
    compiler-rt/trunk/lib/ubsan/CMakeLists.txt
    compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
    compiler-rt/trunk/lib/ubsan/ubsan_diag.h
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
    compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc
    compiler-rt/trunk/test/cfi/CMakeLists.txt
    compiler-rt/trunk/test/cfi/anon-namespace.cpp
    compiler-rt/trunk/test/cfi/bad-cast.cpp
    compiler-rt/trunk/test/cfi/multiple-inheritance.cpp
    compiler-rt/trunk/test/cfi/nvcall.cpp
    compiler-rt/trunk/test/cfi/overwrite.cpp
    compiler-rt/trunk/test/cfi/sibling.cpp
    compiler-rt/trunk/test/cfi/simple-fail.cpp
    compiler-rt/trunk/test/cfi/vdtor.cpp
    compiler-rt/trunk/test/lit.common.cfg
    compiler-rt/trunk/test/ubsan/lit.common.cfg

Modified: compiler-rt/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/CMakeLists.txt (original)
+++ compiler-rt/trunk/CMakeLists.txt Wed Jul  8 17:10:34 2015
@@ -213,17 +213,16 @@ append_list_if(COMPILER_RT_HAS_FNO_FUNCT
 append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
 
 if(MSVC)
-  # Replace the /MD[d] flags with /MT.
+  # Replace the /M[DT][d] flags with /MT, and strip any definitions of _DEBUG,
+  # which cause definition mismatches at link time.
   # FIXME: In fact, sanitizers should support both /MT and /MD, see PR20214.
   if(COMPILER_RT_HAS_MT_FLAG)
     foreach(flag_var
       CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
       CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
-      if(${flag_var} MATCHES "/MD")
-        string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
-      elseif(${flag_var} MATCHES "/MDd")
-        string(REGEX REPLACE "/MDd" "/MT" ${flag_var} "${${flag_var}}")
-      endif()
+      string(REGEX REPLACE "/M[DT]d" "/MT" ${flag_var} "${${flag_var}}")
+      string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
+      string(REGEX REPLACE "/D_DEBUG" "" ${flag_var} "${${flag_var}}")
     endforeach()
   endif()
   append_list_if(COMPILER_RT_HAS_Oy_FLAG /Oy- SANITIZER_COMMON_CFLAGS)
@@ -333,9 +332,6 @@ if(APPLE AND SANITIZER_MIN_OSX_VERSION V
   # Mac OS X prior to 10.9 had problems with exporting symbols from
   # libc++/libc++abi.
   set(SANITIZER_CAN_USE_CXXABI FALSE)
-elseif(WIN32)
-  # We do not currently support the Microsoft C++ ABI.
-  set(SANITIZER_CAN_USE_CXXABI FALSE)
 else()
   set(SANITIZER_CAN_USE_CXXABI TRUE)
 endif()

Modified: compiler-rt/trunk/lib/ubsan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/CMakeLists.txt?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/ubsan/CMakeLists.txt Wed Jul  8 17:10:34 2015
@@ -15,6 +15,8 @@ set(UBSAN_STANDALONE_SOURCES
 set(UBSAN_CXX_SOURCES
   ubsan_handlers_cxx.cc
   ubsan_type_hash.cc
+  ubsan_type_hash_itanium.cc
+  ubsan_type_hash_win.cc
   )
 
 include_directories(..)

Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.cc?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.cc Wed Jul  8 17:10:34 2015
@@ -165,8 +165,12 @@ static void renderText(const char *Messa
       case Diag::AK_String:
         Printf("%s", A.String);
         break;
-      case Diag::AK_Mangled: {
-        Printf("'%s'", Symbolizer::GetOrInit()->Demangle(A.String));
+      case Diag::AK_TypeName: {
+        if (SANITIZER_WINDOWS)
+          // The Windows implementation demangles names early.
+          Printf("'%s'", A.String);
+        else
+          Printf("'%s'", Symbolizer::GetOrInit()->Demangle(A.String));
         break;
       }
       case Diag::AK_SInt:

Modified: compiler-rt/trunk/lib/ubsan/ubsan_diag.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_diag.h?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.h Wed Jul  8 17:10:34 2015
@@ -113,11 +113,11 @@ public:
   const char *getText() const { return Text; }
 };
 
-/// \brief A mangled C++ name. Really just a strong typedef for 'const char*'.
-class MangledName {
+/// \brief A C++ type name. Really just a strong typedef for 'const char*'.
+class TypeName {
   const char *Name;
 public:
-  MangledName(const char *Name) : Name(Name) {}
+  TypeName(const char *Name) : Name(Name) {}
   const char *getName() const { return Name; }
 };
 
@@ -141,7 +141,7 @@ public:
   /// Kinds of arguments, corresponding to members of \c Arg's union.
   enum ArgKind {
     AK_String, ///< A string argument, displayed as-is.
-    AK_Mangled,///< A C++ mangled name, demangled before display.
+    AK_TypeName,///< A C++ type name, possibly demangled before display.
     AK_UInt,   ///< An unsigned integer argument.
     AK_SInt,   ///< A signed integer argument.
     AK_Float,  ///< A floating-point argument.
@@ -152,7 +152,7 @@ public:
   struct Arg {
     Arg() {}
     Arg(const char *String) : Kind(AK_String), String(String) {}
-    Arg(MangledName MN) : Kind(AK_Mangled), String(MN.getName()) {}
+    Arg(TypeName TN) : Kind(AK_TypeName), String(TN.getName()) {}
     Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
     Arg(SIntMax SInt) : Kind(AK_SInt), SInt(SInt) {}
     Arg(FloatMax Float) : Kind(AK_Float), Float(Float) {}
@@ -202,7 +202,7 @@ public:
   ~Diag();
 
   Diag &operator<<(const char *Str) { return AddArg(Str); }
-  Diag &operator<<(MangledName MN) { return AddArg(MN); }
+  Diag &operator<<(TypeName TN) { return AddArg(TN); }
   Diag &operator<<(unsigned long long V) { return AddArg(UIntMax(V)); }
   Diag &operator<<(const void *V) { return AddArg(V); }
   Diag &operator<<(const TypeDescriptor &V);

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Wed Jul  8 17:10:34 2015
@@ -54,19 +54,19 @@ static void HandleDynamicTypeCacheMiss(
   // If possible, say what type it actually points to.
   if (!DTI.isValid())
     Diag(Pointer, DL_Note, "object has invalid vptr")
-        << MangledName(DTI.getMostDerivedTypeName())
+        << TypeName(DTI.getMostDerivedTypeName())
         << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
   else if (!DTI.getOffset())
     Diag(Pointer, DL_Note, "object is of type %0")
-        << MangledName(DTI.getMostDerivedTypeName())
+        << TypeName(DTI.getMostDerivedTypeName())
         << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
   else
     // FIXME: Find the type at the specified offset, and include that
     //        in the note.
     Diag(Pointer - DTI.getOffset(), DL_Note,
          "object is base class subobject at offset %0 within object of type %1")
-        << DTI.getOffset() << MangledName(DTI.getMostDerivedTypeName())
-        << MangledName(DTI.getSubobjectTypeName())
+        << DTI.getOffset() << TypeName(DTI.getMostDerivedTypeName())
+        << TypeName(DTI.getSubobjectTypeName())
         << Range(Pointer, Pointer + sizeof(uptr),
                  "vptr for %2 base class of %1");
 }
@@ -104,7 +104,7 @@ static void HandleCFIBadType(CFIBadTypeD
     Diag(Vtable, DL_Note, "invalid vtable");
   else
     Diag(Vtable, DL_Note, "vtable is of type %0")
-        << MangledName(DTI.getMostDerivedTypeName());
+        << TypeName(DTI.getMostDerivedTypeName());
 }
 
 void __ubsan::__ubsan_handle_cfi_bad_type(CFIBadTypeData *Data,

Modified: compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc Wed Jul  8 17:10:34 2015
@@ -11,6 +11,9 @@
 // relationships. This file is only linked into C++ compilations, and is
 // permitted to use language features which require a C++ ABI library.
 //
+// Most of the implementation lives in an ABI-specific source file
+// (ubsan_type_hash_{itanium,win}.cc).
+//
 //===----------------------------------------------------------------------===//
 
 #include "ubsan_platform.h"
@@ -19,243 +22,13 @@
 
 #include "sanitizer_common/sanitizer_common.h"
 
-// The following are intended to be binary compatible with the definitions
-// given in the Itanium ABI. We make no attempt to be ODR-compatible with
-// those definitions, since existing ABI implementations aren't.
-
-namespace std {
-  class type_info {
-  public:
-    virtual ~type_info();
-
-    const char *__type_name;
-  };
-}
-
-namespace __cxxabiv1 {
-
-/// Type info for classes with no bases, and base class for type info for
-/// classes with bases.
-class __class_type_info : public std::type_info {
-  ~__class_type_info() override;
-};
-
-/// Type info for classes with simple single public inheritance.
-class __si_class_type_info : public __class_type_info {
-public:
-  ~__si_class_type_info() override;
-
-  const __class_type_info *__base_type;
-};
-
-class __base_class_type_info {
-public:
-  const __class_type_info *__base_type;
-  long __offset_flags;
-
-  enum __offset_flags_masks {
-    __virtual_mask = 0x1,
-    __public_mask = 0x2,
-    __offset_shift = 8
-  };
-};
-
-/// Type info for classes with multiple, virtual, or non-public inheritance.
-class __vmi_class_type_info : public __class_type_info {
-public:
-  ~__vmi_class_type_info() override;
-
-  unsigned int flags;
-  unsigned int base_count;
-  __base_class_type_info base_info[1];
-};
-
-}
-
-namespace abi = __cxxabiv1;
-
-// We implement a simple two-level cache for type-checking results. For each
-// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
-// unique; if it collides, we will get false negatives, but:
-//  * such a collision would have to occur on the *first* bad access,
-//  * the probability of such a collision is low (and for a 64-bit target, is
-//    negligible), and
-//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
-//    give better coverage.
-//
-// The first caching layer is a small hash table with no chaining; buckets are
-// reused as needed. The second caching layer is a large hash table with open
-// chaining. We can freely evict from either layer since this is just a cache.
-//
-// FIXME: Make these hash table accesses thread-safe. The races here are benign:
-//        assuming the unsequenced loads and stores don't misbehave too badly,
-//        the worst case is false negatives or poor cache behavior, not false
-//        positives or crashes.
-
-/// Find a bucket to store the given hash value in.
-static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
-  static const unsigned HashTableSize = 65537;
-  static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize];
-
-  unsigned First = (V & 65535) ^ 1;
-  unsigned Probe = First;
-  for (int Tries = 5; Tries; --Tries) {
-    if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
-      return &__ubsan_vptr_hash_set[Probe];
-    Probe += ((V >> 16) & 65535) + 1;
-    if (Probe >= HashTableSize)
-      Probe -= HashTableSize;
-  }
-  // FIXME: Pick a random entry from the probe sequence to evict rather than
-  //        just taking the first.
-  return &__ubsan_vptr_hash_set[First];
-}
-
 /// A cache of recently-checked hashes. Mini hash table with "random" evictions.
 __ubsan::HashValue
 __ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];
 
-/// \brief Determine whether \p Derived has a \p Base base class subobject at
-/// offset \p Offset.
-static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
-                                  const abi::__class_type_info *Base,
-                                  sptr Offset) {
-  if (Derived->__type_name == Base->__type_name)
-    return Offset == 0;
-
-  if (const abi::__si_class_type_info *SI =
-        dynamic_cast<const abi::__si_class_type_info*>(Derived))
-    return isDerivedFromAtOffset(SI->__base_type, Base, Offset);
-
-  const abi::__vmi_class_type_info *VTI =
-    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
-  if (!VTI)
-    // No base class subobjects.
-    return false;
-
-  // Look for a base class which is derived from \p Base at the right offset.
-  for (unsigned int base = 0; base != VTI->base_count; ++base) {
-    // FIXME: Curtail the recursion if this base can't possibly contain the
-    //        given offset.
-    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
-                      abi::__base_class_type_info::__offset_shift;
-    if (VTI->base_info[base].__offset_flags &
-          abi::__base_class_type_info::__virtual_mask)
-      // For now, just punt on virtual bases and say 'yes'.
-      // FIXME: OffsetHere is the offset in the vtable of the virtual base
-      //        offset. Read the vbase offset out of the vtable and use it.
-      return true;
-    if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
-                              Base, Offset - OffsetHere))
-      return true;
-  }
-
-  return false;
-}
-
-/// \brief Find the derived-most dynamic base class of \p Derived at offset
-/// \p Offset.
-static const abi::__class_type_info *findBaseAtOffset(
-    const abi::__class_type_info *Derived, sptr Offset) {
-  if (!Offset)
-    return Derived;
-
-  if (const abi::__si_class_type_info *SI =
-        dynamic_cast<const abi::__si_class_type_info*>(Derived))
-    return findBaseAtOffset(SI->__base_type, Offset);
-
-  const abi::__vmi_class_type_info *VTI =
-    dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
-  if (!VTI)
-    // No base class subobjects.
-    return 0;
-
-  for (unsigned int base = 0; base != VTI->base_count; ++base) {
-    sptr OffsetHere = VTI->base_info[base].__offset_flags >>
-                      abi::__base_class_type_info::__offset_shift;
-    if (VTI->base_info[base].__offset_flags &
-          abi::__base_class_type_info::__virtual_mask)
-      // FIXME: Can't handle virtual bases yet.
-      continue;
-    if (const abi::__class_type_info *Base =
-          findBaseAtOffset(VTI->base_info[base].__base_type,
-                           Offset - OffsetHere))
-      return Base;
-  }
-
-  return 0;
-}
-
-namespace {
-
-struct VtablePrefix {
-  /// The offset from the vptr to the start of the most-derived object.
-  /// This should never be greater than zero, and will usually be exactly
-  /// zero.
-  sptr Offset;
-  /// The type_info object describing the most-derived class type.
-  std::type_info *TypeInfo;
-};
-VtablePrefix *getVtablePrefix(void *Vtable) {
-  VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
-  if (!Vptr)
-    return 0;
-  VtablePrefix *Prefix = Vptr - 1;
-  if (Prefix->Offset > 0 || !Prefix->TypeInfo)
-    // This can't possibly be a valid vtable.
-    return 0;
-  return Prefix;
-}
-
-}
-
-bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
-  // A crash anywhere within this function probably means the vptr is corrupted.
-  // FIXME: Perform these checks more cautiously.
-
-  // Check whether this is something we've evicted from the cache.
-  HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
-  if (*Bucket == Hash) {
-    __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
-    return true;
-  }
-
-  void *VtablePtr = *reinterpret_cast<void **>(Object);
-  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
-  if (!Vtable)
-    return false;
-
-  // Check that this is actually a type_info object for a class type.
-  abi::__class_type_info *Derived =
-    dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
-  if (!Derived)
-    return false;
-
-  abi::__class_type_info *Base = (abi::__class_type_info*)Type;
-  if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
-    return false;
-
-  // Success. Cache this result.
-  __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
-  *Bucket = Hash;
-  return true;
-}
-
 __ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfoFromObject(void *Object) {
   void *VtablePtr = *reinterpret_cast<void **>(Object);
   return getDynamicTypeInfoFromVtable(VtablePtr);
 }
 
-__ubsan::DynamicTypeInfo
-__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
-  VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
-  if (!Vtable)
-    return DynamicTypeInfo(0, 0, 0);
-  const abi::__class_type_info *ObjectType = findBaseAtOffset(
-    static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),
-    -Vtable->Offset);
-  return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,
-                         ObjectType ? ObjectType->__type_name : "<unknown>");
-}
-
 #endif  // CAN_SANITIZE_UB

Copied: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc (from r241571, compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc?p2=compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc&p1=compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc&r1=241571&r2=241745&rev=241745&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc Wed Jul  8 17:10:34 2015
@@ -1,4 +1,4 @@
-//===-- ubsan_type_hash.cc ------------------------------------------------===//
+//===-- ubsan_type_hash_itanium.cc ----------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,14 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Implementation of a hash table for fast checking of inheritance
-// relationships. This file is only linked into C++ compilations, and is
-// permitted to use language features which require a C++ ABI library.
+// Implementation of type hashing/lookup for Itanium C++ ABI.
 //
 //===----------------------------------------------------------------------===//
 
+#include "sanitizer_common/sanitizer_platform.h"
 #include "ubsan_platform.h"
-#if CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB && !SANITIZER_WINDOWS
 #include "ubsan_type_hash.h"
 
 #include "sanitizer_common/sanitizer_common.h"
@@ -111,10 +110,6 @@ static __ubsan::HashValue *getTypeCacheH
   return &__ubsan_vptr_hash_set[First];
 }
 
-/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
-__ubsan::HashValue
-__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize];
-
 /// \brief Determine whether \p Derived has a \p Base base class subobject at
 /// offset \p Offset.
 static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
@@ -241,11 +236,6 @@ bool __ubsan::checkDynamicType(void *Obj
   return true;
 }
 
-__ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfoFromObject(void *Object) {
-  void *VtablePtr = *reinterpret_cast<void **>(Object);
-  return getDynamicTypeInfoFromVtable(VtablePtr);
-}
-
 __ubsan::DynamicTypeInfo
 __ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
   VtablePrefix *Vtable = getVtablePrefix(VtablePtr);
@@ -258,4 +248,4 @@ __ubsan::getDynamicTypeInfoFromVtable(vo
                          ObjectType ? ObjectType->__type_name : "<unknown>");
 }
 
-#endif  // CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS

Added: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc?rev=241745&view=auto
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc (added)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc Wed Jul  8 17:10:34 2015
@@ -0,0 +1,72 @@
+//===-- ubsan_type_hash_win.cc --------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of type hashing/lookup for Microsoft C++ ABI.
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_platform.h"
+#include "ubsan_platform.h"
+#if CAN_SANITIZE_UB && SANITIZER_WINDOWS
+#include "ubsan_type_hash.h"
+
+#include "sanitizer_common/sanitizer_common.h"
+
+#include <typeinfo>
+#include <windows.h>
+
+struct CompleteObjectLocator {
+  int is_image_relative;
+  int offset_to_top;
+  int vfptr_offset;
+};
+
+bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
+  // FIXME: Implement.
+  return false;
+}
+
+__ubsan::DynamicTypeInfo
+__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
+  // The virtual table may not have a complete object locator if the object
+  // was compiled without RTTI (i.e. we might be reading from some other global
+  // laid out before the virtual table), so we need to carefully validate each
+  // pointer dereference and perform sanity checks.
+  CompleteObjectLocator **obj_locator_ptr =
+    ((CompleteObjectLocator**)VtablePtr)-1;
+  if (!IsAccessibleMemoryRange((uptr)obj_locator_ptr, sizeof(void*)))
+    return DynamicTypeInfo(0, 0, 0);
+
+  CompleteObjectLocator *obj_locator = *obj_locator_ptr;
+  if (!IsAccessibleMemoryRange((uptr)obj_locator,
+                               sizeof(CompleteObjectLocator)+sizeof(void*)))
+    return DynamicTypeInfo(0, 0, 0);
+
+  std::type_info *tinfo;
+  if (obj_locator->is_image_relative == 1) {
+    MEMORY_BASIC_INFORMATION mbi;
+    VirtualQuery(obj_locator, &mbi, sizeof(mbi));
+    tinfo = (std::type_info*)(*(int*)(obj_locator+1) +
+                              (char*)mbi.AllocationBase);
+  } else if (obj_locator->is_image_relative == 0)
+    tinfo = *(std::type_info**)(obj_locator+1);
+  else
+    // Probably not a complete object locator.
+    return DynamicTypeInfo(0, 0, 0);
+
+  if (!IsAccessibleMemoryRange((uptr)tinfo, sizeof(std::type_info)))
+    return DynamicTypeInfo(0, 0, 0);
+
+  // Okay, this is probably a std::type_info. Request its name.
+  // FIXME: Implement a base class search like we do for Itanium.
+  return DynamicTypeInfo(tinfo->name(), obj_locator->offset_to_top,
+                         "<unknown>");
+}
+
+#endif  // CAN_SANITIZE_UB && SANITIZER_WINDOWS

Modified: compiler-rt/trunk/test/cfi/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/CMakeLists.txt?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/CMakeLists.txt (original)
+++ compiler-rt/trunk/test/cfi/CMakeLists.txt Wed Jul  8 17:10:34 2015
@@ -21,6 +21,11 @@ if(NOT COMPILER_RT_STANDALONE_BUILD)
       LTO
     )
   endif()
+  if(WIN32 AND EXISTS ${CMAKE_SOURCE_DIR}/tools/lld)
+    list(APPEND CFI_TEST_DEPS
+      lld
+    )
+  endif()
 endif()
 
 add_lit_testsuite(check-cfi "Running the cfi regression tests"

Modified: compiler-rt/trunk/test/cfi/anon-namespace.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/anon-namespace.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/anon-namespace.cpp (original)
+++ compiler-rt/trunk/test/cfi/anon-namespace.cpp Wed Jul  8 17:10:34 2015
@@ -1,32 +1,32 @@
 // RUN: %clangxx_cfi -c -DTU1 -o %t1.o %s
 // RUN: %clangxx_cfi -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %t1.o %t2.o
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
 
 // RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s
 // RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t2 %t1.o %t2.o
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
 
 // RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s
 // RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t3 %t1.o %t2.o
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
 
 // RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s
 // RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi -o %t %t1.o %t2.o
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t4 %t1.o %t2.o
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
 
 // RUN: %clangxx -c -DTU1 -o %t1.o %s
 // RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx -o %t %t1.o %t2.o
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %t1.o %t2.o
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
 
 // RUN: %clangxx_cfi_diag -c -DTU1 -o %t1.o %s
 // RUN: %clangxx_cfi_diag -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp
-// RUN: %clangxx_cfi_diag -o %t %t1.o %t2.o
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %t1.o %t2.o
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
 // Tests that the CFI mechanism treats classes in the anonymous namespace in
 // different translation units as having distinct identities. This is done by
@@ -91,13 +91,13 @@ int main() {
   fprintf(stderr, "1\n");
 
   // CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during base-to-derived cast
-  // CFI-DIAG-NEXT: note: vtable is of type '(anonymous namespace)::B'
+  // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B'
   // CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during virtual call
-  // CFI-DIAG-NEXT: note: vtable is of type '(anonymous namespace)::B'
+  // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B'
   ((B *)a)->f(); // UB here
 
-  // CFI-NOT: 2
-  // NCFI: 2
+  // CFI-NOT: {{^2$}}
+  // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
 }
 

Modified: compiler-rt/trunk/test/cfi/bad-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/bad-cast.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/bad-cast.cpp (original)
+++ compiler-rt/trunk/test/cfi/bad-cast.cpp Wed Jul  8 17:10:34 2015
@@ -1,68 +1,68 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t %s
-// RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t d 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t e 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t f 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s
-// RUN: not --crash %t h 2>&1 | FileCheck --check-prefix=FAIL %s
-
-// RUN: %clangxx -o %t %s
-// RUN: %t a 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t b 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t c 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t g 2>&1 | FileCheck --check-prefix=PASS %s
-// RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s
-
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
-// RUN: %t b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
-// RUN: %t c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
-// RUN: %t g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t1 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t1 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t1 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t1 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t1 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t1 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t1 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t2 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t2 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t2 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t2 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t2 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t2 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t2 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t3 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t3 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t3 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t3 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t3 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t3 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t3 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t4 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t4 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t4 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t4 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t4 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %expect_crash %t4 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %t4 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t5 %s
+// RUN: %expect_crash %t5 a 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 b 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 c 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 d 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 e 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 f 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 g 2>&1 | FileCheck --check-prefix=FAIL %s
+// RUN: %expect_crash %t5 h 2>&1 | FileCheck --check-prefix=FAIL %s
+
+// RUN: %clangxx -o %t6 %s
+// RUN: %t6 a 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 b 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 c 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 d 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 e 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 f 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 g 2>&1 | FileCheck --check-prefix=PASS %s
+// RUN: %t6 h 2>&1 | FileCheck --check-prefix=PASS %s
+
+// RUN: %clangxx_cfi_diag -o %t7 %s
+// RUN: %t7 a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
+// RUN: %t7 b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
+// RUN: %t7 c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
+// RUN: %t7 g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s
 
 // Tests that the CFI enforcement detects bad casts.
 
@@ -112,10 +112,10 @@ int main(int argc, char **argv) {
   A a;
 
   // CFI-DIAG-D: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast
-  // CFI-DIAG-D-NEXT: note: vtable is of type 'A'
+  // CFI-DIAG-D-NEXT: note: vtable is of type '{{(struct )?}}A'
 
   // CFI-DIAG-U: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
-  // CFI-DIAG-U-NEXT: note: vtable is of type 'A'
+  // CFI-DIAG-U-NEXT: note: vtable is of type '{{(struct )?}}A'
 
   switch (argv[1][0]) {
     case 'a':
@@ -144,7 +144,7 @@ int main(int argc, char **argv) {
       break;
   }
 
-  // FAIL-NOT: 2
-  // PASS: 2
+  // FAIL-NOT: {{^2$}}
+  // PASS: {{^2$}}
   fprintf(stderr, "2\n");
 }

Modified: compiler-rt/trunk/test/cfi/multiple-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/multiple-inheritance.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/multiple-inheritance.cpp (original)
+++ compiler-rt/trunk/test/cfi/multiple-inheritance.cpp Wed Jul  8 17:10:34 2015
@@ -1,26 +1,26 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
-// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s
-
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
-// RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s
-
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG2 %s
-// RUN: %t x 2>&1 | FileCheck --check-prefix=CFI-DIAG1 %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t1 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t2 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t3 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %expect_crash %t4 x 2>&1 | FileCheck --check-prefix=CFI %s
+
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %t5 x 2>&1 | FileCheck --check-prefix=NCFI %s
+
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG2 %s
+// RUN: %t6 x 2>&1 | FileCheck --check-prefix=CFI-DIAG1 %s
 
 // Tests that the CFI mechanism is sensitive to multiple inheritance and only
 // permits calls via virtual tables for the correct base class.
@@ -77,16 +77,16 @@ int main(int argc, char **argv) {
   if (argc > 1) {
     A *a = c;
     // CFI-DIAG1: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
-    // CFI-DIAG1-NEXT: note: vtable is of type 'C'
+    // CFI-DIAG1-NEXT: note: vtable is of type '{{(struct )?}}C'
     ((B *)a)->g(); // UB here
   } else {
     // CFI-DIAG2: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
-    // CFI-DIAG2-NEXT: note: vtable is of type 'C'
+    // CFI-DIAG2-NEXT: note: vtable is of type '{{(struct )?}}C'
     B *b = c;
     ((A *)b)->f(); // UB here
   }
 
-  // CFI-NOT: 2
-  // NCFI: 2
+  // CFI-NOT: {{^2$}}
+  // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
 }

Modified: compiler-rt/trunk/test/cfi/nvcall.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/nvcall.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/nvcall.cpp (original)
+++ compiler-rt/trunk/test/cfi/nvcall.cpp Wed Jul  8 17:10:34 2015
@@ -1,20 +1,20 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
 
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
 // Tests that the CFI mechanism crashes the program when making a non-virtual
 // call to an object of the wrong class, by casting a pointer to such an object
@@ -63,10 +63,10 @@ int main() {
   fprintf(stderr, "1\n");
 
   // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during non-virtual call
-  // CFI-DIAG-NEXT: note: vtable is of type 'A'
+  // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
   ((B *)a)->f(); // UB here
 
-  // CFI-NOT: 2
-  // NCFI: 2
+  // CFI-NOT: {{^2$}}
+  // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
 }

Modified: compiler-rt/trunk/test/cfi/overwrite.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/overwrite.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/overwrite.cpp (original)
+++ compiler-rt/trunk/test/cfi/overwrite.cpp Wed Jul  8 17:10:34 2015
@@ -1,20 +1,20 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
 
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
 // Tests that the CFI mechanism crashes the program when a virtual table is
 // replaced with a compatible table of function pointers that does not belong to
@@ -68,7 +68,7 @@ int main() {
   // CFI-DIAG-NEXT: note: invalid vtable
   a->f();
 
-  // CFI-NOT: 2
-  // NCFI: 2
+  // CFI-NOT: {{^2$}}
+  // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
 }

Modified: compiler-rt/trunk/test/cfi/sibling.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/sibling.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/sibling.cpp (original)
+++ compiler-rt/trunk/test/cfi/sibling.cpp Wed Jul  8 17:10:34 2015
@@ -1,19 +1,19 @@
 // XFAIL: *
 
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
 
 // Tests that the CFI enforcement distinguishes betwen non-overriding siblings.
 // XFAILed as not implemented yet.

Modified: compiler-rt/trunk/test/cfi/simple-fail.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/simple-fail.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/simple-fail.cpp (original)
+++ compiler-rt/trunk/test/cfi/simple-fail.cpp Wed Jul  8 17:10:34 2015
@@ -1,56 +1,56 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O1 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -o %t5 %s
+// RUN: %expect_crash %t5 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O1 -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s
+// RUN: %expect_crash %t6 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O1 -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s
+// RUN: %expect_crash %t7 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O1 -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O1 -DBM -o %t8 %s
+// RUN: %expect_crash %t8 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O2 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -o %t9 %s
+// RUN: %expect_crash %t9 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O2 -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s
+// RUN: %expect_crash %t10 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O2 -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s
+// RUN: %expect_crash %t11 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O2 -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O2 -DBM -o %t12 %s
+// RUN: %expect_crash %t12 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O3 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -o %t13 %s
+// RUN: %expect_crash %t13 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O3 -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s
+// RUN: %expect_crash %t14 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O3 -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s
+// RUN: %expect_crash %t15 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -O3 -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -O3 -DBM -o %t16 %s
+// RUN: %expect_crash %t16 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t17 %s
+// RUN: %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t18 %s
+// RUN: %t18 2>&1 | FileCheck --check-prefix=NCFI %s
 
 // Tests that the CFI mechanism crashes the program when making a virtual call
 // to an object of the wrong class but with a compatible vtable, by casting a
@@ -97,12 +97,12 @@ int main() {
   fprintf(stderr, "1\n");
 
   // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
-  // CFI-DIAG-NEXT: note: vtable is of type 'A'
+  // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
   // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call
-  // CFI-DIAG-NEXT: note: vtable is of type 'A'
+  // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
   ((B *)a)->f(); // UB here
 
-  // CFI-NOT: 2
-  // NCFI: 2
+  // CFI-NOT: {{^2$}}
+  // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
 }

Modified: compiler-rt/trunk/test/cfi/vdtor.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/vdtor.cpp?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/cfi/vdtor.cpp (original)
+++ compiler-rt/trunk/test/cfi/vdtor.cpp Wed Jul  8 17:10:34 2015
@@ -1,20 +1,20 @@
-// RUN: %clangxx_cfi -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -o %t1 %s
+// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB32 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB32 -o %t2 %s
+// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DB64 -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DB64 -o %t3 %s
+// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx_cfi -DBM -o %t %s
-// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
+// RUN: %clangxx_cfi -DBM -o %t4 %s
+// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
 
-// RUN: %clangxx -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
+// RUN: %clangxx -o %t5 %s
+// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
 
-// RUN: %clangxx_cfi_diag -o %t %s
-// RUN: %t 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %clangxx_cfi_diag -o %t6 %s
+// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
 // Tests that the CFI enforcement also applies to virtual destructor calls made
 // via 'delete'.
@@ -60,10 +60,10 @@ int main() {
   fprintf(stderr, "1\n");
 
   // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call
-  // CFI-DIAG-NEXT: note: vtable is of type 'A'
+  // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
   delete (B *)a; // UB here
 
-  // CFI-NOT: 2
-  // NCFI: 2
+  // CFI-NOT: {{^2$}}
+  // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
 }

Modified: compiler-rt/trunk/test/lit.common.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lit.common.cfg?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/lit.common.cfg (original)
+++ compiler-rt/trunk/test/lit.common.cfg Wed Jul  8 17:10:34 2015
@@ -121,13 +121,20 @@ def is_linux_lto_supported():
 
   return True
 
-if sys.platform == 'darwin' and is_darwin_lto_supported():
+def is_windows_lto_supported():
+  return os.path.exists(os.path.join(config.llvm_tools_dir, 'lld-link2.exe'))
+
+if config.host_os == 'Darwin' and is_darwin_lto_supported():
   config.lto_supported = True
   config.lto_launch = ["env", "DYLD_LIBRARY_PATH=" + config.llvm_shlib_dir]
   config.lto_flags = []
-elif sys.platform.startswith('linux') and is_linux_lto_supported():
+elif config.host_os == 'Linux' and is_linux_lto_supported():
   config.lto_supported = True
   config.lto_launch = []
   config.lto_flags = ["-fuse-ld=gold"]
+elif config.host_os == 'Windows' and is_windows_lto_supported():
+  config.lto_supported = True
+  config.lto_launch = []
+  config.lto_flags = ["-fuse-ld=lld-link2"]
 else:
   config.lto_supported = False

Modified: compiler-rt/trunk/test/ubsan/lit.common.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/lit.common.cfg?rev=241745&r1=241744&r2=241745&view=diff
==============================================================================
--- compiler-rt/trunk/test/ubsan/lit.common.cfg (original)
+++ compiler-rt/trunk/test/ubsan/lit.common.cfg Wed Jul  8 17:10:34 2015
@@ -54,6 +54,11 @@ config.suffixes = ['.c', '.cc', '.cpp']
 if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows']:
   config.unsupported = True
 
+if config.host_os == 'Windows':
+  # We do not currently support enough of the Microsoft ABI for UBSan to work on
+  # Windows.
+  config.available_features.remove('cxxabi')
+
 # Allow tests to use REQUIRES=stable-runtime.  For use when you cannot use XFAIL
 # because the test hangs or fails on one configuration and not the other.
 if config.target_arch.startswith('arm') == False:





More information about the llvm-commits mailing list