Skip to content

Commit 530d429

Browse files
committed
Merge remote-tracking branch 'upstream/master' into DefaultTaintTracking-Configuration
2 parents 58366b1 + 316d932 commit 530d429

File tree

75 files changed

+1903
-335
lines changed

Some content is hidden

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

75 files changed

+1903
-335
lines changed

change-notes/1.24/analysis-cpp.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
2020
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
2121
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed false positive results in template code. |
2222
| Missing return statement (`cpp/missing-return`) | Fewer false positive results | Functions containing `asm` statements are no longer highlighted by this query. |
23+
| Missing return statement (`cpp/missing-return`) | More accurate locations | Locations reported by this query are now more accurate in some cases. |
2324
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | String arguments to formatting functions are now (usually) expected to be null terminated strings. |
2425
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |
2526
| No space for zero terminator (`cpp/no-space-for-terminator`) | Fewer false positive results | This query has been modified to be more conservative when identifying which pointers point to null-terminated strings. This approach produces fewer, more accurate results. |
@@ -45,6 +46,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
4546
`StackVariableReachability`. The functionality is the same.
4647
* The models library models `strlen` in more detail, and includes common variations such as `wcslen`.
4748
* The models library models `gets` and similar functions.
49+
* The models library now partially models `std::string`.
4850
* The taint tracking library (`semmle.code.cpp.dataflow.TaintTracking`) has had
4951
the following improvements:
5052
* The library now models data flow through `strdup` and similar functions.

config/identical-files.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@
242242
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/gvn/ValueNumbering.qll",
243243
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll"
244244
],
245+
"C++ IR PrintValueNumbering": [
246+
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
247+
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll",
248+
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll",
249+
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
250+
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll"
251+
],
245252
"C++ IR ConstantAnalysis": [
246253
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
247254
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/ConstantAnalysis.qll",

cpp/ql/src/jsf/4.13 Functions/AV Rule 114.ql

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ predicate functionsMissingReturnStmt(Function f, ControlFlowNode blame) {
3030
) and
3131
exists(ReturnStmt s |
3232
f.getAPredecessor() = s and
33-
blame = s.getAPredecessor()
33+
(
34+
blame = s.getAPredecessor() and
35+
count(blame.getASuccessor()) = 1
36+
or
37+
blame = s and
38+
exists(ControlFlowNode pred | pred = s.getAPredecessor() | count(pred.getASuccessor()) != 1)
39+
)
3440
)
3541
}
3642

cpp/ql/src/semmle/code/cpp/exprs/Expr.qll

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import semmle.code.cpp.Element
22
private import semmle.code.cpp.Enclosing
33
private import semmle.code.cpp.internal.ResolveClass
44
private import semmle.code.cpp.internal.AddressConstantExpression
5+
private import semmle.code.cpp.models.implementations.Allocation
56

67
/**
78
* A C/C++ expression.
@@ -804,8 +805,10 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
804805
* call the constructor of `T` but will not allocate memory.
805806
*/
806807
Expr getPlacementPointer() {
807-
isStandardPlacementNewAllocator(this.getAllocator()) and
808-
result = this.getAllocatorCall().getArgument(1)
808+
result =
809+
this
810+
.getAllocatorCall()
811+
.getArgument(this.getAllocator().(OperatorNewAllocationFunction).getPlacementArgument())
809812
}
810813
}
811814

@@ -1194,12 +1197,6 @@ private predicate convparents(Expr child, int idx, Element parent) {
11941197
)
11951198
}
11961199

1197-
private predicate isStandardPlacementNewAllocator(Function operatorNew) {
1198-
operatorNew.getName().matches("operator new%") and
1199-
operatorNew.getNumberOfParameters() = 2 and
1200-
operatorNew.getParameter(1).getType() instanceof VoidPointerType
1201-
}
1202-
12031200
// Pulled out for performance. See QL-796.
12041201
private predicate hasNoConversions(Expr e) { not e.hasConversion() }
12051202

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
private import internal.ValueNumberingImports
2+
private import ValueNumbering
3+
4+
/**
5+
* Provides additional information about value numbering in IR dumps.
6+
*/
7+
class ValueNumberPropertyProvider extends IRPropertyProvider {
8+
override string getInstructionProperty(Instruction instr, string key) {
9+
exists(ValueNumber vn |
10+
vn = valueNumber(instr) and
11+
key = "valnum" and
12+
if strictcount(vn.getAnInstruction()) > 1
13+
then result = vn.getDebugString()
14+
else result = "unique"
15+
)
16+
}
17+
}

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,6 @@
11
private import internal.ValueNumberingInternal
22
private import internal.ValueNumberingImports
33

4-
/**
5-
* Provides additional information about value numbering in IR dumps.
6-
*/
7-
class ValueNumberPropertyProvider extends IRPropertyProvider {
8-
override string getInstructionProperty(Instruction instr, string key) {
9-
exists(ValueNumber vn |
10-
vn = valueNumber(instr) and
11-
key = "valnum" and
12-
if strictcount(vn.getAnInstruction()) > 1
13-
then result = vn.getDebugString()
14-
else result = "unique"
15-
)
16-
}
17-
}
18-
194
/**
205
* The value number assigned to a particular set of instructions that produce equivalent results.
216
*/
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
private import internal.ValueNumberingImports
2+
private import ValueNumbering
3+
4+
/**
5+
* Provides additional information about value numbering in IR dumps.
6+
*/
7+
class ValueNumberPropertyProvider extends IRPropertyProvider {
8+
override string getInstructionProperty(Instruction instr, string key) {
9+
exists(ValueNumber vn |
10+
vn = valueNumber(instr) and
11+
key = "valnum" and
12+
if strictcount(vn.getAnInstruction()) > 1
13+
then result = vn.getDebugString()
14+
else result = "unique"
15+
)
16+
}
17+
}

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,6 @@
11
private import internal.ValueNumberingInternal
22
private import internal.ValueNumberingImports
33

4-
/**
5-
* Provides additional information about value numbering in IR dumps.
6-
*/
7-
class ValueNumberPropertyProvider extends IRPropertyProvider {
8-
override string getInstructionProperty(Instruction instr, string key) {
9-
exists(ValueNumber vn |
10-
vn = valueNumber(instr) and
11-
key = "valnum" and
12-
if strictcount(vn.getAnInstruction()) > 1
13-
then result = vn.getDebugString()
14-
else result = "unique"
15-
)
16-
}
17-
}
18-
194
/**
205
* The value number assigned to a particular set of instructions that produce equivalent results.
216
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll

Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,44 @@ abstract class TranslatedCall extends TranslatedExpr {
206206

207207
predicate hasPreciseSideEffect() { exists(getSideEffects()) }
208208

209-
TranslatedSideEffects getSideEffects() { result.getCall() = expr }
209+
final TranslatedSideEffects getSideEffects() { result.getExpr() = expr }
210+
}
211+
212+
abstract class TranslatedSideEffects extends TranslatedElement {
213+
abstract Expr getExpr();
214+
215+
final override Locatable getAST() { result = getExpr() }
216+
217+
final override Function getFunction() { result = getExpr().getEnclosingFunction() }
218+
219+
override TranslatedElement getChild(int i) {
220+
result =
221+
rank[i + 1](TranslatedSideEffect tse, int isWrite, int index |
222+
(
223+
tse.getCall() = getExpr() and
224+
tse.getArgumentIndex() = index and
225+
if tse.isWrite() then isWrite = 1 else isWrite = 0
226+
)
227+
|
228+
tse order by isWrite, index
229+
)
230+
}
231+
232+
final override Instruction getChildSuccessor(TranslatedElement te) {
233+
exists(int i |
234+
getChild(i) = te and
235+
if exists(getChild(i + 1))
236+
then result = getChild(i + 1).getFirstInstruction()
237+
else result = getParent().getChildSuccessor(this)
238+
)
239+
}
240+
241+
/**
242+
* Gets the `TranslatedFunction` containing this expression.
243+
*/
244+
final TranslatedFunction getEnclosingFunction() {
245+
result = getTranslatedFunction(getExpr().getEnclosingFunction())
246+
}
210247
}
211248

212249
/**
@@ -308,56 +345,27 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
308345
override predicate hasQualifier() { any() }
309346
}
310347

311-
class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
312-
Call expr;
313-
314-
TranslatedSideEffects() { this = TTranslatedSideEffects(expr) }
348+
class TranslatedAllocationSideEffects extends TranslatedSideEffects,
349+
TTranslatedAllocationSideEffects {
350+
AllocationExpr expr;
315351

316-
override string toString() { result = "(side effects for " + expr.toString() + ")" }
352+
TranslatedAllocationSideEffects() { this = TTranslatedAllocationSideEffects(expr) }
317353

318-
override Locatable getAST() { result = expr }
354+
final override AllocationExpr getExpr() { result = expr }
319355

320-
Call getCall() { result = expr }
356+
override string toString() { result = "(allocation side effects for " + expr.toString() + ")" }
321357

322-
override TranslatedElement getChild(int i) {
323-
result =
324-
rank[i + 1](TranslatedSideEffect tse, int isWrite, int index |
325-
(
326-
tse.getCall() = getCall() and
327-
tse.getArgumentIndex() = index and
328-
if tse.isWrite() then isWrite = 1 else isWrite = 0
329-
)
330-
|
331-
tse order by isWrite, index
332-
)
333-
}
334-
335-
override Instruction getChildSuccessor(TranslatedElement te) {
336-
exists(int i |
337-
getChild(i) = te and
338-
if exists(getChild(i + 1))
339-
then result = getChild(i + 1).getFirstInstruction()
340-
else result = getParent().getChildSuccessor(this)
341-
)
342-
}
358+
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
343359

344360
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
345-
expr.getTarget() instanceof AllocationFunction and
346361
opcode instanceof Opcode::InitializeDynamicAllocation and
347362
tag = OnlyInstructionTag() and
348363
type = getUnknownType()
349364
}
350365

351-
override Instruction getFirstInstruction() {
352-
if expr.getTarget() instanceof AllocationFunction
353-
then result = getInstruction(OnlyInstructionTag())
354-
else result = getChild(0).getFirstInstruction()
355-
}
356-
357366
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
358367
tag = OnlyInstructionTag() and
359368
kind = gotoEdge() and
360-
expr.getTarget() instanceof AllocationFunction and
361369
if exists(getChild(0))
362370
then result = getChild(0).getFirstInstruction()
363371
else result = getParent().getChildSuccessor(this)
@@ -371,23 +379,34 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
371379

372380
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
373381
tag = OnlyInstructionTag() and
374-
result = getTranslatedExpr(expr).getInstruction(CallTag())
382+
if expr instanceof NewOrNewArrayExpr
383+
then result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
384+
else result = getTranslatedExpr(expr).getInstruction(CallTag())
375385
}
386+
}
376387

377-
/**
378-
* Gets the `TranslatedFunction` containing this expression.
379-
*/
380-
final TranslatedFunction getEnclosingFunction() {
381-
result = getTranslatedFunction(expr.getEnclosingFunction())
382-
}
388+
class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSideEffects {
389+
Call expr;
383390

384-
/**
385-
* Gets the `Function` containing this expression.
386-
*/
387-
override Function getFunction() { result = expr.getEnclosingFunction() }
391+
TranslatedCallSideEffects() { this = TTranslatedCallSideEffects(expr) }
392+
393+
override string toString() { result = "(side effects for " + expr.toString() + ")" }
394+
395+
override Call getExpr() { result = expr }
396+
397+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { none() }
398+
399+
override Instruction getFirstInstruction() { result = getChild(0).getFirstInstruction() }
400+
401+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
402+
403+
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
404+
tag = OnlyInstructionTag() and
405+
result = getTranslatedExpr(expr).getInstruction(CallTag())
406+
}
388407
}
389408

390-
class TranslatedStructorCallSideEffects extends TranslatedSideEffects {
409+
class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
391410
TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() }
392411

393412
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,22 @@ newtype TTranslatedElement =
442442
// The declaration/initialization part of a `ConditionDeclExpr`
443443
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
444444
// The side effects of a `Call`
445-
TTranslatedSideEffects(Call expr) {
446-
exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or
447-
expr instanceof ConstructorCall or
448-
expr.getTarget() instanceof AllocationFunction
449-
} or // A precise side effect of an argument to a `Call`
445+
TTranslatedCallSideEffects(Call expr) {
446+
// Exclude allocations such as `malloc` (which happen to also be function calls).
447+
// Both `TranslatedCallSideEffects` and `TranslatedAllocationSideEffects` generate
448+
// the same side effects for its children as they both extend the `TranslatedSideEffects`
449+
// class.
450+
// Note: We can separate allocation side effects and call side effects into two
451+
// translated elements as no call can be both a `ConstructorCall` and an `AllocationExpr`.
452+
not expr instanceof AllocationExpr and
453+
(
454+
exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or
455+
expr instanceof ConstructorCall
456+
)
457+
} or
458+
// The side effects of an allocation, i.e. `new`, `new[]` or `malloc`
459+
TTranslatedAllocationSideEffects(AllocationExpr expr) or
460+
// A precise side effect of an argument to a `Call`
450461
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) {
451462
(
452463
expr = call.getArgument(n).getFullyConverted()

0 commit comments

Comments
 (0)