Skip to content

Commit dfbfbe4

Browse files
committed
Merge branch 'main' into use-shared-ssa-in-ir-dataflow
2 parents ad5619f + ab37ae6 commit dfbfbe4

File tree

391 files changed

+12736
-3447
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

391 files changed

+12736
-3447
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ If you have an idea for a query that you would like to share with other CodeQL u
1111

1212
1. **Directory structure**
1313

14-
There are five language-specific query directories in this repository:
14+
There are six language-specific query directories in this repository:
1515

1616
* C/C++: `cpp/ql/src`
1717
* C#: `csharp/ql/src`
1818
* Java: `java/ql/src`
1919
* JavaScript: `javascript/ql/src`
2020
* Python: `python/ql/src`
21+
* Ruby: `ruby/ql/src`
2122

2223
Each language-specific directory contains further subdirectories that group queries based on their `@tags` or purpose.
2324
- Experimental queries and libraries are stored in the `experimental` subdirectory within each language-specific directory in the [CodeQL repository](https://github.com/github/codeql). For example, experimental Java queries and libraries are stored in `java/ql/src/experimental` and any corresponding tests in `java/ql/test/experimental`.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
lgtm,codescanning
2+
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
3+
`isFromSystemMacroDefinition` for identifying code that originates from a
4+
macro outside the project being analyzed.

cpp/ql/lib/semmle/code/cpp/Class.qll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class Class extends UserType {
237237
exists(ClassDerivation cd | cd.getBaseClass() = base |
238238
result =
239239
this.accessOfBaseMemberMulti(cd.getDerivedClass(),
240-
fieldInBase.accessInDirectDerived(cd.getASpecifier().(AccessSpecifier)))
240+
fieldInBase.accessInDirectDerived(cd.getASpecifier()))
241241
)
242242
}
243243

@@ -261,8 +261,7 @@ class Class extends UserType {
261261
* includes the case of `base` = `this`.
262262
*/
263263
AccessSpecifier accessOfBaseMember(Declaration member) {
264-
result =
265-
this.accessOfBaseMember(member.getDeclaringType(), member.getASpecifier().(AccessSpecifier))
264+
result = this.accessOfBaseMember(member.getDeclaringType(), member.getASpecifier())
266265
}
267266

268267
/**
@@ -319,7 +318,7 @@ class Class extends UserType {
319318
exists(Type t | t = this.getAFieldSubobjectType().getUnspecifiedType() |
320319
// Note: Overload resolution is not implemented -- all copy
321320
// constructors are considered equal.
322-
this.cannotAccessCopyConstructorOnAny(t.(Class))
321+
this.cannotAccessCopyConstructorOnAny(t)
323322
)
324323
or
325324
// - T has direct or virtual base class that cannot be copied (has deleted,
@@ -392,7 +391,7 @@ class Class extends UserType {
392391
exists(Type t | t = this.getAFieldSubobjectType().getUnspecifiedType() |
393392
// Note: Overload resolution is not implemented -- all copy assignment
394393
// operators are considered equal.
395-
this.cannotAccessCopyAssignmentOperatorOnAny(t.(Class))
394+
this.cannotAccessCopyAssignmentOperatorOnAny(t)
396395
)
397396
or
398397
exists(Class c | c = this.getADirectOrVirtualBase() |

cpp/ql/lib/semmle/code/cpp/Declaration.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,7 @@ class AccessHolder extends Declaration, TAccessHolder {
490490
*/
491491
pragma[inline]
492492
predicate canAccessMember(Declaration member, Class derived) {
493-
this.couldAccessMember(member.getDeclaringType(), member.getASpecifier().(AccessSpecifier),
494-
derived)
493+
this.couldAccessMember(member.getDeclaringType(), member.getASpecifier(), derived)
495494
}
496495

497496
/**

cpp/ql/lib/semmle/code/cpp/commons/Dependency.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,17 @@ private predicate dependsOnDeclarationEntry(Element src, DeclarationEntry dest)
275275
dependsOnTransitive(src, mid) and
276276
not mid instanceof Type and
277277
not mid instanceof EnumConstant and
278-
getDeclarationEntries(mid, dest.(DeclarationEntry)) and
278+
getDeclarationEntries(mid, dest) and
279279
not dest instanceof TypeDeclarationEntry
280280
)
281281
or
282282
exists(Declaration mid |
283283
// dependency from a Type / Variable / Function use -> any (visible) definition
284284
dependsOnTransitive(src, mid) and
285285
not mid instanceof EnumConstant and
286-
getDeclarationEntries(mid, dest.(DeclarationEntry)) and
286+
getDeclarationEntries(mid, dest) and
287287
// must be definition
288-
dest.(DeclarationEntry).isDefinition()
288+
dest.isDefinition()
289289
)
290290
}
291291

@@ -307,7 +307,7 @@ private predicate dependsOnFull(DependsSource src, Symbol dest, int category) {
307307
// dependency from a Variable / Function use -> non-visible definition (link time)
308308
dependsOnTransitive(src, mid) and
309309
not mid instanceof EnumConstant and
310-
getDeclarationEntries(mid, dest.(DeclarationEntry)) and
310+
getDeclarationEntries(mid, dest) and
311311
not dest instanceof TypeDeclarationEntry and
312312
// must be definition
313313
dest.(DeclarationEntry).isDefinition() and

cpp/ql/lib/semmle/code/cpp/commons/Exclusions.qll

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ predicate functionContainsPreprocCode(Function f) {
8181
}
8282

8383
/**
84-
* Holds if `e` is completely or partially from a macro definition, as opposed
85-
* to being passed in as an argument.
84+
* Holds if `e` is completely or partially from a macro invocation `mi`, as
85+
* opposed to being passed in as an argument.
8686
*
8787
* In the following example, the call to `f` is from a macro definition,
8888
* while `y`, `+`, `1`, and `;` are not. This assumes that no identifier apart
@@ -93,8 +93,8 @@ predicate functionContainsPreprocCode(Function f) {
9393
* M(y + 1);
9494
* ```
9595
*/
96-
predicate isFromMacroDefinition(Element e) {
97-
exists(MacroInvocation mi, Location eLocation, Location miLocation |
96+
private predicate isFromMacroInvocation(Element e, MacroInvocation mi) {
97+
exists(Location eLocation, Location miLocation |
9898
mi.getAnExpandedElement() = e and
9999
eLocation = e.getLocation() and
100100
miLocation = mi.getLocation() and
@@ -109,3 +109,36 @@ predicate isFromMacroDefinition(Element e) {
109109
eLocation.getEndColumn() >= miLocation.getEndColumn()
110110
)
111111
}
112+
113+
/**
114+
* Holds if `e` is completely or partially from a macro definition, as opposed
115+
* to being passed in as an argument.
116+
*
117+
* In the following example, the call to `f` is from a macro definition,
118+
* while `y`, `+`, `1`, and `;` are not. This assumes that no identifier apart
119+
* from `M` refers to a macro.
120+
* ```
121+
* #define M(x) f(x)
122+
* ...
123+
* M(y + 1);
124+
* ```
125+
*/
126+
predicate isFromMacroDefinition(Element e) { isFromMacroInvocation(e, _) }
127+
128+
/**
129+
* Holds if `e` is completely or partially from a _system macro_ definition, as
130+
* opposed to being passed in as an argument. A system macro is a macro whose
131+
* definition is outside the source directory of the database.
132+
*
133+
* If the system macro is invoked through a non-system macro, then this
134+
* predicate does not hold.
135+
*
136+
* See also `isFromMacroDefinition`.
137+
*/
138+
predicate isFromSystemMacroDefinition(Element e) {
139+
exists(MacroInvocation mi |
140+
isFromMacroInvocation(e, mi) and
141+
// Has no relative path in the database, meaning it's a system file.
142+
not exists(mi.getMacro().getFile().getRelativePath())
143+
)
144+
}

cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, Expr e0)
1111
)
1212
}
1313

14+
bindingset[n1, n2]
15+
private predicate controlFlowNodeSuccessorTransitive(ControlFlowNode n1, ControlFlowNode n2) {
16+
exists(BasicBlock bb1, int pos1, BasicBlock bb2, int pos2 |
17+
pragma[only_bind_into](bb1).getNode(pos1) = n1 and
18+
pragma[only_bind_into](bb2).getNode(pos2) = n2 and
19+
(
20+
bb1 = bb2 and pos1 < pos2
21+
or
22+
bb1.getASuccessor+() = bb2
23+
)
24+
)
25+
}
26+
1427
/**
1528
* Holds if the expression `e` may add a null terminator to the string in
1629
* variable `v`.
@@ -30,14 +43,9 @@ predicate mayAddNullTerminator(Expr e, VariableAccess va) {
3043
)
3144
or
3245
// Assignment to another stack variable
33-
exists(Expr e0, BasicBlock bb, int pos, BasicBlock bb0, int pos0 |
34-
mayAddNullTerminatorHelper(e, va, e0) and
35-
bb.getNode(pos) = e and
36-
bb0.getNode(pos0) = e0
37-
|
38-
bb = bb0 and pos < pos0
39-
or
40-
bb.getASuccessor+() = bb0
46+
exists(Expr e0 |
47+
mayAddNullTerminatorHelper(pragma[only_bind_into](e), va, pragma[only_bind_into](e0)) and
48+
controlFlowNodeSuccessorTransitive(e, e0)
4149
)
4250
or
4351
// Assignment to non-stack variable
@@ -119,14 +127,9 @@ predicate variableMustBeNullTerminated(VariableAccess va) {
119127
variableMustBeNullTerminated(use) and
120128
// Simplified: check that `p` may not be null terminated on *any*
121129
// path to `use` (including the one found via `parameterUsePair`)
122-
not exists(Expr e, BasicBlock bb1, int pos1, BasicBlock bb2, int pos2 |
123-
mayAddNullTerminator(e, p.getAnAccess()) and
124-
bb1.getNode(pos1) = e and
125-
bb2.getNode(pos2) = use
126-
|
127-
bb1 = bb2 and pos1 < pos2
128-
or
129-
bb1.getASuccessor+() = bb2
130+
not exists(Expr e |
131+
mayAddNullTerminator(pragma[only_bind_into](e), p.getAnAccess()) and
132+
controlFlowNodeSuccessorTransitive(e, use)
130133
)
131134
)
132135
)

cpp/ql/lib/semmle/code/cpp/commons/Printf.qll

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ class FormattingFunctionCall extends Expr {
175175
/**
176176
* Gets the index at which the format string occurs in the argument list.
177177
*/
178-
int getFormatParameterIndex() {
179-
result = this.getTarget().(FormattingFunction).getFormatParameterIndex()
180-
}
178+
int getFormatParameterIndex() { result = this.getTarget().getFormatParameterIndex() }
181179

182180
/**
183181
* Gets the format expression used in this call.
@@ -191,7 +189,7 @@ class FormattingFunctionCall extends Expr {
191189
exists(int i |
192190
result = this.getArgument(i) and
193191
n >= 0 and
194-
n = i - this.getTarget().(FormattingFunction).getFirstFormatArgumentIndex()
192+
n = i - this.getTarget().getFirstFormatArgumentIndex()
195193
)
196194
}
197195

@@ -251,7 +249,7 @@ class FormattingFunctionCall extends Expr {
251249
int getNumFormatArgument() {
252250
result = count(this.getFormatArgument(_)) and
253251
// format arguments must be known
254-
exists(this.getTarget().(FormattingFunction).getFirstFormatArgumentIndex())
252+
exists(this.getTarget().getFirstFormatArgumentIndex())
255253
}
256254

257255
/**
@@ -289,35 +287,27 @@ class FormatLiteral extends Literal {
289287
* a `char *` (either way, `%S` will have the opposite meaning).
290288
* DEPRECATED: Use getDefaultCharType() instead.
291289
*/
292-
deprecated predicate isWideCharDefault() {
293-
this.getUse().getTarget().(FormattingFunction).isWideCharDefault()
294-
}
290+
deprecated predicate isWideCharDefault() { this.getUse().getTarget().isWideCharDefault() }
295291

296292
/**
297293
* Gets the default character type expected for `%s` by this format literal. Typically
298294
* `char` or `wchar_t`.
299295
*/
300-
Type getDefaultCharType() {
301-
result = this.getUse().getTarget().(FormattingFunction).getDefaultCharType()
302-
}
296+
Type getDefaultCharType() { result = this.getUse().getTarget().getDefaultCharType() }
303297

304298
/**
305299
* Gets the non-default character type expected for `%S` by this format literal. Typically
306300
* `wchar_t` or `char`. On some snapshots there may be multiple results where we can't tell
307301
* which is correct for a particular function.
308302
*/
309-
Type getNonDefaultCharType() {
310-
result = this.getUse().getTarget().(FormattingFunction).getNonDefaultCharType()
311-
}
303+
Type getNonDefaultCharType() { result = this.getUse().getTarget().getNonDefaultCharType() }
312304

313305
/**
314306
* Gets the wide character type for this format literal. This is usually `wchar_t`. On some
315307
* snapshots there may be multiple results where we can't tell which is correct for a
316308
* particular function.
317309
*/
318-
Type getWideCharType() {
319-
result = this.getUse().getTarget().(FormattingFunction).getWideCharType()
320-
}
310+
Type getWideCharType() { result = this.getUse().getTarget().getWideCharType() }
321311

322312
/**
323313
* Holds if this `FormatLiteral` is in a context that supports
@@ -896,7 +886,7 @@ class FormatLiteral extends Literal {
896886
exists(string len, string conv |
897887
this.parseConvSpec(n, _, _, _, _, _, len, conv) and
898888
(len != "l" and len != "w" and len != "h") and
899-
this.getUse().getTarget().(FormattingFunction).getFormatCharType().getSize() > 1 and // wide function
889+
this.getUse().getTarget().getFormatCharType().getSize() > 1 and // wide function
900890
(
901891
conv = "c" and
902892
result = this.getNonDefaultCharType()

cpp/ql/lib/semmle/code/cpp/controlflow/DefinitionsAndUses.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ predicate definitionUsePair(SemanticStackVariable var, Expr def, Expr use) {
2525
* Holds if the definition `def` of some stack variable can reach `node`, which
2626
* is a definition or use, without crossing definitions of the same variable.
2727
*/
28-
predicate definitionReaches(Expr def, Expr node) { def.(Def).reaches(true, _, node.(DefOrUse)) }
28+
predicate definitionReaches(Expr def, Expr node) { def.(Def).reaches(true, _, node) }
2929

3030
private predicate hasAddressOfAccess(SemanticStackVariable var) {
3131
var.getAnAccess().isAddressOfAccessNonConst()

cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class SsaDefinition extends ControlFlowNodeBase {
6262
BasicBlock getBasicBlock() { result.contains(this.getDefinition()) }
6363

6464
/** Holds if this definition is a phi node for variable `v`. */
65-
predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this.(BasicBlock))) }
65+
predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this)) }
6666

6767
/** Gets the location of this definition. */
6868
Location getLocation() { result = this.(ControlFlowNode).getLocation() }

0 commit comments

Comments
 (0)