1 //===-- tsan_suppressions_test.cc -----------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "tsan_suppressions.h"
14 #include "tsan_rtl.h"
15 #include "gtest/gtest.h"
16
17 #include <string.h>
18
19 namespace __tsan {
20
TEST(Suppressions,Parse)21 TEST(Suppressions, Parse) {
22 ScopedInRtl in_rtl;
23 Suppression *supp0 = SuppressionParse(
24 "race:foo\n"
25 " race:bar\n" // NOLINT
26 "race:baz \n" // NOLINT
27 "# a comment\n"
28 "race:quz\n"
29 ); // NOLINT
30 Suppression *supp = supp0;
31 EXPECT_EQ(supp->type, SuppressionRace);
32 EXPECT_EQ(0, strcmp(supp->templ, "quz"));
33 supp = supp->next;
34 EXPECT_EQ(supp->type, SuppressionRace);
35 EXPECT_EQ(0, strcmp(supp->templ, "baz"));
36 supp = supp->next;
37 EXPECT_EQ(supp->type, SuppressionRace);
38 EXPECT_EQ(0, strcmp(supp->templ, "bar"));
39 supp = supp->next;
40 EXPECT_EQ(supp->type, SuppressionRace);
41 EXPECT_EQ(0, strcmp(supp->templ, "foo"));
42 supp = supp->next;
43 EXPECT_EQ((Suppression*)0, supp);
44 }
45
TEST(Suppressions,Parse2)46 TEST(Suppressions, Parse2) {
47 ScopedInRtl in_rtl;
48 Suppression *supp0 = SuppressionParse(
49 " # first line comment\n" // NOLINT
50 " race:bar \n" // NOLINT
51 "race:baz* *baz\n"
52 "# a comment\n"
53 "# last line comment\n"
54 ); // NOLINT
55 Suppression *supp = supp0;
56 EXPECT_EQ(supp->type, SuppressionRace);
57 EXPECT_EQ(0, strcmp(supp->templ, "baz* *baz"));
58 supp = supp->next;
59 EXPECT_EQ(supp->type, SuppressionRace);
60 EXPECT_EQ(0, strcmp(supp->templ, "bar"));
61 supp = supp->next;
62 EXPECT_EQ((Suppression*)0, supp);
63 }
64
TEST(Suppressions,Parse3)65 TEST(Suppressions, Parse3) {
66 ScopedInRtl in_rtl;
67 Suppression *supp0 = SuppressionParse(
68 "# last suppression w/o line-feed\n"
69 "race:foo\n"
70 "race:bar"
71 ); // NOLINT
72 Suppression *supp = supp0;
73 EXPECT_EQ(supp->type, SuppressionRace);
74 EXPECT_EQ(0, strcmp(supp->templ, "bar"));
75 supp = supp->next;
76 EXPECT_EQ(supp->type, SuppressionRace);
77 EXPECT_EQ(0, strcmp(supp->templ, "foo"));
78 supp = supp->next;
79 EXPECT_EQ((Suppression*)0, supp);
80 }
81
TEST(Suppressions,ParseType)82 TEST(Suppressions, ParseType) {
83 ScopedInRtl in_rtl;
84 Suppression *supp0 = SuppressionParse(
85 "race:foo\n"
86 "thread:bar\n"
87 "mutex:baz\n"
88 "signal:quz\n"
89 ); // NOLINT
90 Suppression *supp = supp0;
91 EXPECT_EQ(supp->type, SuppressionSignal);
92 EXPECT_EQ(0, strcmp(supp->templ, "quz"));
93 supp = supp->next;
94 EXPECT_EQ(supp->type, SuppressionMutex);
95 EXPECT_EQ(0, strcmp(supp->templ, "baz"));
96 supp = supp->next;
97 EXPECT_EQ(supp->type, SuppressionThread);
98 EXPECT_EQ(0, strcmp(supp->templ, "bar"));
99 supp = supp->next;
100 EXPECT_EQ(supp->type, SuppressionRace);
101 EXPECT_EQ(0, strcmp(supp->templ, "foo"));
102 supp = supp->next;
103 EXPECT_EQ((Suppression*)0, supp);
104 }
105
MyMatch(const char * templ,const char * func)106 static bool MyMatch(const char *templ, const char *func) {
107 char tmp[1024];
108 strcpy(tmp, templ); // NOLINT
109 return SuppressionMatch(tmp, func);
110 }
111
TEST(Suppressions,Match)112 TEST(Suppressions, Match) {
113 EXPECT_TRUE(MyMatch("foobar", "foobar"));
114 EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix"));
115 EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix"));
116 EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar"));
117 EXPECT_TRUE(MyMatch("foo*bar", "foobar"));
118 EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz"));
119 EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz"));
120
121 EXPECT_FALSE(MyMatch("foo", "baz"));
122 EXPECT_FALSE(MyMatch("foobarbaz", "foobar"));
123 EXPECT_FALSE(MyMatch("foobarbaz", "barbaz"));
124 EXPECT_FALSE(MyMatch("foo*bar", "foobaz"));
125 EXPECT_FALSE(MyMatch("foo*bar", "foo_baz"));
126 }
127
128 } // namespace __tsan
129