1 //===- unittest/StaticAnalyzer/AnalyzerOptionsTest.cpp - SA Options test --===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" 10 #include "clang/StaticAnalyzer/Core/Checker.h" 11 #include "gtest/gtest.h" 12 13 namespace clang { 14 namespace ento { 15 16 TEST(StaticAnalyzerOptions, getRegisteredCheckers) { 17 auto IsDebugChecker = [](StringRef CheckerName) { 18 return CheckerName.startswith("debug"); 19 }; 20 auto IsAlphaChecker = [](StringRef CheckerName) { 21 return CheckerName.startswith("alpha"); 22 }; 23 const auto &AllCheckers = 24 AnalyzerOptions::getRegisteredCheckers(/*IncludeExperimental=*/true); 25 EXPECT_FALSE(llvm::any_of(AllCheckers, IsDebugChecker)); 26 EXPECT_TRUE(llvm::any_of(AllCheckers, IsAlphaChecker)); 27 28 const auto &StableCheckers = AnalyzerOptions::getRegisteredCheckers(); 29 EXPECT_FALSE(llvm::any_of(StableCheckers, IsDebugChecker)); 30 EXPECT_FALSE(llvm::any_of(StableCheckers, IsAlphaChecker)); 31 } 32 33 TEST(StaticAnalyzerOptions, SearchInParentPackageTests) { 34 AnalyzerOptions Opts; 35 Opts.Config["Outer.Inner.CheckerOne:Option"] = "true"; 36 Opts.Config["Outer.Inner:Option"] = "false"; 37 Opts.Config["Outer.Inner:Option2"] = "true"; 38 Opts.Config["Outer:Option2"] = "false"; 39 40 struct CheckerOneMock : CheckerBase { 41 StringRef getTagDescription() const override { 42 return "Outer.Inner.CheckerOne"; 43 } 44 }; 45 struct CheckerTwoMock : CheckerBase { 46 StringRef getTagDescription() const override { 47 return "Outer.Inner.CheckerTwo"; 48 } 49 }; 50 51 // CheckerTwo one has Option specified as true. It should read true regardless 52 // of search mode. 53 CheckerOneMock CheckerOne; 54 EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option", false)); 55 // The package option is overridden with a checker option. 56 EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option", false, 57 true)); 58 // The Outer package option is overridden by the Inner package option. No 59 // package option is specified. 60 EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option2", false, 61 true)); 62 // No package option is specified and search in packages is turned off. The 63 // default value should be returned. 64 EXPECT_FALSE(Opts.getCheckerBooleanOption(&CheckerOne, "Option2", false)); 65 EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option2", true)); 66 67 // Checker true has no option specified. It should get the default value when 68 // search in parents turned off and false when search in parents turned on. 69 CheckerTwoMock CheckerTwo; 70 EXPECT_FALSE(Opts.getCheckerBooleanOption(&CheckerTwo, "Option", false)); 71 EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerTwo, "Option", true)); 72 EXPECT_FALSE(Opts.getCheckerBooleanOption(&CheckerTwo, "Option", true, true)); 73 } 74 75 TEST(StaticAnalyzerOptions, StringOptions) { 76 AnalyzerOptions Opts; 77 Opts.Config["Outer.Inner.CheckerOne:Option"] = "StringValue"; 78 79 struct CheckerOneMock : CheckerBase { 80 StringRef getTagDescription() const override { 81 return "Outer.Inner.CheckerOne"; 82 } 83 }; 84 85 CheckerOneMock CheckerOne; 86 EXPECT_TRUE("StringValue" == 87 Opts.getCheckerStringOption(&CheckerOne, "Option", "DefaultValue")); 88 EXPECT_TRUE("DefaultValue" == 89 Opts.getCheckerStringOption(&CheckerOne, "Option2", "DefaultValue")); 90 } 91 92 TEST(StaticAnalyzerOptions, SubCheckerOptions) { 93 AnalyzerOptions Opts; 94 Opts.Config["Outer.Inner.CheckerOne:Option"] = "StringValue"; 95 EXPECT_TRUE("StringValue" == Opts.getCheckerStringOption( 96 "Outer.Inner.CheckerOne", "Option", "DefaultValue")); 97 } 98 99 } // end namespace ento 100 } // end namespace clang 101