Skip to content

Commit cd58c12

Browse files
committed
Merge branch 'main' into orm
2 parents 98c60a7 + 94cb5c2 commit cd58c12

File tree

108 files changed

+4356
-1921
lines changed

Some content is hidden

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

108 files changed

+4356
-1921
lines changed

.pre-commit-config.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See https://pre-commit.com for more information
2+
# See https://pre-commit.com/hooks.html for more hooks
3+
exclude: /test/.*$(?<!\.ql)(?<!\.qll)(?<!\.qlref)
4+
repos:
5+
- repo: https://github.com/pre-commit/pre-commit-hooks
6+
rev: v3.2.0
7+
hooks:
8+
- id: trailing-whitespace
9+
- id: end-of-file-fixer
10+
11+
- repo: local
12+
hooks:
13+
- id: codeql-format
14+
name: Fix QL file formatting
15+
files: \.qll?$
16+
language: system
17+
entry: codeql query format --in-place
18+
19+
- id: sync-files
20+
name: Fix files required to be identical
21+
language: system
22+
entry: python3 config/sync-files.py --latest
23+
pass_filenames: false
24+
25+
- id: qhelp
26+
name: Check query help generation
27+
files: \.qhelp$
28+
language: system
29+
entry: python3 misc/scripts/check-qhelp.py

CONTRIBUTING.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ If you have an idea for a query that you would like to share with other CodeQL u
4242

4343
- The queries and libraries must be autoformatted, for example using the "Format Document" command in [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode/procedures/about-codeql-for-vscode.html).
4444

45-
If you prefer, you can use this [pre-commit hook](misc/scripts/pre-commit) that automatically checks whether your files are correctly formatted. See the [pre-commit hook installation guide](docs/pre-commit-hook-setup.md) for instructions on how to install the hook.
45+
If you prefer, you can either:
46+
1. install the [pre-commit framework](https://pre-commit.com/) and install the configured hooks on this repo via `pre-commit install`, or
47+
2. use this [pre-commit hook](misc/scripts/pre-commit) that automatically checks whether your files are correctly formatted.
48+
49+
See the [pre-commit hook installation guide](docs/pre-commit-hook-setup.md) for instructions on the two approaches.
4650

4751
4. **Compilation**
4852

@@ -63,6 +67,6 @@ After the experimental query is merged, we welcome pull requests to improve it.
6367

6468
## Using your personal data
6569

66-
If you contribute to this project, we will record your name and email address (as provided by you with your contributions) as part of the code repositories, which are public. We might also use this information to contact you in relation to your contributions, as well as in the normal course of software development. We also store records of CLA agreements signed in the past, but no longer require contributors to sign a CLA. Under GDPR legislation, we do this on the basis of our legitimate interest in creating the CodeQL product.
70+
If you contribute to this project, we will record your name and email address (as provided by you with your contributions) as part of the code repositories, which are public. We might also use this information to contact you in relation to your contributions, as well as in the normal course of software development. We also store records of CLA agreements signed in the past, but no longer require contributors to sign a CLA. Under GDPR legislation, we do this on the basis of our legitimate interest in creating the CodeQL product.
6771

6872
Please do get in touch ([email protected]) if you have any questions about this or our data protection policies.

cpp/ql/lib/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.0.10
2+
3+
### New Features
4+
5+
* Added a `isStructuredBinding` predicate to the `Variable` class which holds when the variable is declared as part of a structured binding declaration.
6+
17
## 0.0.9
28

39
## 0.0.8
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Many queries now support structured bindings, as structured bindings are now handled in the IR translation.
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
---
2-
category: feature
3-
---
1+
## 0.0.10
2+
3+
### New Features
4+
45
* Added a `isStructuredBinding` predicate to the `Variable` class which holds when the variable is declared as part of a structured binding declaration.

cpp/ql/lib/codeql-pack.release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
lastReleaseVersion: 0.0.9
2+
lastReleaseVersion: 0.0.10

cpp/ql/lib/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cpp-all
2-
version: 0.0.10-dev
2+
version: 0.0.11-dev
33
groups: cpp
44
dbscheme: semmlecode.cpp.dbscheme
55
extractor: cpp

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ newtype TInstructionTag =
7171
AsmTag() or
7272
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) } or
7373
ThisAddressTag() or
74-
ThisLoadTag()
74+
ThisLoadTag() or
75+
StructuredBindingAccessTag()
7576

7677
class InstructionTag extends TInstructionTag {
7778
final string toString() { result = "Tag" }
@@ -221,4 +222,6 @@ string getInstructionTagId(TInstructionTag tag) {
221222
tag = ThisAddressTag() and result = "ThisAddress"
222223
or
223224
tag = ThisLoadTag() and result = "ThisLoad"
225+
or
226+
tag = StructuredBindingAccessTag() and result = "StructuredBindingAccess"
224227
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import semmle.code.cpp.ir.implementation.IRType
33
private import semmle.code.cpp.ir.implementation.Opcode
44
private import semmle.code.cpp.ir.implementation.internal.OperandTag
55
private import semmle.code.cpp.ir.internal.CppType
6+
private import semmle.code.cpp.ir.internal.IRUtilities
67
private import semmle.code.cpp.ir.internal.TempVariableTag
78
private import InstructionTag
89
private import TranslatedCondition
@@ -813,7 +814,9 @@ abstract class TranslatedVariableAccess extends TranslatedNonConstantExpr {
813814
}
814815

815816
class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
816-
TranslatedNonFieldVariableAccess() { not expr instanceof FieldAccess }
817+
TranslatedNonFieldVariableAccess() {
818+
not expr instanceof FieldAccess and not isNonReferenceStructuredBinding(expr.getTarget())
819+
}
817820

818821
override Instruction getFirstInstruction() {
819822
if exists(this.getQualifier())
@@ -860,6 +863,71 @@ class TranslatedFieldAccess extends TranslatedVariableAccess {
860863
}
861864
}
862865

866+
/**
867+
* The IR translation of a variable access of a structured binding, where the type
868+
* of the structured binding is not of a reference type, e.g., `x0` and `x1`
869+
* in `auto [x0, x1] = xs` where `xs` is an array. Although the type of the
870+
* structured binding is a non-reference type, the structured binding behaves
871+
* like a reference. Hence, the translation requires a `VariableAddress` followed
872+
* by a `Load` instead of only a `VariableAddress` as produced by
873+
* `TranslatedVariableAccess`.
874+
*/
875+
class TranslatedStructuredBindingVariableAccess extends TranslatedNonConstantExpr {
876+
override VariableAccess expr;
877+
878+
TranslatedStructuredBindingVariableAccess() { isNonReferenceStructuredBinding(expr.getTarget()) }
879+
880+
override Instruction getFirstInstruction() {
881+
// Structured bindings cannot be qualified.
882+
result = this.getInstruction(StructuredBindingAccessTag())
883+
}
884+
885+
override TranslatedElement getChild(int id) {
886+
// Structured bindings cannot be qualified.
887+
none()
888+
}
889+
890+
override Instruction getResult() { result = this.getInstruction(LoadTag()) }
891+
892+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
893+
tag = StructuredBindingAccessTag() and
894+
kind instanceof GotoEdge and
895+
result = this.getInstruction(LoadTag())
896+
or
897+
tag = LoadTag() and
898+
kind instanceof GotoEdge and
899+
result = this.getParent().getChildSuccessor(this)
900+
}
901+
902+
override Instruction getChildSuccessor(TranslatedElement child) { none() }
903+
904+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
905+
tag = StructuredBindingAccessTag() and
906+
opcode instanceof Opcode::VariableAddress and
907+
resultType = getTypeForGLValue(this.getLValueReferenceType())
908+
or
909+
tag = LoadTag() and
910+
opcode instanceof Opcode::Load and
911+
resultType = getTypeForPRValue(this.getLValueReferenceType())
912+
}
913+
914+
private LValueReferenceType getLValueReferenceType() {
915+
// The extractor ensures `result` exists when `isNonReferenceStructuredBinding(expr.getTarget())` holds.
916+
result.getBaseType() = expr.getUnspecifiedType()
917+
}
918+
919+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
920+
tag = LoadTag() and
921+
operandTag instanceof AddressOperandTag and
922+
result = this.getInstruction(StructuredBindingAccessTag())
923+
}
924+
925+
override IRVariable getInstructionVariable(InstructionTag tag) {
926+
tag = StructuredBindingAccessTag() and
927+
result = getIRUserVariable(expr.getEnclosingFunction(), expr.getTarget())
928+
}
929+
}
930+
863931
class TranslatedFunctionAccess extends TranslatedNonConstantExpr {
864932
override FunctionAccess expr;
865933

cpp/ql/lib/semmle/code/cpp/ir/internal/IRUtilities.qll

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ private Type getDecayedType(Type type) {
1111
result.(PointerType).getBaseType() = type.(ArrayType).getBaseType()
1212
}
1313

14+
/**
15+
* Holds if the sepcified variable is a structured binding with a non-reference
16+
* type.
17+
*/
18+
predicate isNonReferenceStructuredBinding(Variable v) {
19+
v.isStructuredBinding() and
20+
not v.getUnspecifiedType() instanceof ReferenceType
21+
}
22+
1423
/**
1524
* Get the actual type of the specified variable, as opposed to the declared type.
1625
* This returns the type of the variable after any pointer decay is applied, and
@@ -30,7 +39,12 @@ Type getVariableType(Variable v) {
3039
result = v.getInitializer().getExpr().getType()
3140
or
3241
not exists(v.getInitializer()) and result = v.getType()
33-
else result = v.getType()
42+
else
43+
if isNonReferenceStructuredBinding(v)
44+
then
45+
// The extractor ensures `r` exists when `isNonReferenceStructuredBinding(v)` holds.
46+
exists(LValueReferenceType r | r.getBaseType() = v.getUnspecifiedType() | result = r)
47+
else result = v.getType()
3448
)
3549
}
3650

0 commit comments

Comments
 (0)