Skip to content

Commit c4940aa

Browse files
committed
Merge branch 'master' into copymove
2 parents 37158f4 + 7dd2677 commit c4940aa

File tree

826 files changed

+36642
-31656
lines changed

Some content is hidden

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

826 files changed

+36642
-31656
lines changed

cpp/autobuilder/.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
obj/
2+
TestResults/
3+
*.manifest
4+
*.pdb
5+
*.suo
6+
*.mdb
7+
*.vsmdi
8+
csharp.log
9+
**/bin/Debug
10+
**/bin/Release
11+
*.tlog
12+
.vs
13+
*.user

cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/Bound.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ private newtype TBound =
88
exists(Instruction i |
99
vn.getAnInstruction() = i and
1010
(
11-
i.getResultType() instanceof IntegralType or
12-
i.getResultType() instanceof PointerType
11+
i.getResultIRType() instanceof IRIntegerType or
12+
i.getResultIRType() instanceof IRAddressType
1313
) and
1414
not vn.getAnInstruction() instanceof ConstantInstruction
1515
|

cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,14 @@ class CondReason extends Reason, TCondReason {
244244
/**
245245
* Holds if `typ` is a small integral type with the given lower and upper bounds.
246246
*/
247-
private predicate typeBound(IntegralType typ, int lowerbound, int upperbound) {
248-
typ.isSigned() and typ.getSize() = 1 and lowerbound = -128 and upperbound = 127
247+
private predicate typeBound(IRIntegerType typ, int lowerbound, int upperbound) {
248+
typ.isSigned() and typ.getByteSize() = 1 and lowerbound = -128 and upperbound = 127
249249
or
250-
typ.isUnsigned() and typ.getSize() = 1 and lowerbound = 0 and upperbound = 255
250+
typ.isUnsigned() and typ.getByteSize() = 1 and lowerbound = 0 and upperbound = 255
251251
or
252-
typ.isSigned() and typ.getSize() = 2 and lowerbound = -32768 and upperbound = 32767
252+
typ.isSigned() and typ.getByteSize() = 2 and lowerbound = -32768 and upperbound = 32767
253253
or
254-
typ.isUnsigned() and typ.getSize() = 2 and lowerbound = 0 and upperbound = 65535
254+
typ.isUnsigned() and typ.getByteSize() = 2 and lowerbound = 0 and upperbound = 65535
255255
}
256256

257257
/**
@@ -260,14 +260,14 @@ private predicate typeBound(IntegralType typ, int lowerbound, int upperbound) {
260260
private class NarrowingCastInstruction extends ConvertInstruction {
261261
NarrowingCastInstruction() {
262262
not this instanceof SafeCastInstruction and
263-
typeBound(getResultType(), _, _)
263+
typeBound(getResultIRType(), _, _)
264264
}
265265

266266
/** Gets the lower bound of the resulting type. */
267-
int getLowerBound() { typeBound(getResultType(), result, _) }
267+
int getLowerBound() { typeBound(getResultIRType(), result, _) }
268268

269269
/** Gets the upper bound of the resulting type. */
270-
int getUpperBound() { typeBound(getResultType(), _, result) }
270+
int getUpperBound() { typeBound(getResultIRType(), _, result) }
271271
}
272272

273273
/**

cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/RangeUtils.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,15 @@ predicate backEdge(PhiInstruction phi, PhiInputOperand op) {
8686
* range analysis.
8787
*/
8888
pragma[inline]
89-
private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
90-
fromtyp.getSize() < totyp.getSize() and
89+
private predicate safeCast(IRIntegerType fromtyp, IRIntegerType totyp) {
90+
fromtyp.getByteSize() < totyp.getByteSize() and
9191
(
9292
fromtyp.isUnsigned()
9393
or
9494
totyp.isSigned()
9595
)
9696
or
97-
fromtyp.getSize() <= totyp.getSize() and
97+
fromtyp.getByteSize() <= totyp.getByteSize() and
9898
(
9999
fromtyp.isSigned() and
100100
totyp.isSigned()
@@ -109,8 +109,8 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
109109
*/
110110
class PtrToPtrCastInstruction extends ConvertInstruction {
111111
PtrToPtrCastInstruction() {
112-
getResultType() instanceof PointerType and
113-
getUnary().getResultType() instanceof PointerType
112+
getResultIRType() instanceof IRAddressType and
113+
getUnary().getResultIRType() instanceof IRAddressType
114114
}
115115
}
116116

@@ -119,7 +119,7 @@ class PtrToPtrCastInstruction extends ConvertInstruction {
119119
* that cannot overflow or underflow.
120120
*/
121121
class SafeIntCastInstruction extends ConvertInstruction {
122-
SafeIntCastInstruction() { safeCast(getUnary().getResultType(), getResultType()) }
122+
SafeIntCastInstruction() { safeCast(getUnary().getResultIRType(), getResultIRType()) }
123123
}
124124

125125
/**

cpp/ql/src/experimental/semmle/code/cpp/rangeanalysis/SignAnalysis.qll

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -469,17 +469,21 @@ module SignAnalysisCached {
469469
not exists(certainInstructionSign(i)) and
470470
not (
471471
result = TNeg() and
472-
i.getResultType().(IntegralType).isUnsigned()
472+
i.getResultIRType().(IRIntegerType).isUnsigned()
473473
) and
474474
(
475475
unknownSign(i)
476476
or
477477
exists(ConvertInstruction ci, Instruction prior, boolean fromSigned, boolean toSigned |
478478
i = ci and
479479
prior = ci.getUnary() and
480-
(if ci.getResultType().(IntegralType).isSigned() then toSigned = true else toSigned = false) and
481480
(
482-
if prior.getResultType().(IntegralType).isSigned()
481+
if ci.getResultIRType().(IRIntegerType).isSigned()
482+
then toSigned = true
483+
else toSigned = false
484+
) and
485+
(
486+
if prior.getResultIRType().(IRIntegerType).isSigned()
483487
then fromSigned = true
484488
else fromSigned = false
485489
) and
@@ -512,11 +516,11 @@ module SignAnalysisCached {
512516
i instanceof ShiftLeftInstruction and result = s1.lshift(s2)
513517
or
514518
i instanceof ShiftRightInstruction and
515-
i.getResultType().(IntegralType).isSigned() and
519+
i.getResultIRType().(IRIntegerType).isSigned() and
516520
result = s1.rshift(s2)
517521
or
518522
i instanceof ShiftRightInstruction and
519-
not i.getResultType().(IntegralType).isSigned() and
523+
not i.getResultIRType().(IRIntegerType).isSigned() and
520524
result = s1.urshift(s2)
521525
)
522526
or

cpp/ql/src/printAst.ql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* @name Print AST
3+
* @description Outputs a representation of a file's Abstract Syntax Tree. This
4+
* query is used by the VS Code extension.
5+
* @id cpp/print-ast
6+
* @kind graph
7+
* @tags ide-contextual-queries/print-ast
8+
*/
9+
10+
import cpp
11+
import semmle.code.cpp.PrintAST
12+
import definitions
13+
14+
/**
15+
* The source file to generate an AST from.
16+
*/
17+
external string selectedSourceFile();
18+
19+
class Cfg extends PrintASTConfiguration {
20+
/**
21+
* Holds if the AST for `func` should be printed.
22+
* Print All functions from the selected file.
23+
*/
24+
override predicate shouldPrintFunction(Function func) {
25+
func.getFile() = getEncodedFile(selectedSourceFile())
26+
}
27+
}

cpp/ql/src/semmle/code/cpp/Location.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ class Location extends @location {
1515
/** Gets the file corresponding to this location, if any. */
1616
File getFile() { result = this.getContainer() }
1717

18-
/** Gets the start line of this location. */
18+
/** Gets the 1-based line number (inclusive) where this location starts. */
1919
int getStartLine() { this.fullLocationInfo(_, result, _, _, _) }
2020

21-
/** Gets the start column of this location. */
21+
/** Gets the 1-based column number (inclusive) where this location starts. */
2222
int getStartColumn() { this.fullLocationInfo(_, _, result, _, _) }
2323

24-
/** Gets the end line of this location. */
24+
/** Gets the 1-based line number (inclusive) where this location ends. */
2525
int getEndLine() { this.fullLocationInfo(_, _, _, result, _) }
2626

27-
/** Gets the end column of this location. */
27+
/** Gets the 1-based column number (inclusive) where this location ends. */
2828
int getEndColumn() { this.fullLocationInfo(_, _, _, _, result) }
2929

3030
/**

cpp/ql/src/semmle/code/cpp/Preprocessor.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ class PreprocessorDirective extends Locatable, @preprocdirect {
3333
}
3434
}
3535

36+
private class TPreprocessorBranchDirective = @ppd_branch or @ppd_else or @ppd_endif;
37+
3638
/**
3739
* A C/C++ preprocessor branch related directive: `#if`, `#ifdef`,
3840
* `#ifndef`, `#elif`, `#else` or `#endif`.
3941
*/
40-
abstract class PreprocessorBranchDirective extends PreprocessorDirective {
42+
class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBranchDirective {
4143
/**
4244
* Gets the `#if`, `#ifdef` or `#ifndef` directive which matches this
4345
* branching directive.

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,20 @@ predicate clearsContent(Node n, Content c) {
234234
}
235235

236236
/** Gets the type of `n` used for type pruning. */
237-
Type getNodeType(Node n) {
237+
IRType getNodeType(Node n) {
238238
suppressUnusedNode(n) and
239-
result instanceof VoidType // stub implementation
239+
result instanceof IRVoidType // stub implementation
240240
}
241241

242242
/** Gets a string representation of a type returned by `getNodeType`. */
243-
string ppReprType(Type t) { none() } // stub implementation
243+
string ppReprType(IRType t) { none() } // stub implementation
244244

245245
/**
246246
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
247247
* a node of type `t1` to a node of type `t2`.
248248
*/
249249
pragma[inline]
250-
predicate compatibleTypes(Type t1, Type t2) {
250+
predicate compatibleTypes(IRType t1, IRType t2) {
251251
any() // stub implementation
252252
}
253253

@@ -271,7 +271,7 @@ class DataFlowCallable = Declaration;
271271

272272
class DataFlowExpr = Expr;
273273

274-
class DataFlowType = Type;
274+
class DataFlowType = IRType;
275275

276276
/** A function call relevant for data flow. */
277277
class DataFlowCall extends CallInstruction {
@@ -303,4 +303,4 @@ predicate isImmutableOrUnobservable(Node n) {
303303
}
304304

305305
/** Holds if `n` should be hidden from path explanations. */
306-
predicate nodeIsHidden(Node n) { none() }
306+
predicate nodeIsHidden(Node n) { n instanceof OperandNode }

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
1313

1414
private newtype TIRDataFlowNode =
1515
TInstructionNode(Instruction i) or
16+
TOperandNode(Operand op) or
1617
TVariableNode(Variable var)
1718

1819
/**
@@ -32,11 +33,14 @@ class Node extends TIRDataFlowNode {
3233
Function getFunction() { none() } // overridden in subclasses
3334

3435
/** Gets the type of this node. */
35-
Type getType() { none() } // overridden in subclasses
36+
IRType getType() { none() } // overridden in subclasses
3637

3738
/** Gets the instruction corresponding to this node, if any. */
3839
Instruction asInstruction() { result = this.(InstructionNode).getInstruction() }
3940

41+
/** Gets the operands corresponding to this node, if any. */
42+
Operand asOperand() { result = this.(OperandNode).getOperand() }
43+
4044
/**
4145
* Gets the non-conversion expression corresponding to this node, if any. If
4246
* this node strictly (in the sense of `asConvertedExpr`) corresponds to a
@@ -84,7 +88,7 @@ class Node extends TIRDataFlowNode {
8488
/**
8589
* Gets an upper bound on the type of this node.
8690
*/
87-
Type getTypeBound() { result = getType() }
91+
IRType getTypeBound() { result = getType() }
8892

8993
/** Gets the location of this element. */
9094
Location getLocation() { none() } // overridden by subclasses
@@ -121,7 +125,7 @@ class InstructionNode extends Node, TInstructionNode {
121125

122126
override Function getFunction() { result = instr.getEnclosingFunction() }
123127

124-
override Type getType() { result = instr.getResultType() }
128+
override IRType getType() { result = instr.getResultIRType() }
125129

126130
override Location getLocation() { result = instr.getLocation() }
127131

@@ -132,6 +136,28 @@ class InstructionNode extends Node, TInstructionNode {
132136
}
133137
}
134138

139+
/**
140+
* An operand, viewed as a node in a data flow graph.
141+
*/
142+
class OperandNode extends Node, TOperandNode {
143+
Operand op;
144+
145+
OperandNode() { this = TOperandNode(op) }
146+
147+
/** Gets the operand corresponding to this node. */
148+
Operand getOperand() { result = op }
149+
150+
override Declaration getEnclosingCallable() { result = this.getFunction() }
151+
152+
override Function getFunction() { result = op.getUse().getEnclosingFunction() }
153+
154+
override IRType getType() { result = op.getIRType() }
155+
156+
override Location getLocation() { result = op.getLocation() }
157+
158+
override string toString() { result = this.getOperand().toString() }
159+
}
160+
135161
/**
136162
* An expression, viewed as a node in a data flow graph.
137163
*/
@@ -291,7 +317,7 @@ abstract class PostUpdateNode extends InstructionNode {
291317
* setY(&x); // a partial definition of the object `x`.
292318
* ```
293319
*/
294-
abstract private class PartialDefinitionNode extends PostUpdateNode, TInstructionNode {
320+
abstract private class PartialDefinitionNode extends PostUpdateNode {
295321
abstract Expr getDefinedExpr();
296322
}
297323

@@ -306,11 +332,11 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
306332
)
307333
}
308334

309-
// There might be multiple `ChiInstructions` that has a particular instruction as
310-
// the total operand - so this definition gives consistency errors in
311-
// DataFlowImplConsistency::Consistency. However, it's not clear what (if any) implications
312-
// this consistency failure has.
313-
override Node getPreUpdateNode() { result.asInstruction() = instr.getTotal() }
335+
// By using an operand as the result of this predicate we avoid the dataflow inconsistency errors
336+
// caused by having multiple nodes sharing the same pre update node. This inconsistency error can cause
337+
// a tuple explosion in the big step dataflow relation since it can make many nodes be the entry node
338+
// into a big step.
339+
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
314340

315341
override Expr getDefinedExpr() {
316342
result = field.getObjectAddress().getUnconvertedResultExpression()
@@ -423,7 +449,7 @@ class VariableNode extends Node, TVariableNode {
423449
result = v
424450
}
425451

426-
override Type getType() { result = v.getType() }
452+
override IRType getType() { result.getCanonicalLanguageType().hasUnspecifiedType(v.getType(), _) }
427453

428454
override Location getLocation() { result = v.getLocation() }
429455

@@ -482,7 +508,11 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
482508
* data flow. It may have less flow than the `localFlowStep` predicate.
483509
*/
484510
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
511+
// Instruction -> Instruction flow
485512
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
513+
or
514+
// Operand -> Instruction flow
515+
simpleOperandLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())
486516
}
487517

488518
pragma[noinline]
@@ -494,6 +524,16 @@ private predicate getFieldSizeOfClass(Class c, Type type, int size) {
494524
)
495525
}
496526

527+
private predicate simpleOperandLocalFlowStep(Operand opFrom, Instruction iTo) {
528+
// Certain dataflow steps (for instance `PostUpdateNode.getPreUpdateNode()`) generates flow to
529+
// operands, so we include dataflow from those operands to the "result" of the instruction (i.e., to
530+
// the instruction itself).
531+
exists(PostUpdateNode post |
532+
opFrom = post.getPreUpdateNode().asOperand() and
533+
iTo.getAnOperand() = opFrom
534+
)
535+
}
536+
497537
cached
498538
private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo) {
499539
iTo.(CopyInstruction).getSourceValue() = iFrom

0 commit comments

Comments
 (0)