Skip to content

Commit b665f45

Browse files
authored
Merge branch 'main' into unreachable2
2 parents e1aaa13 + 41e8117 commit b665f45

File tree

88 files changed

+37172
-32798
lines changed

Some content is hidden

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

88 files changed

+37172
-32798
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The function call target resolution algorithm has been improved to resolve more calls through function pointers. As a result, dataflow queries may have more results.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: feature
3+
---
4+
* Added a new predicate `DataFlow::getARuntimeTarget` for getting a function that may be invoked by a `Call` expression. Unlike `Call.getTarget` this new predicate may also resolve function pointers.

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class Element extends ElementBase {
129129
* or certain kinds of `Statement`.
130130
*/
131131
Element getParentScope() {
132-
// result instanceof class
132+
// result instanceof Class
133133
exists(Declaration m |
134134
m = this and
135135
result = m.getDeclaringType() and
@@ -138,31 +138,40 @@ class Element extends ElementBase {
138138
or
139139
exists(TemplateClass tc | this = tc.getATemplateArgument() and result = tc)
140140
or
141-
// result instanceof namespace
141+
// result instanceof Namespace
142142
exists(Namespace n | result = n and n.getADeclaration() = this)
143143
or
144144
exists(FriendDecl d, Namespace n | this = d and n.getADeclaration() = d and result = n)
145145
or
146146
exists(Namespace n | this = n and result = n.getParentNamespace())
147147
or
148-
// result instanceof stmt
148+
// result instanceof Stmt
149149
exists(LocalVariable v |
150150
this = v and
151151
exists(DeclStmt ds | ds.getADeclaration() = v and result = ds.getParent())
152152
)
153153
or
154-
exists(Parameter p | this = p and result = p.getFunction())
154+
exists(Parameter p |
155+
this = p and
156+
(
157+
result = p.getFunction() or
158+
result = p.getCatchBlock().getParent().(Handler).getParent().(TryStmt).getParent() or
159+
result = p.getRequiresExpr().getEnclosingStmt().getParent()
160+
)
161+
)
155162
or
156163
exists(GlobalVariable g, Namespace n | this = g and n.getADeclaration() = g and result = n)
157164
or
165+
exists(TemplateVariable tv | this = tv.getATemplateArgument() and result = tv)
166+
or
158167
exists(EnumConstant e | this = e and result = e.getDeclaringEnum())
159168
or
160-
// result instanceof block|function
169+
// result instanceof Block|Function
161170
exists(BlockStmt b | this = b and blockscope(unresolveElement(b), unresolveElement(result)))
162171
or
163172
exists(TemplateFunction tf | this = tf.getATemplateArgument() and result = tf)
164173
or
165-
// result instanceof stmt
174+
// result instanceof Stmt
166175
exists(ControlStructure s | this = s and result = s.getParent())
167176
or
168177
using_container(unresolveElement(result), underlyingElement(this))

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ class Parameter extends LocalScopeVariable, @parameter {
7373
}
7474

7575
private VariableDeclarationEntry getANamedDeclarationEntry() {
76-
result = this.getAnEffectiveDeclarationEntry() and result.getName() != ""
76+
result = this.getAnEffectiveDeclarationEntry() and
77+
exists(string name | var_decls(unresolveElement(result), _, _, name, _) | name != "")
7778
}
7879

7980
/**

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
241241
name != "" and result = name
242242
or
243243
name = "" and result = this.getVariable().(LocalVariable).getName()
244+
or
245+
name = "" and
246+
not this instanceof ParameterDeclarationEntry and
247+
result = this.getVariable().(Parameter).getName()
244248
)
245249
)
246250
}
@@ -295,19 +299,11 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
295299

296300
private string getAnonymousParameterDescription() {
297301
not exists(this.getName()) and
298-
exists(string idx |
299-
idx =
300-
((this.getIndex() + 1).toString() + "th")
301-
.replaceAll("1th", "1st")
302-
.replaceAll("2th", "2nd")
303-
.replaceAll("3th", "3rd")
304-
.replaceAll("11st", "11th")
305-
.replaceAll("12nd", "12th")
306-
.replaceAll("13rd", "13th") and
302+
exists(string anon |
303+
anon = "(unnamed parameter " + this.getIndex().toString() + ")" and
307304
if exists(this.getCanonicalName())
308-
then
309-
result = "declaration of " + this.getCanonicalName() + " as anonymous " + idx + " parameter"
310-
else result = "declaration of " + idx + " parameter"
305+
then result = "declaration of " + this.getCanonicalName() + " as " + anon
306+
else result = "declaration of " + anon
311307
)
312308
}
313309

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,10 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
13281328

13291329
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
13301330
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
1331-
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() and
1331+
(
1332+
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() or
1333+
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
1334+
) and
13321335
exists(kind)
13331336
}
13341337

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ private import SsaInternals as Ssa
1717
private import DataFlowImplCommon as DataFlowImplCommon
1818
private import codeql.util.Unit
1919
private import Node0ToString
20+
private import DataFlowDispatch as DataFlowDispatch
2021
import ExprNodes
2122

2223
/**
@@ -2497,3 +2498,16 @@ class AdditionalCallTarget extends Unit {
24972498
*/
24982499
abstract Declaration viableTarget(Call call);
24992500
}
2501+
2502+
/**
2503+
* Gets a function that may be called by `call`.
2504+
*
2505+
* Note that `call` may be a call to a function pointer expression.
2506+
*/
2507+
Function getARuntimeTarget(Call call) {
2508+
exists(DataFlowCall dfCall | dfCall.asCallInstruction().getUnconvertedResultExpression() = call |
2509+
result = DataFlowDispatch::viableCallable(dfCall).asSourceCallable()
2510+
or
2511+
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
2512+
)
2513+
}

cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ uniqueEnclosingCallable
33
| test.cpp:864:47:864:54 | call to source | Node should have one enclosing callable but has 0. |
44
| test.cpp:872:46:872:51 | call to source | Node should have one enclosing callable but has 0. |
55
| test.cpp:872:53:872:56 | 1 | Node should have one enclosing callable but has 0. |
6+
| test.cpp:1126:33:1129:1 | {...} | Node should have one enclosing callable but has 0. |
7+
| test.cpp:1127:3:1127:13 | reads_input | Node should have one enclosing callable but has 0. |
8+
| test.cpp:1128:3:1128:21 | not_does_read_input | Node should have one enclosing callable but has 0. |
69
uniqueCallEnclosingCallable
710
| test.cpp:864:47:864:54 | call to source | Call should have one enclosing callable but has 0. |
811
| test.cpp:872:46:872:51 | call to source | Call should have one enclosing callable but has 0. |

cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ irFlow
323323
| test.cpp:1069:9:1069:14 | call to source | test.cpp:1074:10:1074:10 | i |
324324
| test.cpp:1069:9:1069:14 | call to source | test.cpp:1081:10:1081:10 | i |
325325
| test.cpp:1117:27:1117:34 | call to source | test.cpp:1117:27:1117:34 | call to source |
326+
| test.cpp:1132:11:1132:16 | call to source | test.cpp:1121:8:1121:8 | x |
326327
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
327328
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
328329
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |

cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,4 +1115,20 @@ void indirect_sink_const_ref(const T&);
11151115

11161116
void test_temp_with_conversion_from_materialization() {
11171117
indirect_sink_const_ref(source()); // $ ir MISSING: ast
1118+
}
1119+
1120+
void reads_input(int x) {
1121+
sink(x); // $ ir MISSING: ast
1122+
}
1123+
1124+
void not_does_read_input(int x);
1125+
1126+
void (*dispatch_table[])(int) = {
1127+
reads_input,
1128+
not_does_read_input
1129+
};
1130+
1131+
void test_dispatch_table(int i) {
1132+
int x = source();
1133+
dispatch_table[i](x);
11181134
}

0 commit comments

Comments
 (0)