xref: /llvm-project/clang/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp (revision 2946cd701067404b99c39fb29dc9c74bd7193eb3)
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