1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_string.cc ----------------------------------------------------===//
2da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
3da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//                     The LLVM Compiler Infrastructure
4da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
5da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is distributed under the University of Illinois Open Source
6da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// License. See LICENSE.TXT for details.
7da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
8da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
9da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
10da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector.
11da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//
12da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany//===----------------------------------------------------------------------===//
13da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "tsan_test_util.h"
14da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include "gtest/gtest.h"
15da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany#include <string.h>
16da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
17da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryanynamespace __tsan {
18da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
19da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(ThreadSanitizer, Memcpy) {
20da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char data0[7] = {1, 2, 3, 4, 5, 6, 7};
21da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char data[7] = {42, 42, 42, 42, 42, 42, 42};
22da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  MainThread().Memcpy(data+1, data0+1, 5);
23da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[0], 42);
24da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[1], 2);
25da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[2], 3);
26da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[3], 4);
27da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[4], 5);
28da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[5], 6);
29da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[6], 42);
30da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  MainThread().Memset(data+1, 13, 5);
31da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[0], 42);
32da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[1], 13);
33da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[2], 13);
34da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[3], 13);
35da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[4], 13);
36da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[5], 13);
37da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  EXPECT_EQ(data[6], 42);
38da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
39da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
40da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(ThreadSanitizer, MemcpyRace1) {
41da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data = new char[10];
42da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data1 = new char[10];
43da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data2 = new char[10];
44da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  ScopedThread t1, t2;
45da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t1.Memcpy(data, data1, 10);
46da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t2.Memcpy(data, data2, 10, true);
47da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
48da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
49694fe46661a138d0eede348f3645ce37025b6ff4Dmitry Vyukov// The test fails with TSAN_SHADOW_COUNT=2,
50694fe46661a138d0eede348f3645ce37025b6ff4Dmitry Vyukov// because the old racy access is evicted.
51694fe46661a138d0eede348f3645ce37025b6ff4Dmitry Vyukov#if defined(TSAN_SHADOW_COUNT) && TSAN_SHADOW_COUNT >= 4
52da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(ThreadSanitizer, MemcpyRace2) {
53da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data = new char[10];
54da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data1 = new char[10];
55da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data2 = new char[10];
56da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  ScopedThread t1, t2;
57da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t1.Memcpy(data+5, data1, 1);
58da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t2.Memcpy(data+3, data2, 4, true);
59da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
60694fe46661a138d0eede348f3645ce37025b6ff4Dmitry Vyukov#endif
61da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
62da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(ThreadSanitizer, MemcpyRace3) {
63da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data = new char[10];
64da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data1 = new char[10];
65da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data2 = new char[10];
66da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  ScopedThread t1, t2;
67da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t1.Memcpy(data, data1, 10);
68da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t2.Memcpy(data1, data2, 10, true);
69da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
70da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
71da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(ThreadSanitizer, MemcpyStack) {
72da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data = new char[10];
73da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data1 = new char[10];
74da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  ScopedThread t1, t2;
75da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t1.Memcpy(data, data1, 10);
76da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t2.Memcpy(data, data1, 10, true);
77da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
78da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
79da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya SerebryanyTEST(ThreadSanitizer, MemsetRace1) {
80da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  char *data = new char[10];
81da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  ScopedThread t1, t2;
82da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t1.Memset(data, 1, 10);
83da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany  t2.Memset(data, 2, 10, true);
84da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}
85da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany
86da4edd850db1a333c15fc3b0abc01a2e8d2f08feKostya Serebryany}  // namespace __tsan
87