FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
codeql/cpp/ql/lib/semmle/code/cpp/Specifier.qll at codeql-cli/v2.27.1 · github/codeql · GitHub
github
codeql
Repository navigation
Code
Issues
1k
(1k)
Pull requests
485
(485)
Discussions
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
codeql
/
cpp
/
ql
/
lib
/
semmle
/
code
/
cpp
/
Specifier.qll
Copy path
More file actions
More file actions
Latest commit
History
History
History
336 lines (293 loc) · 10.8 KB
Breadcrumbs
codeql
/
cpp
/
ql
/
lib
/
semmle
/
code
/
cpp
/
Specifier.qll
Copy path
File metadata and controls
336 lines (293 loc) · 10.8 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/**
* Provides classes for modeling specifiers and attributes.
*/
import
semmle.code.cpp.Element
private
import
semmle.code.cpp.internal.ResolveClass
/**
* A C/C++ specifier: `friend`, `auto`, `register`, `static`, `extern`,
* `mutable`, `inline`, `virtual`, or `explicit`.
*/
class
Specifier
extends
Element
,
@specifier
{
/** Gets a dummy location for the specifier. */
override
Location
getLocation
(
)
{
exists
(
this
)
and
result
instanceof
UnknownLocation
}
override
string
getAPrimaryQlClass
(
)
{
result
=
"Specifier"
}
/** Gets the name of this specifier. */
string
getName
(
)
{
specifiers
(
underlyingElement
(
this
)
,
result
)
}
/** Holds if the name of this specifier is `name`. */
predicate
hasName
(
string
name
)
{
name
=
this
.
getName
(
)
}
override
string
toString
(
)
{
result
=
this
.
getName
(
)
}
}
/**
* A C/C++ function specifier: `inline`, `virtual`, or `explicit`.
*/
class
FunctionSpecifier
extends
Specifier
{
FunctionSpecifier
(
)
{
this
.
hasName
(
[
"inline"
,
"virtual"
,
"explicit"
]
)
}
override
string
getAPrimaryQlClass
(
)
{
result
=
"FunctionSpecifier"
}
}
/**
* A C/C++ storage class specifier: `auto`, `register`, `static`, `extern`,
* or `mutable`.
*/
class
StorageClassSpecifier
extends
Specifier
{
StorageClassSpecifier
(
)
{
this
.
hasName
(
[
"auto"
,
"register"
,
"static"
,
"extern"
,
"mutable"
]
)
}
override
string
getAPrimaryQlClass
(
)
{
result
=
"StorageClassSpecifier"
}
}
/**
* A C++ access specifier: `public`, `protected`, or `private`.
*/
class
AccessSpecifier
extends
Specifier
{
AccessSpecifier
(
)
{
this
.
hasName
(
[
"public"
,
"protected"
,
"private"
]
)
}
/**
* Gets the visibility of a field with access specifier `this` if it is
* directly inherited with access specifier `baseAccess`. For example:
*
* ```
* class A { protected int f; };
* class B : private A {};
* ```
*
* In this example, `this` is `protected`, `baseAccess` is `private`, and
* `result` is `private` because the visibility of field `f` in class `B`
* is `private`.
*
* This method encodes the rules of N4140 11.2/1, tabulated here:
*
* ```
* `this` | `baseAccess` | `result`
* (access in base) | (base class specifier) | (access in derived)
* ----------------------------------------------------------
* private | private | N/A
* private | protected | N/A
* private | public | N/A
* protected | private | private
* protected | protected | protected
* protected | public | protected
* public | private | private
* public | protected | protected
* public | public | public
* ```
*/
AccessSpecifier
accessInDirectDerived
(
AccessSpecifier
baseAccess
)
{
this
.
getName
(
)
!=
"private"
and
(
// Alphabetically, "private" < "protected" < "public". This disjunction
// encodes that `result` is the minimum access of `this` and
// `baseAccess`.
baseAccess
.
getName
(
)
<
this
.
getName
(
)
and
result
=
baseAccess
or
baseAccess
.
getName
(
)
>=
this
.
getName
(
)
and
result
=
this
)
}
override
string
getAPrimaryQlClass
(
)
{
result
=
"AccessSpecifier"
}
}
/**
* A C/C++ calling convention specifier: `cdecl`, `fastcall`, `stdcall`, `thiscall`,
* `vectorcall`, or `clrcall`.
*/
class
CallingConventionSpecifier
extends
Specifier
{
CallingConventionSpecifier
(
)
{
this
.
hasName
(
[
"cdecl"
,
"fastcall"
,
"stdcall"
,
"thiscall"
,
"vectorcall"
,
"clrcall"
]
)
}
override
string
getAPrimaryQlClass
(
)
{
result
=
"CallingConventionSpecifier"
}
}
/**
* An attribute introduced by GNU's `__attribute__((name))` syntax,
* Microsoft's `__declspec(name)` syntax, Microsoft's `[name]` syntax, the
* C++11 standard `[[name]]` syntax, or the C++11 `alignas` syntax.
*/
class
Attribute
extends
Element
,
@attribute
{
/**
* Gets the name of this attribute.
*
* As examples, this is "noreturn" for `__attribute__((__noreturn__))`,
* "fallthrough" for `[[clang::fallthrough]]`, and "dllimport" for
* `__declspec(dllimport)`.
*
* Note that the name does not include the namespace. For example, the
* name of `[[clang::fallthrough]]` is "fallthrough".
*/
string
getName
(
)
{
attributes
(
underlyingElement
(
this
)
,
_
,
result
,
_
,
_
)
}
override
Location
getLocation
(
)
{
attributes
(
underlyingElement
(
this
)
,
_
,
_
,
_
,
result
)
}
/** Holds if the name of this attribute is `name`. */
predicate
hasName
(
string
name
)
{
name
=
this
.
getName
(
)
}
override
string
toString
(
)
{
result
=
this
.
getName
(
)
}
/** Gets the `i`th argument of the attribute. */
AttributeArgument
getArgument
(
int
i
)
{
result
.
getAttribute
(
)
=
this
and
result
.
getIndex
(
)
=
i
}
/** Gets an argument of the attribute. */
AttributeArgument
getAnArgument
(
)
{
result
=
this
.
getArgument
(
_
)
}
}
/**
* An attribute introduced by GNU's `__attribute__((name))` syntax, for
* example: `__attribute__((__noreturn__))`.
*/
class
GnuAttribute
extends
Attribute
,
@gnuattribute
{
}
/**
* An attribute introduced by the C++11 standard `[[name]]` syntax, for
* example: `[[clang::fallthrough]]`.
*/
class
StdAttribute
extends
Attribute
,
@stdattribute
{
/**
* Gets the namespace of this attribute.
*
* As examples, this is "" for `[[carries_dependency]]`, and "clang" for
* `[[clang::fallthrough]]`.
*/
string
getNamespace
(
)
{
attributes
(
underlyingElement
(
this
)
,
_
,
_
,
result
,
_
)
}
/**
* Holds if this attribute has the given namespace and name.
*/
predicate
hasQualifiedName
(
string
namespace
,
string
name
)
{
namespace
=
this
.
getNamespace
(
)
and
this
.
hasName
(
name
)
}
}
/**
* An attribute introduced by Microsoft's `__declspec(name)` syntax. For
* example the attribute on the following declaration:
* ```
* __declspec(dllimport) void myFunction();
* ```
*/
class
Declspec
extends
Attribute
,
@declspec
{
}
/**
* An attribute introduced by Microsoft's "[name]" syntax, for example "[SA_Pre(Deref=1,Access=SA_Read)]".
*/
class
MicrosoftAttribute
extends
Attribute
,
@msattribute
{
AttributeArgument
getNamedArgument
(
string
name
)
{
result
=
this
.
getAnArgument
(
)
and
result
.
getName
(
)
=
name
}
}
/**
* A C++11 `alignas` construct. For example the attribute in the following
* code:
* ```
* struct alignas(16) MyStruct {
* int x;
* };
* ```
* Though it doesn't use the attribute syntax, `alignas(...)` is presented
* as an `Attribute` for consistency with the `[[align(...)]]` attribute.
*/
class
AlignAs
extends
Attribute
,
@alignas
{
override
string
toString
(
)
{
result
=
"alignas(...)"
}
}
/**
* A GNU `format` attribute of the form `__attribute__((format(archetype, format-index, first-arg)))`
* that declares a function to accept a `printf` style format string. For example the attribute
* on the following declaration:
* ```
* int myPrintf(const char *format, ...) __attribute__((format(printf, 1, 2)));
* ```
*/
class
FormatAttribute
extends
GnuAttribute
{
FormatAttribute
(
)
{
this
.
getName
(
)
=
"format"
}
/**
* Gets the archetype of this format attribute, for example
* `"printf"`.
*/
string
getArchetype
(
)
{
result
=
this
.
getArgument
(
0
)
.
getValueText
(
)
}
/**
* Gets the index in (1-based) format attribute notation associated
* with the first argument of the function.
*/
private
int
firstArgumentNumber
(
)
{
if
exists
(
MemberFunction
f
|
f
.
getAnAttribute
(
)
=
this
and
not
f
.
isStatic
(
)
)
then
// 1 is `this`, so the first parameter is 2
result
=
2
else
result
=
1
}
/**
* Gets the (0-based) index of the format string,
* according to this attribute.
*/
int
getFormatIndex
(
)
{
result
=
this
.
getArgument
(
1
)
.
getValueInt
(
)
-
this
.
firstArgumentNumber
(
)
}
/**
* Gets the (0-based) index of the first format argument (if any),
* according to this attribute.
*/
int
getFirstFormatArgIndex
(
)
{
exists
(
int
val
|
val
=
this
.
getArgument
(
2
)
.
getValueInt
(
)
and
result
=
val
-
this
.
firstArgumentNumber
(
)
and
not
val
=
0
// indicates a `vprintf` style format function with arguments not directly available.
)
}
override
string
getAPrimaryQlClass
(
)
{
result
=
"FormatAttribute"
}
}
/**
* An argument to an `Attribute`. For example the argument "dllimport" on the
* attribute in the following code:
* ```
* __declspec(dllimport) void myFunction();
* ```
*/
class
AttributeArgument
extends
Element
,
@attribute_arg
{
/**
* Gets the name of this argument, if it is a named argument. Named
* arguments are a Microsoft feature, so only a `MicrosoftAttribute` can
* have a named argument.
*/
string
getName
(
)
{
attribute_arg_name
(
underlyingElement
(
this
)
,
result
)
}
/**
* Gets the text for the value of this argument, if its value is
* a constant or a token.
*/
string
getValueText
(
)
{
if
underlyingElement
(
this
)
instanceof
@attribute_arg_constant_expr
then
result
=
this
.
getValueConstant
(
)
.
getValue
(
)
else
attribute_arg_value
(
underlyingElement
(
this
)
,
result
)
}
/**
* Gets the value of this argument, if its value is integral.
*/
int
getValueInt
(
)
{
result
=
this
.
getValueText
(
)
.
toInt
(
)
}
/**
* Gets the value of this argument, if its value is a type.
*/
Type
getValueType
(
)
{
attribute_arg_type
(
underlyingElement
(
this
)
,
unresolveElement
(
result
)
)
}
/**
* Gets the value of this argument, if its value is a constant.
*/
Expr
getValueConstant
(
)
{
attribute_arg_constant
(
underlyingElement
(
this
)
,
unresolveElement
(
result
)
)
}
/**
* Gets the value of this argument, if its value is an expression.
*/
Expr
getValueExpr
(
)
{
attribute_arg_expr
(
underlyingElement
(
this
)
,
unresolveElement
(
result
)
)
}
/**
* Gets the attribute to which this is an argument.
*/
Attribute
getAttribute
(
)
{
attribute_args
(
underlyingElement
(
this
)
,
_
,
unresolveElement
(
result
)
,
_
,
_
)
}
/**
* Gets the zero-based index of this argument in the containing
* attribute's argument list.
*/
int
getIndex
(
)
{
attribute_args
(
underlyingElement
(
this
)
,
_
,
_
,
result
,
_
)
}
override
Location
getLocation
(
)
{
attribute_args
(
underlyingElement
(
this
)
,
_
,
_
,
_
,
result
)
}
override
string
toString
(
)
{
if
underlyingElement
(
this
)
instanceof
@attribute_arg_empty
then
result
=
"empty argument"
else
exists
(
string
prefix
,
string
tail
|
(
if
exists
(
this
.
getName
(
)
)
then
prefix
=
this
.
getName
(
)
+
"="
else
prefix
=
""
)
and
(
if
underlyingElement
(
this
)
instanceof
@attribute_arg_type
then
tail
=
this
.
getValueType
(
)
.
getName
(
)
else
if
underlyingElement
(
this
)
instanceof
@attribute_arg_constant_expr
then
tail
=
this
.
getValueConstant
(
)
.
toString
(
)
else
if
underlyingElement
(
this
)
instanceof
@attribute_arg_expr
then
tail
=
this
.
getValueExpr
(
)
.
toString
(
)
else
tail
=
this
.
getValueText
(
)
)
and
result
=
prefix
+
tail
)
}
}
Back
|
FazBrowse Home
|
New Git URL