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 // Checker one has Option specified as true. It should read true regardless of 52 // search mode. 53 CheckerOneMock CheckerOne; 54 EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", false, &CheckerOne)); 55 // The package option is overridden with a checker option. 56 EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", false, &CheckerOne, 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("Option2", false, &CheckerOne, 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("Option2", false, &CheckerOne)); 65 EXPECT_TRUE(Opts.getCheckerBooleanOption("Option2", true, &CheckerOne)); 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("Option", false, &CheckerTwo)); 71 EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", true, &CheckerTwo)); 72 EXPECT_FALSE(Opts.getCheckerBooleanOption("Option", true, &CheckerTwo, 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("Option", "DefaultValue", &CheckerOne)); 88 EXPECT_TRUE("DefaultValue" == 89 Opts.getCheckerStringOption("Option2", "DefaultValue", &CheckerOne)); 90 } 91 } // end namespace ento 92 } // end namespace clang 93