1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
//===--- CheckerBase.td - Checker TableGen classes ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the TableGen core definitions for checkers
//
//===----------------------------------------------------------------------===//
/// Describes a checker or package option type. This is important for validating
/// user supplied inputs.
/// New option types can be added by modifying this enum. Note that this
/// requires changes in the TableGen emitter file ClangSACheckersEmitter.cpp.
class CmdLineOptionTypeEnum<bits<2> val> {
bits<2> Type = val;
}
def Integer : CmdLineOptionTypeEnum<0>;
def String : CmdLineOptionTypeEnum<1>;
def Boolean : CmdLineOptionTypeEnum<2>;
/// Describes the state of the entry. We wouldn't like to display, for example,
/// developer only entries for a list meant for end users.
class DevelopmentStageEnum<bits<1> val> {
bits<1> Val = val;
}
/// Alpha entries are under development, might be incomplet, inkorrekt and
/// unstable.
def InAlpha : DevelopmentStageEnum<0>;
/// Released entries are stable, produce minimal, if any false positives,
/// and emits reports that explain the occurance of the bug understandably and
/// thoroughly.
def Released : DevelopmentStageEnum<1>;
/// Marks the entry hidden. Hidden entries won't be displayed in
/// -analyzer-checker-option-help.
class HiddenEnum<bit val> {
bit Val = val;
}
def DontHide : HiddenEnum<0>;
def Hide : HiddenEnum<1>;
/// Describes an option for a checker or a package.
class CmdLineOption<CmdLineOptionTypeEnum type, string cmdFlag, string desc,
string defaultVal, DevelopmentStageEnum stage,
HiddenEnum isHidden = DontHide> {
bits<2> Type = type.Type;
string CmdFlag = cmdFlag;
string Desc = desc;
string DefaultVal = defaultVal;
bits<1> DevelopmentStage = stage.Val;
bit Hidden = isHidden.Val;
}
/// Describes a list of package options.
class PackageOptions<list<CmdLineOption> opts> {
list<CmdLineOption> PackageOptions = opts;
}
/// Describes a package. Every checker is a part of a package, for example,
/// 'NullDereference' is part of the 'core' package, hence it's full name is
/// 'core.NullDereference'.
/// Example:
/// def Core : Package<"core">;
class Package<string name> {
string PackageName = name;
// This field is optional.
list<CmdLineOption> PackageOptions;
Package ParentPackage;
bit Hidden = 0;
}
/// Describes a 'super' package that holds another package inside it. This is
/// used to nest packages in one another. One may, for example, create the
/// 'builtin' package inside 'core', thus creating the package 'core.builtin'.
/// Example:
/// def CoreBuiltin : Package<"builtin">, ParentPackage<Core>;
class ParentPackage<Package P> { Package ParentPackage = P; }
/// A description. May be displayed to the user when clang is invoked with
/// a '-help'-like command line option.
class HelpText<string text> { string HelpText = text; }
/// Describes what kind of documentation exists for the checker.
class DocumentationEnum<bits<2> val> {
bits<2> Documentation = val;
}
def NotDocumented : DocumentationEnum<0>;
def HasDocumentation : DocumentationEnum<1>;
def HasAlphaDocumentation : DocumentationEnum<2>;
class Documentation<DocumentationEnum val> {
bits<2> Documentation = val.Documentation;
}
/// Describes a checker. Every builtin checker has to be registered with the use
/// of this class (out-of-trunk checkers loaded from plugins obviously don't).
/// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname,
/// that is autogenerated with the help of the ParentPackage field, that also
/// includes package names (e.g.: 'core.NullDereference').
/// Example:
/// def DereferenceChecker : Checker<"NullDereference">,
/// HelpText<"Check for dereferences of null pointers">;
class Checker<string name = ""> {
string CheckerName = name;
string HelpText;
// This field is optional.
list<CmdLineOption> CheckerOptions;
// This field is optional.
list<Checker> Dependencies;
// This field is optional.
list<Checker> WeakDependencies;
bits<2> Documentation;
Package ParentPackage;
bit Hidden = 0;
}
/// Describes a list of checker options.
class CheckerOptions<list<CmdLineOption> opts> {
list<CmdLineOption> CheckerOptions = opts;
}
/// Describes (strong) dependencies in between checkers. This is important for
/// modeling checkers, for example, MallocBase depends on the proper modeling of
/// string operations, so it depends on CStringBase. A checker may only be
/// enabled if none of its dependencies (transitively) is disabled. Dependencies
/// are always registered before the dependent checker, and its checker
/// callbacks are also evaluated sooner.
/// One may only depend on a purely modeling checker (that emits no diagnostis).
/// Example:
/// def InnerPointerChecker : Checker<"InnerPointer">,
/// HelpText<"Check for inner pointers of C++ containers used after "
/// "re/deallocation">,
/// Dependencies<[MallocBase]>;
class Dependencies<list<Checker> Deps = []> {
list<Checker> Dependencies = Deps;
}
/// Describes preferred registration and evaluation order in between checkers.
/// Unlike strong dependencies, this expresses dependencies in between
/// diagnostics, and *not* modeling. In the case of an unsatisfied (disabled)
/// weak dependency, the dependent checker might still be registered. If the
/// weak dependency is satisfied, it'll be registered, and its checker
/// callbacks will be evaluated before the dependent checker. This can be used
/// to ensure that a more specific warning would be displayed in place of a
/// generic one, should multiple checkers detect the same bug. For example,
/// non-null parameter bugs are detected by NonNullParamChecker due to the
/// nonnull attribute, and StdLibraryFunctionsChecker as it models standard
/// functions, and the former is the more specific one. While freeing a
/// dangling pointer is a bug, if it is also a double free, we would like to
/// recognize it as such first and foremost. This works best for fatal error
/// node generation, otherwise both warnings may be present and in any order.
class WeakDependencies<list<Checker> Deps = []> {
list<Checker> WeakDependencies = Deps;
}
/// Marks a checker or a package hidden. Hidden entries are meant for developers
/// only, and aren't exposed to end users.
class Hidden { bit Hidden = 1; }
|