1 //===-- tsan_mop.cpp ------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //===----------------------------------------------------------------------===//
12 #include "tsan_interface.h"
13 #include "tsan_test_util.h"
14 #include "gtest/gtest.h"
18 TEST_F(ThreadSanitizer
, SimpleWrite
) {
24 TEST_F(ThreadSanitizer
, SimpleWriteWrite
) {
31 TEST_F(ThreadSanitizer
, WriteWriteRace
) {
38 TEST_F(ThreadSanitizer
, ReadWriteRace
) {
45 TEST_F(ThreadSanitizer
, WriteReadRace
) {
52 TEST_F(ThreadSanitizer
, ReadReadNoRace
) {
59 TEST_F(ThreadSanitizer
, WriteThenRead
) {
67 TEST_F(ThreadSanitizer
, WriteThenLockedRead
) {
68 UserMutex
m(UserMutex::RW
);
86 TEST_F(ThreadSanitizer
, LockedWriteThenRead
) {
87 UserMutex
m(UserMutex::RW
);
106 TEST_F(ThreadSanitizer
, RaceWithOffset
) {
110 t1
.Access(l
.loc(), true, 8, false);
111 t2
.Access((char*)l
.loc() + 4, true, 4, true);
115 t1
.Access(l
.loc(), true, 8, false);
116 t2
.Access((char*)l
.loc() + 7, true, 1, true);
120 t1
.Access((char*)l
.loc() + 4, true, 4, false);
121 t2
.Access((char*)l
.loc() + 4, true, 2, true);
125 t1
.Access((char*)l
.loc() + 4, true, 4, false);
126 t2
.Access((char*)l
.loc() + 6, true, 2, true);
130 t1
.Access((char*)l
.loc() + 3, true, 2, false);
131 t2
.Access((char*)l
.loc() + 4, true, 1, true);
135 t1
.Access((char*)l
.loc() + 1, true, 8, false);
136 t2
.Access((char*)l
.loc() + 3, true, 1, true);
140 TEST_F(ThreadSanitizer
, RaceWithOffset2
) {
144 t1
.Access((char*)l
.loc(), true, 4, false);
145 t2
.Access((char*)l
.loc() + 2, true, 1, true);
149 t1
.Access((char*)l
.loc() + 2, true, 1, false);
150 t2
.Access((char*)l
.loc(), true, 4, true);
154 TEST_F(ThreadSanitizer
, NoRaceWithOffset
) {
158 t1
.Access(l
.loc(), true, 4, false);
159 t2
.Access((char*)l
.loc() + 4, true, 4, false);
163 t1
.Access((char*)l
.loc() + 3, true, 2, false);
164 t2
.Access((char*)l
.loc() + 1, true, 2, false);
165 t2
.Access((char*)l
.loc() + 5, true, 2, false);
169 TEST_F(ThreadSanitizer
, RaceWithDeadThread
) {
172 ScopedThread().Write1(l
);
176 TEST_F(ThreadSanitizer
, BenignRaceOnVptr
) {
178 MemLoc
vptr(&vptr_storage
), val
;
179 vptr_storage
= val
.loc();
181 t1
.VptrUpdate(vptr
, val
);
185 TEST_F(ThreadSanitizer
, HarmfulRaceOnVptr
) {
187 MemLoc
vptr(&vptr_storage
), val1
, val2
;
188 vptr_storage
= val1
.loc();
190 t1
.VptrUpdate(vptr
, val2
);
191 t2
.Read8(vptr
, true);
206 TEST_F(ThreadSanitizer
, ReportDeadThread
) {
218 struct ClassWithStatic
{
222 int ClassWithStatic::Data
[4];
224 static void foobarbaz() {}
226 TEST_F(ThreadSanitizer
, ReportRace
) {
228 MainThread().Access(&ClassWithStatic::Data
, true, 4, false);
230 t1
.Access(&ClassWithStatic::Data
, true, 2, true);