[TSan] Let the users suppress use-after-free errors using the "race:" suppressions.

If there's a race between a memory access and a free() call in the client program,
it can be reported as a use-after-free (if the access occurs after the free()) or an ordinary race
(if free() occurs after the access).
We've decided to use a single "race:" prefix for both cases instead of introducing a "use-after-free:" one,
because in many cases this allows us to keep a single suppression for both the use-after-free and free-after-use.

This may be misleading if the use-after-free occurs in a non-racy way (e.g. in a single-threaded program).
But normally such bugs shall not be suppressed.



git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@187885 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/tsan/lit_tests/free_race.c b/lib/tsan/lit_tests/free_race.c
index a49572c..f54b628 100644
--- a/lib/tsan/lit_tests/free_race.c
+++ b/lib/tsan/lit_tests/free_race.c
@@ -1,4 +1,7 @@
-// RUN: %clang_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 %s -o %t || exit 1
+// RUN: not %t 2>&1 | FileCheck %s --check-prefix=NOZUPP
+// RUN: TSAN_OPTIONS="suppressions=%s.supp print_suppressions=1" not %t 2>&1 | FileCheck %s --check-prefix=SUPP
+
 #include <pthread.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -34,11 +37,14 @@
   return 0;
 }
 
-// CHECK: WARNING: ThreadSanitizer: heap-use-after-free
-// CHECK:   Write of size 4 at {{.*}} by main thread{{.*}}:
-// CHECK:     #0 Thread2
-// CHECK:     #1 main
-// CHECK:   Previous write of size 8 at {{.*}} by thread T1{{.*}}:
-// CHECK:     #0 free
-// CHECK:     #{{(1|2)}} Thread1
-// CHECK: SUMMARY: ThreadSanitizer: heap-use-after-free{{.*}}Thread2
+// CHECK-NOZUPP: WARNING: ThreadSanitizer: heap-use-after-free
+// CHECK-NOZUPP:   Write of size 4 at {{.*}} by main thread{{.*}}:
+// CHECK-NOZUPP:     #0 Thread2
+// CHECK-NOZUPP:     #1 main
+// CHECK-NOZUPP:   Previous write of size 8 at {{.*}} by thread T1{{.*}}:
+// CHECK-NOZUPP:     #0 free
+// CHECK-NOZUPP:     #{{(1|2)}} Thread1
+// CHECK-NOZUPP: SUMMARY: ThreadSanitizer: heap-use-after-free{{.*}}Thread2
+// CHECK-SUPP:   ThreadSanitizer: Matched 1 suppressions
+// CHECK-SUPP:    1 race:^Thread2$
+
diff --git a/lib/tsan/lit_tests/free_race.c.supp b/lib/tsan/lit_tests/free_race.c.supp
new file mode 100644
index 0000000..f5d6a49
--- /dev/null
+++ b/lib/tsan/lit_tests/free_race.c.supp
@@ -0,0 +1,2 @@
+# Suppression for a use-after-free in free_race.c
+race:^Thread2$
diff --git a/lib/tsan/rtl/tsan_suppressions.cc b/lib/tsan/rtl/tsan_suppressions.cc
index 22e07aa..69e616c 100644
--- a/lib/tsan/rtl/tsan_suppressions.cc
+++ b/lib/tsan/rtl/tsan_suppressions.cc
@@ -81,7 +81,7 @@
   else if (typ == ReportTypeVptrRace)
     return SuppressionRace;
   else if (typ == ReportTypeUseAfterFree)
-    return SuppressionNone;
+    return SuppressionRace;
   else if (typ == ReportTypeThreadLeak)
     return SuppressionThread;
   else if (typ == ReportTypeMutexDestroyLocked)