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 21 TEST(Suppressions, Parse) { 22 ScopedInRtl in_rtl; 23 Suppression *supp0 = SuppressionParse(0, 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 46 TEST(Suppressions, Parse2) { 47 ScopedInRtl in_rtl; 48 Suppression *supp0 = SuppressionParse(0, 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 65 TEST(Suppressions, Parse3) { 66 ScopedInRtl in_rtl; 67 Suppression *supp0 = SuppressionParse(0, 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 82 TEST(Suppressions, ParseType) { 83 ScopedInRtl in_rtl; 84 Suppression *supp0 = SuppressionParse(0, 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 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 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