[compiler-rt] r230026 - [Sanitizer] Refactor SuppressionContext class.

Alexey Samsonov vonosmas at gmail.com
Fri Feb 20 09:42:00 PST 2015


Author: samsonov
Date: Fri Feb 20 11:41:59 2015
New Revision: 230026

URL: http://llvm.org/viewvc/llvm-project?rev=230026&view=rev
Log:
[Sanitizer] Refactor SuppressionContext class.

SuppressionContext is no longer a singleton, shared by all sanitizers,
but a regular class. Each of ASan, LSan, UBSan and TSan now have their
own SuppressionContext, which only parses suppressions specific to
that sanitizer.

"suppressions" flag is moved away from common flags into tool-specific
flags, so the user now may pass
  ASAN_OPTIONS=suppressions=asan_supp.txt LSAN_OPIONS=suppressions=lsan_supp.txt
in a single invocation.

Modified:
    compiler-rt/trunk/lib/asan/asan_flags.inc
    compiler-rt/trunk/lib/asan/asan_suppressions.cc
    compiler-rt/trunk/lib/lsan/lsan_common.cc
    compiler-rt/trunk/lib/lsan/lsan_flags.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h
    compiler-rt/trunk/lib/ubsan/ubsan_diag.cc
    compiler-rt/trunk/lib/ubsan/ubsan_diag.h
    compiler-rt/trunk/lib/ubsan/ubsan_flags.inc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
    compiler-rt/trunk/lib/ubsan/ubsan_init.cc
    compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp

Modified: compiler-rt/trunk/lib/asan/asan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.inc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.inc (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.inc Fri Feb 20 11:41:59 2015
@@ -142,3 +142,4 @@ ASAN_FLAG(int, detect_odr_violation, 2,
           "have different sizes")
 ASAN_FLAG(bool, dump_instruction_bytes, false,
           "If true, dump 16 bytes starting at the instruction that caused SEGV")
+ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")

Modified: compiler-rt/trunk/lib/asan/asan_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_suppressions.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_suppressions.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_suppressions.cc Fri Feb 20 11:41:59 2015
@@ -15,57 +15,62 @@
 #include "asan_suppressions.h"
 
 #include "asan_stack.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_suppressions.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 
 namespace __asan {
 
-static bool suppressions_inited = false;
+ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];
+static SuppressionContext *suppression_ctx = nullptr;
+static const char kInterceptorName[] = "interceptor_name";
+static const char kInterceptorViaFunction[] = "interceptor_via_fun";
+static const char kInterceptorViaLibrary[] = "interceptor_via_lib";
+static const char *kSuppressionTypes[] = {
+    kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary};
 
 void InitializeSuppressions() {
-  CHECK(!suppressions_inited);
-  SuppressionContext::InitIfNecessary();
-  suppressions_inited = true;
+  CHECK_EQ(nullptr, suppression_ctx);
+  suppression_ctx = new (suppression_placeholder)  // NOLINT
+      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
+  suppression_ctx->ParseFromFile(flags()->suppressions);
 }
 
 bool IsInterceptorSuppressed(const char *interceptor_name) {
-  CHECK(suppressions_inited);
-  SuppressionContext *ctx = SuppressionContext::Get();
+  CHECK(suppression_ctx);
   Suppression *s;
   // Match "interceptor_name" suppressions.
-  return ctx->Match(interceptor_name, SuppressionInterceptorName, &s);
+  return suppression_ctx->Match(interceptor_name, kInterceptorName, &s);
 }
 
 bool HaveStackTraceBasedSuppressions() {
-  CHECK(suppressions_inited);
-  SuppressionContext *ctx = SuppressionContext::Get();
-  return ctx->HasSuppressionType(SuppressionInterceptorViaFunction) ||
-         ctx->HasSuppressionType(SuppressionInterceptorViaLibrary);
+  CHECK(suppression_ctx);
+  return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) ||
+         suppression_ctx->HasSuppressionType(kInterceptorViaLibrary);
 }
 
 bool IsStackTraceSuppressed(const StackTrace *stack) {
-  CHECK(suppressions_inited);
   if (!HaveStackTraceBasedSuppressions())
     return false;
 
-  SuppressionContext *ctx = SuppressionContext::Get();
+  CHECK(suppression_ctx);
   Symbolizer *symbolizer = Symbolizer::GetOrInit();
   Suppression *s;
   for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {
     uptr addr = stack->trace[i];
 
-    if (ctx->HasSuppressionType(SuppressionInterceptorViaLibrary)) {
+    if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) {
       const char *module_name;
       uptr module_offset;
       // Match "interceptor_via_lib" suppressions.
       if (symbolizer->GetModuleNameAndOffsetForPC(addr, &module_name,
                                                   &module_offset) &&
-          ctx->Match(module_name, SuppressionInterceptorViaLibrary, &s)) {
+          suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s)) {
         return true;
       }
     }
 
-    if (ctx->HasSuppressionType(SuppressionInterceptorViaFunction)) {
+    if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) {
       SymbolizedStack *frames = symbolizer->SymbolizePC(addr);
       for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
         const char *function_name = cur->info.function;
@@ -73,7 +78,8 @@ bool IsStackTraceSuppressed(const StackT
           continue;
         }
         // Match "interceptor_via_fun" suppressions.
-        if (ctx->Match(function_name, SuppressionInterceptorViaFunction, &s)) {
+        if (suppression_ctx->Match(function_name, kInterceptorViaFunction,
+                                   &s)) {
           frames->ClearAll();
           return true;
         }

Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Fri Feb 20 11:41:59 2015
@@ -60,14 +60,23 @@ void RegisterLsanFlags(FlagParser *parse
     if (flags()->log_threads) Report(__VA_ARGS__); \
   } while (0);
 
-static bool suppressions_inited = false;
+ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];
+static SuppressionContext *suppression_ctx = nullptr;
+static const char kSuppressionLeak[] = "leak";
+static const char *kSuppressionTypes[] = { kSuppressionLeak };
 
 void InitializeSuppressions() {
-  CHECK(!suppressions_inited);
-  SuppressionContext::InitIfNecessary();
+  CHECK_EQ(nullptr, suppression_ctx);
+  suppression_ctx = new (suppression_placeholder) // NOLINT
+      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
+  suppression_ctx->ParseFromFile(flags()->suppressions);
   if (&__lsan_default_suppressions)
-    SuppressionContext::Get()->Parse(__lsan_default_suppressions());
-  suppressions_inited = true;
+    suppression_ctx->Parse(__lsan_default_suppressions());
+}
+
+static SuppressionContext *GetSuppressionContext() {
+  CHECK(suppression_ctx);
+  return suppression_ctx;
 }
 
 struct RootRegion {
@@ -350,7 +359,7 @@ static void CollectLeaksCb(uptr chunk, v
 
 static void PrintMatchedSuppressions() {
   InternalMmapVector<Suppression *> matched(1);
-  SuppressionContext::Get()->GetMatched(&matched);
+  GetSuppressionContext()->GetMatched(&matched);
   if (!matched.size())
     return;
   const char *line = "-----------------------------------------------------";
@@ -429,17 +438,17 @@ static Suppression *GetSuppressionForAdd
   // Suppress by module name.
   const char *module_name;
   uptr module_offset;
+  SuppressionContext *suppressions = GetSuppressionContext();
   if (Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC(addr, &module_name,
                                                            &module_offset) &&
-      SuppressionContext::Get()->Match(module_name, SuppressionLeak, &s))
+      suppressions->Match(module_name, kSuppressionLeak, &s))
     return s;
 
   // Suppress by file or function name.
   SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr);
   for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
-    if (SuppressionContext::Get()->Match(cur->info.function, SuppressionLeak,
-                                         &s) ||
-        SuppressionContext::Get()->Match(cur->info.file, SuppressionLeak, &s)) {
+    if (suppressions->Match(cur->info.function, kSuppressionLeak, &s) ||
+        suppressions->Match(cur->info.file, kSuppressionLeak, &s)) {
       break;
     }
   }

Modified: compiler-rt/trunk/lib/lsan/lsan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_flags.inc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_flags.inc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_flags.inc Fri Feb 20 11:41:59 2015
@@ -42,3 +42,4 @@ LSAN_FLAG(bool, use_poisoned, false,
           "Consider pointers found in poisoned memory to be valid.")
 LSAN_FLAG(bool, log_pointers, false, "Debug logging")
 LSAN_FLAG(bool, log_threads, false, "Debug logging")
+LSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc Fri Feb 20 11:41:59 2015
@@ -128,7 +128,6 @@ COMMON_FLAG(const char *, coverage_dir,
 COMMON_FLAG(bool, full_address_space, false,
             "Sanitize complete address space; "
             "by default kernel area on 32-bit platforms will not be sanitized")
-COMMON_FLAG(const char *, suppressions, "", "Suppressions file name.")
 COMMON_FLAG(bool, print_suppressions, true,
             "Print matched suppressions at exit.")
 COMMON_FLAG(

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc Fri Feb 20 11:41:59 2015
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Suppression parsing/matching code shared between TSan and LSan.
+// Suppression parsing/matching code.
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,55 +21,43 @@
 
 namespace __sanitizer {
 
-static const char *const kTypeStrings[SuppressionTypeCount] = {
-    "none", "race", "mutex", "thread", "signal", "leak", "called_from_lib",
-    "deadlock", "vptr_check", "interceptor_name", "interceptor_via_fun",
-    "interceptor_via_lib"};
-
-ALIGNED(64) static char placeholder[sizeof(SuppressionContext)];
-static SuppressionContext *suppression_ctx = 0;
-
-SuppressionContext::SuppressionContext() : suppressions_(1), can_parse_(true) {
-  internal_memset(has_suppresson_type_, 0, sizeof(has_suppresson_type_));
-}
-
-SuppressionContext *SuppressionContext::Get() {
-  CHECK(suppression_ctx);
-  return suppression_ctx;
+SuppressionContext::SuppressionContext(const char *suppression_types[],
+                                       int suppression_types_num)
+    : suppression_types_(suppression_types),
+      suppression_types_num_(suppression_types_num), suppressions_(1),
+      can_parse_(true) {
+  CHECK_LE(suppression_types_num_, kMaxSuppressionTypes);
+  internal_memset(has_suppression_type_, 0, suppression_types_num_);
 }
 
-void SuppressionContext::InitIfNecessary() {
-  if (suppression_ctx)
+void SuppressionContext::ParseFromFile(const char *filename) {
+  if (filename[0] == '\0')
     return;
-  suppression_ctx = new(placeholder) SuppressionContext;
-  if (common_flags()->suppressions[0] == '\0')
-    return;
-  char *suppressions_from_file;
+  char *file_contents;
   uptr buffer_size;
-  uptr contents_size =
-      ReadFileToBuffer(common_flags()->suppressions, &suppressions_from_file,
-                       &buffer_size, 1 << 26 /* max_len */);
+  uptr contents_size = ReadFileToBuffer(filename, &file_contents, &buffer_size,
+                                        1 << 26 /* max_len */);
   if (contents_size == 0) {
     Printf("%s: failed to read suppressions file '%s'\n", SanitizerToolName,
-           common_flags()->suppressions);
+           filename);
     Die();
   }
-  suppression_ctx->Parse(suppressions_from_file);
+  Parse(file_contents);
 }
 
-bool SuppressionContext::Match(const char *str, SuppressionType type,
+bool SuppressionContext::Match(const char *str, const char *type,
                                Suppression **s) {
-  if (!has_suppresson_type_[type])
-    return false;
   can_parse_ = false;
-  uptr i;
-  for (i = 0; i < suppressions_.size(); i++)
-    if (type == suppressions_[i].type &&
-        TemplateMatch(suppressions_[i].templ, str))
-      break;
-  if (i == suppressions_.size()) return false;
-  *s = &suppressions_[i];
-  return true;
+  if (!HasSuppressionType(type))
+    return false;
+  for (uptr i = 0; i < suppressions_.size(); i++) {
+    Suppression &cur = suppressions_[i];
+    if (0 == internal_strcmp(cur.type, type) && TemplateMatch(cur.templ, str)) {
+      *s = &cur;
+      return true;
+    }
+  }
+  return false;
 }
 
 static const char *StripPrefix(const char *str, const char *prefix) {
@@ -97,26 +85,26 @@ void SuppressionContext::Parse(const cha
       while (line != end2 && (end2[-1] == ' ' || end2[-1] == '\t'))
         end2--;
       int type;
-      for (type = 0; type < SuppressionTypeCount; type++) {
-        const char *next_char = StripPrefix(line, kTypeStrings[type]);
+      for (type = 0; type < suppression_types_num_; type++) {
+        const char *next_char = StripPrefix(line, suppression_types_[type]);
         if (next_char && *next_char == ':') {
           line = ++next_char;
           break;
         }
       }
-      if (type == SuppressionTypeCount) {
+      if (type == suppression_types_num_) {
         Printf("%s: failed to parse suppressions\n", SanitizerToolName);
         Die();
       }
       Suppression s;
-      s.type = static_cast<SuppressionType>(type);
+      s.type = suppression_types_[type];
       s.templ = (char*)InternalAlloc(end2 - line + 1);
       internal_memcpy(s.templ, line, end2 - line);
       s.templ[end2 - line] = 0;
       s.hit_count = 0;
       s.weight = 0;
       suppressions_.push_back(s);
-      has_suppresson_type_[s.type] = true;
+      has_suppression_type_[type] = true;
     }
     if (end[0] == 0)
       break;
@@ -128,8 +116,12 @@ uptr SuppressionContext::SuppressionCoun
   return suppressions_.size();
 }
 
-bool SuppressionContext::HasSuppressionType(SuppressionType type) const {
-  return has_suppresson_type_[type];
+bool SuppressionContext::HasSuppressionType(const char *type) const {
+  for (int i = 0; i < suppression_types_num_; i++) {
+    if (0 == internal_strcmp(type, suppression_types_[i]))
+      return has_suppression_type_[i];
+  }
+  return false;
 }
 
 const Suppression *SuppressionContext::SuppressionAt(uptr i) const {
@@ -144,9 +136,4 @@ void SuppressionContext::GetMatched(
       matched->push_back(&suppressions_[i]);
 }
 
-const char *SuppressionTypeString(SuppressionType t) {
-  CHECK(t < SuppressionTypeCount);
-  return kTypeStrings[t];
-}
-
 }  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h Fri Feb 20 11:41:59 2015
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Suppression parsing/matching code shared between TSan and LSan.
+// Suppression parsing/matching code.
 //
 //===----------------------------------------------------------------------===//
 #ifndef SANITIZER_SUPPRESSIONS_H
@@ -18,24 +18,8 @@
 
 namespace __sanitizer {
 
-enum SuppressionType {
-  SuppressionNone,
-  SuppressionRace,
-  SuppressionMutex,
-  SuppressionThread,
-  SuppressionSignal,
-  SuppressionLeak,
-  SuppressionLib,
-  SuppressionDeadlock,
-  SuppressionVptrCheck,
-  SuppressionInterceptorName,
-  SuppressionInterceptorViaFunction,
-  SuppressionInterceptorViaLibrary,
-  SuppressionTypeCount
-};
-
 struct Suppression {
-  SuppressionType type;
+  const char *type;
   char *templ;
   unsigned hit_count;
   uptr weight;
@@ -43,31 +27,29 @@ struct Suppression {
 
 class SuppressionContext {
  public:
+  // Create new SuppressionContext capable of parsing given suppression types.
+  SuppressionContext(const char *supprression_types[],
+                     int suppression_types_num);
+
+  void ParseFromFile(const char *filename);
   void Parse(const char *str);
-  bool Match(const char* str, SuppressionType type, Suppression **s);
+
+  bool Match(const char *str, const char *type, Suppression **s);
   uptr SuppressionCount() const;
-  bool HasSuppressionType(SuppressionType type) const;
+  bool HasSuppressionType(const char *type) const;
   const Suppression *SuppressionAt(uptr i) const;
   void GetMatched(InternalMmapVector<Suppression *> *matched);
 
-  // Create a SuppressionContext singleton if it hasn't been created earlier.
-  // Not thread safe. Must be called early during initialization (but after
-  // runtime flags are parsed).
-  static void InitIfNecessary();
-  // Returns a SuppressionContext singleton.
-  static SuppressionContext *Get();
-
  private:
-  SuppressionContext();
+  static const int kMaxSuppressionTypes = 16;
+  const char **const suppression_types_;
+  const int suppression_types_num_;
+
   InternalMmapVector<Suppression> suppressions_;
-  bool has_suppresson_type_[SuppressionTypeCount];
+  bool has_suppression_type_[kMaxSuppressionTypes];
   bool can_parse_;
-
-  friend class SuppressionContextTest;
 };
 
-const char *SuppressionTypeString(SuppressionType t);
-
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_SUPPRESSIONS_H

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc Fri Feb 20 11:41:59 2015
@@ -58,117 +58,77 @@ TEST(Suppressions, Match) {
   EXPECT_FALSE(MyMatch("foo$^bar", "foobar"));
 }
 
-TEST(Suppressions, TypeStrings) {
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionNone), "none"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionRace), "race"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionMutex), "mutex"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionThread), "thread"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionSignal), "signal"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionLeak), "leak"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionLib),
-                         "called_from_lib"));
-  CHECK(
-      !internal_strcmp(SuppressionTypeString(SuppressionDeadlock), "deadlock"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionVptrCheck),
-                         "vptr_check"));
-  CHECK(!internal_strcmp(SuppressionTypeString(SuppressionInterceptorName),
-                         "interceptor_name"));
-  CHECK(
-      !internal_strcmp(SuppressionTypeString(SuppressionInterceptorViaFunction),
-                       "interceptor_via_fun"));
-  CHECK(
-      !internal_strcmp(SuppressionTypeString(SuppressionInterceptorViaLibrary),
-                       "interceptor_via_lib"));
-  // Ensure this test is up-to-date when suppression types are added.
-  CHECK_EQ(12, SuppressionTypeCount);
-}
+static const char *kTestSuppressionTypes[] = {"race", "thread", "mutex",
+                                              "signal"};
 
 class SuppressionContextTest : public ::testing::Test {
  public:
-  virtual void SetUp() { ctx_ = new(placeholder_) SuppressionContext; }
-  virtual void TearDown() { ctx_->~SuppressionContext(); }
+  SuppressionContextTest()
+      : ctx_(kTestSuppressionTypes, ARRAY_SIZE(kTestSuppressionTypes)) {}
 
  protected:
-  InternalMmapVector<Suppression> *Suppressions() {
-    return &ctx_->suppressions_;
+  SuppressionContext ctx_;
+
+  void CheckSuppressions(unsigned count, std::vector<const char *> types,
+                         std::vector<const char *> templs) const {
+    EXPECT_EQ(count, ctx_.SuppressionCount());
+    for (unsigned i = 0; i < count; i++) {
+      const Suppression *s = ctx_.SuppressionAt(i);
+      EXPECT_STREQ(types[i], s->type);
+      EXPECT_STREQ(templs[i], s->templ);
+    }
   }
-  SuppressionContext *ctx_;
-  ALIGNED(64) char placeholder_[sizeof(SuppressionContext)];
 };
 
 TEST_F(SuppressionContextTest, Parse) {
-  ctx_->Parse(
-    "race:foo\n"
-    " 	race:bar\n"  // NOLINT
-    "race:baz	 \n"  // NOLINT
-    "# a comment\n"
-    "race:quz\n"
-  );  // NOLINT
-  EXPECT_EQ((unsigned)4, ctx_->SuppressionCount());
-  EXPECT_EQ((*Suppressions())[3].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz"));
-  EXPECT_EQ((*Suppressions())[2].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz"));
-  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
-  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
+  ctx_.Parse("race:foo\n"
+             " 	race:bar\n"  // NOLINT
+             "race:baz	 \n" // NOLINT
+             "# a comment\n"
+             "race:quz\n"); // NOLINT
+  CheckSuppressions(4, {"race", "race", "race", "race"},
+                    {"foo", "bar", "baz", "quz"});
 }
 
 TEST_F(SuppressionContextTest, Parse2) {
-  ctx_->Parse(
+  ctx_.Parse(
     "  	# first line comment\n"  // NOLINT
     " 	race:bar 	\n"  // NOLINT
     "race:baz* *baz\n"
     "# a comment\n"
     "# last line comment\n"
   );  // NOLINT
-  EXPECT_EQ((unsigned)2, ctx_->SuppressionCount());
-  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "baz* *baz"));
-  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "bar"));
+  CheckSuppressions(2, {"race", "race"}, {"bar", "baz* *baz"});
 }
 
 TEST_F(SuppressionContextTest, Parse3) {
-  ctx_->Parse(
+  ctx_.Parse(
     "# last suppression w/o line-feed\n"
     "race:foo\n"
     "race:bar"
   );  // NOLINT
-  EXPECT_EQ((unsigned)2, ctx_->SuppressionCount());
-  EXPECT_EQ((*Suppressions())[1].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
-  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
+  CheckSuppressions(2, {"race", "race"}, {"foo", "bar"});
 }
 
 TEST_F(SuppressionContextTest, ParseType) {
-  ctx_->Parse(
+  ctx_.Parse(
     "race:foo\n"
     "thread:bar\n"
     "mutex:baz\n"
     "signal:quz\n"
   );  // NOLINT
-  EXPECT_EQ((unsigned)4, ctx_->SuppressionCount());
-  EXPECT_EQ((*Suppressions())[3].type, SuppressionSignal);
-  EXPECT_EQ(0, strcmp((*Suppressions())[3].templ, "quz"));
-  EXPECT_EQ((*Suppressions())[2].type, SuppressionMutex);
-  EXPECT_EQ(0, strcmp((*Suppressions())[2].templ, "baz"));
-  EXPECT_EQ((*Suppressions())[1].type, SuppressionThread);
-  EXPECT_EQ(0, strcmp((*Suppressions())[1].templ, "bar"));
-  EXPECT_EQ((*Suppressions())[0].type, SuppressionRace);
-  EXPECT_EQ(0, strcmp((*Suppressions())[0].templ, "foo"));
+  CheckSuppressions(4, {"race", "thread", "mutex", "signal"},
+                    {"foo", "bar", "baz", "quz"});
 }
 
 TEST_F(SuppressionContextTest, HasSuppressionType) {
-  ctx_->Parse(
+  ctx_.Parse(
     "race:foo\n"
     "thread:bar\n");
-  EXPECT_TRUE(ctx_->HasSuppressionType(SuppressionRace));
-  EXPECT_TRUE(ctx_->HasSuppressionType(SuppressionThread));
-  EXPECT_FALSE(ctx_->HasSuppressionType(SuppressionMutex));
-  EXPECT_FALSE(ctx_->HasSuppressionType(SuppressionSignal));
+  EXPECT_TRUE(ctx_.HasSuppressionType("race"));
+  EXPECT_TRUE(ctx_.HasSuppressionType("thread"));
+  EXPECT_FALSE(ctx_.HasSuppressionType("mutex"));
+  EXPECT_FALSE(ctx_.HasSuppressionType("signal"));
 }
 
 }  // namespace __sanitizer

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.inc Fri Feb 20 11:41:59 2015
@@ -76,3 +76,4 @@ TSAN_FLAG(int, io_sync, 1,
           "2 - global synchronization of all IO operations.")
 TSAN_FLAG(bool, die_after_fork, true,
           "Die after multi-threaded fork if the child creates new threads.")
+TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Fri Feb 20 11:41:59 2015
@@ -182,11 +182,11 @@ static LibIgnore *libignore() {
 }
 
 void InitializeLibIgnore() {
-  const SuppressionContext &supp = *SuppressionContext::Get();
+  const SuppressionContext &supp = *Suppressions();
   const uptr n = supp.SuppressionCount();
   for (uptr i = 0; i < n; i++) {
     const Suppression *s = supp.SuppressionAt(i);
-    if (s->type == SuppressionLib)
+    if (0 == internal_strcmp(s->type, kSuppressionLib))
       libignore()->AddIgnoredLibrary(s->templ);
   }
   libignore()->OnLibraryLoaded(0);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.cc Fri Feb 20 11:41:59 2015
@@ -41,63 +41,74 @@ extern "C" const char *WEAK __tsan_defau
 
 namespace __tsan {
 
-static bool suppressions_inited = false;
+ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];
+static SuppressionContext *suppression_ctx = nullptr;
+static const char *kSuppressionTypes[] = {
+    kSuppressionRace,   kSuppressionMutex, kSuppressionThread,
+    kSuppressionSignal, kSuppressionLib,   kSuppressionDeadlock};
 
 void InitializeSuppressions() {
-  CHECK(!suppressions_inited);
-  SuppressionContext::InitIfNecessary();
+  CHECK_EQ(nullptr, suppression_ctx);
+  suppression_ctx = new (suppression_placeholder) // NOLINT
+      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
+  suppression_ctx->ParseFromFile(flags()->suppressions);
 #ifndef SANITIZER_GO
-  SuppressionContext::Get()->Parse(__tsan_default_suppressions());
-  SuppressionContext::Get()->Parse(std_suppressions);
+  suppression_ctx->Parse(__tsan_default_suppressions());
+  suppression_ctx->Parse(std_suppressions);
 #endif
-  suppressions_inited = true;
 }
 
-SuppressionType conv(ReportType typ) {
+SuppressionContext *Suppressions() {
+  CHECK(suppression_ctx);
+  return suppression_ctx;
+}
+
+static const char *conv(ReportType typ) {
   if (typ == ReportTypeRace)
-    return SuppressionRace;
+    return kSuppressionRace;
   else if (typ == ReportTypeVptrRace)
-    return SuppressionRace;
+    return kSuppressionRace;
   else if (typ == ReportTypeUseAfterFree)
-    return SuppressionRace;
+    return kSuppressionRace;
   else if (typ == ReportTypeVptrUseAfterFree)
-    return SuppressionRace;
+    return kSuppressionRace;
   else if (typ == ReportTypeThreadLeak)
-    return SuppressionThread;
+    return kSuppressionThread;
   else if (typ == ReportTypeMutexDestroyLocked)
-    return SuppressionMutex;
+    return kSuppressionMutex;
   else if (typ == ReportTypeMutexDoubleLock)
-    return SuppressionMutex;
+    return kSuppressionMutex;
   else if (typ == ReportTypeMutexBadUnlock)
-    return SuppressionMutex;
+    return kSuppressionMutex;
   else if (typ == ReportTypeMutexBadReadLock)
-    return SuppressionMutex;
+    return kSuppressionMutex;
   else if (typ == ReportTypeMutexBadReadUnlock)
-    return SuppressionMutex;
+    return kSuppressionMutex;
   else if (typ == ReportTypeSignalUnsafe)
-    return SuppressionSignal;
+    return kSuppressionSignal;
   else if (typ == ReportTypeErrnoInSignal)
-    return SuppressionNone;
+    return kSuppressionNone;
   else if (typ == ReportTypeDeadlock)
-    return SuppressionDeadlock;
+    return kSuppressionDeadlock;
   Printf("ThreadSanitizer: unknown report type %d\n", typ),
   Die();
 }
 
 uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp) {
-  if (!SuppressionContext::Get()->SuppressionCount() || stack == 0 ||
+  CHECK(suppression_ctx);
+  if (!suppression_ctx->SuppressionCount() || stack == 0 ||
       !stack->suppressable)
     return 0;
-  SuppressionType stype = conv(typ);
-  if (stype == SuppressionNone)
+  const char *stype = conv(typ);
+  if (0 == internal_strcmp(stype, kSuppressionNone))
     return 0;
   Suppression *s;
   for (const SymbolizedStack *frame = stack->frames; frame;
        frame = frame->next) {
     const AddressInfo &info = frame->info;
-    if (SuppressionContext::Get()->Match(info.function, stype, &s) ||
-        SuppressionContext::Get()->Match(info.file, stype, &s) ||
-        SuppressionContext::Get()->Match(info.module, stype, &s)) {
+    if (suppression_ctx->Match(info.function, stype, &s) ||
+        suppression_ctx->Match(info.file, stype, &s) ||
+        suppression_ctx->Match(info.module, stype, &s)) {
       DPrintf("ThreadSanitizer: matched suppression '%s'\n", s->templ);
       s->hit_count++;
       *sp = s;
@@ -108,16 +119,17 @@ uptr IsSuppressed(ReportType typ, const
 }
 
 uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) {
-  if (!SuppressionContext::Get()->SuppressionCount() || loc == 0 ||
+  CHECK(suppression_ctx);
+  if (!suppression_ctx->SuppressionCount() || loc == 0 ||
       loc->type != ReportLocationGlobal || !loc->suppressable)
     return 0;
-  SuppressionType stype = conv(typ);
-  if (stype == SuppressionNone)
+  const char *stype = conv(typ);
+  if (0 == internal_strcmp(stype, kSuppressionNone))
     return 0;
   Suppression *s;
   const DataInfo &global = loc->global;
-  if (SuppressionContext::Get()->Match(global.name, stype, &s) ||
-      SuppressionContext::Get()->Match(global.module, stype, &s)) {
+  if (suppression_ctx->Match(global.name, stype, &s) ||
+      suppression_ctx->Match(global.module, stype, &s)) {
       DPrintf("ThreadSanitizer: matched suppression '%s'\n", s->templ);
       s->hit_count++;
       *sp = s;
@@ -128,7 +140,8 @@ uptr IsSuppressed(ReportType typ, const
 
 void PrintMatchedSuppressions() {
   InternalMmapVector<Suppression *> matched(1);
-  SuppressionContext::Get()->GetMatched(&matched);
+  CHECK(suppression_ctx);
+  suppression_ctx->GetMatched(&matched);
   if (!matched.size())
     return;
   int hit_count = 0;
@@ -137,8 +150,8 @@ void PrintMatchedSuppressions() {
   Printf("ThreadSanitizer: Matched %d suppressions (pid=%d):\n", hit_count,
          (int)internal_getpid());
   for (uptr i = 0; i < matched.size(); i++) {
-    Printf("%d %s:%s\n", matched[i]->hit_count,
-           SuppressionTypeString(matched[i]->type), matched[i]->templ);
+    Printf("%d %s:%s\n", matched[i]->hit_count, matched[i]->type,
+           matched[i]->templ);
   }
 }
 }  // namespace __tsan

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_suppressions.h Fri Feb 20 11:41:59 2015
@@ -18,7 +18,16 @@
 
 namespace __tsan {
 
+const char kSuppressionNone[] = "none";
+const char kSuppressionRace[] = "race";
+const char kSuppressionMutex[] = "mutex";
+const char kSuppressionThread[] = "thread";
+const char kSuppressionSignal[] = "signal";
+const char kSuppressionLib[] = "called_from_lib";
+const char kSuppressionDeadlock[] = "deadlock";
+
 void InitializeSuppressions();
+SuppressionContext *Suppressions();
 void PrintMatchedSuppressions();
 uptr IsSuppressed(ReportType typ, const ReportStack *stack, Suppression **sp);
 uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp);

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=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.cc Fri Feb 20 11:41:59 2015
@@ -14,9 +14,11 @@
 #include "ubsan_diag.h"
 #include "ubsan_init.h"
 #include "ubsan_flags.h"
+#include "sanitizer_common/sanitizer_placement_new.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "sanitizer_common/sanitizer_stacktrace_printer.h"
+#include "sanitizer_common/sanitizer_suppressions.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 #include <stdio.h>
 
@@ -333,11 +335,24 @@ ScopedReport::~ScopedReport() {
     Die();
 }
 
-bool __ubsan::MatchSuppression(const char *Str, SuppressionType Type) {
-  Suppression *s;
+ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];
+static SuppressionContext *suppression_ctx = nullptr;
+static const char kVptrCheck[] = "vptr_check";
+static const char *kSuppressionTypes[] = { kVptrCheck };
+
+void __ubsan::InitializeSuppressions() {
+  CHECK_EQ(nullptr, suppression_ctx);
+  suppression_ctx = new (suppression_placeholder) // NOLINT
+      SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
+  suppression_ctx->ParseFromFile(flags()->suppressions);
+}
+
+bool __ubsan::IsVptrCheckSuppressed(const char *TypeName) {
   // If .preinit_array is not used, it is possible that the UBSan runtime is not
   // initialized.
   if (!SANITIZER_CAN_USE_PREINIT_ARRAY)
     InitIfNecessary();
-  return SuppressionContext::Get()->Match(Str, Type, &s);
+  CHECK(suppression_ctx);
+  Suppression *s;
+  return suppression_ctx->Match(TypeName, kVptrCheck, &s);
 }

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=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_diag.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_diag.h Fri Feb 20 11:41:59 2015
@@ -15,7 +15,6 @@
 
 #include "ubsan_value.h"
 #include "sanitizer_common/sanitizer_stacktrace.h"
-#include "sanitizer_common/sanitizer_suppressions.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 
 namespace __ubsan {
@@ -236,7 +235,8 @@ public:
   ~ScopedReport();
 };
 
-bool MatchSuppression(const char *Str, SuppressionType Type);
+void InitializeSuppressions();
+bool IsVptrCheckSuppressed(const char *TypeName);
 
 } // namespace __ubsan
 

Modified: compiler-rt/trunk/lib/ubsan/ubsan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_flags.inc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_flags.inc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_flags.inc Fri Feb 20 11:41:59 2015
@@ -21,4 +21,5 @@ UBSAN_FLAG(bool, halt_on_error, false,
            "Crash the program after printing the first error report")
 UBSAN_FLAG(bool, print_stacktrace, false,
            "Include full stacktrace into an error report")
+UBSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
 

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=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Fri Feb 20 11:41:59 2015
@@ -36,8 +36,7 @@ static void HandleDynamicTypeCacheMiss(
 
   // Check if error report should be suppressed.
   DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
-  if (DTI.isValid() &&
-      MatchSuppression(DTI.getMostDerivedTypeName(), SuppressionVptrCheck))
+  if (DTI.isValid() && IsVptrCheckSuppressed(DTI.getMostDerivedTypeName()))
     return;
 
   SourceLocation Loc = Data->Loc.acquire();

Modified: compiler-rt/trunk/lib/ubsan/ubsan_init.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_init.cc?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_init.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_init.cc Fri Feb 20 11:41:59 2015
@@ -11,12 +11,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ubsan_diag.h"
 #include "ubsan_init.h"
 #include "ubsan_flags.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "sanitizer_common/sanitizer_mutex.h"
-#include "sanitizer_common/sanitizer_suppressions.h"
 #include "sanitizer_common/sanitizer_symbolizer.h"
 
 using namespace __ubsan;
@@ -43,7 +43,7 @@ void __ubsan::InitIfNecessary() {
   }
   // Initialize UBSan-specific flags.
   InitializeFlags(standalone);
-  SuppressionContext::InitIfNecessary();
+  InitializeSuppressions();
   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
   ubsan_inited = true;
 }

Modified: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp?rev=230026&r1=230025&r2=230026&view=diff
==============================================================================
--- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp (original)
+++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp Fri Feb 20 11:41:59 2015
@@ -12,16 +12,16 @@
 // RUN: %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace
 
 // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
-// RUN: ASAN_OPTIONS="suppressions='%t.supp'" UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1
+// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1
 
 // RUN: echo "vptr_check:S" > %t.loc-supp
-// RUN: ASAN_OPTIONS="suppressions='%t.loc-supp'" UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
+// RUN: UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS
 
 // FIXME: This test produces linker errors on Darwin.
 // XFAIL: darwin





More information about the llvm-commits mailing list