Skip to content

Commit fa344d2

Browse files
authored
Merge pull request #4493 from criemen/fix-4278-printast-conversions
Fix C++ Print AST handling of Conversions
2 parents 7856e78 + 59dd892 commit fa344d2

File tree

4 files changed

+2259
-2171
lines changed

4 files changed

+2259
-2171
lines changed

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

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,32 @@ class PrintASTNode extends TPrintASTNode {
114114

115115
/**
116116
* Gets the child node at index `childIndex`. Child indices must be unique,
117-
* but need not be contiguous (but see `getChildByRank`).
117+
* but need not be contiguous.
118118
*/
119-
abstract PrintASTNode getChild(int childIndex);
119+
abstract PrintASTNode getChildInternal(int childIndex);
120+
121+
/**
122+
* Gets the child node at index `childIndex`.
123+
* Adds edges to fully converted expressions, that are not part of the
124+
* regular parent/child relation traversal.
125+
*/
126+
final PrintASTNode getChild(int childIndex) {
127+
result = getChildInternal(childIndex)
128+
or
129+
// We first compute the first available child index that is not used by
130+
// `getChildInternal`, then we synthesize the child for fully converted
131+
// expressions at `nextAvailableIndex` plus the childIndex of the non-converted
132+
// expression. This ensures that both disjuncts are disjoint.
133+
exists(int nonConvertedIndex, int nextAvailableIndex, Expr expr |
134+
nextAvailableIndex = max(int idx | exists(this.getChildInternal(idx))) + 1 and
135+
childIndex - nextAvailableIndex = nonConvertedIndex and
136+
expr = getChildInternal(nonConvertedIndex).(ASTNode).getAST()
137+
|
138+
expr.getFullyConverted() instanceof Conversion and
139+
result.(ASTNode).getAST() = expr.getFullyConverted() and
140+
not expr instanceof Conversion
141+
)
142+
}
120143

121144
/**
122145
* Holds if this node should be printed in the output. By default, all nodes
@@ -154,11 +177,29 @@ class PrintASTNode extends TPrintASTNode {
154177
* default, this is just the index of the child, but subclasses can override
155178
* this.
156179
*/
157-
string getChildEdgeLabel(int childIndex) {
180+
string getChildEdgeLabelInternal(int childIndex) {
158181
exists(getChild(childIndex)) and
159182
result = childIndex.toString()
160183
}
161184

185+
/**
186+
* Gets the label for the edge from this node to the specified child,
187+
* including labels for edges to nodes that represent conversions.
188+
*/
189+
final string getChildEdgeLabel(int childIndex) {
190+
exists(getChildInternal(childIndex)) and
191+
result = getChildEdgeLabelInternal(childIndex)
192+
or
193+
not exists(getChildInternal(childIndex)) and
194+
exists(getChild(childIndex)) and
195+
exists(int nonConvertedIndex, int nextAvailableIndex |
196+
nextAvailableIndex = max(int idx | exists(this.getChildInternal(idx))) + 1 and
197+
childIndex - nextAvailableIndex = nonConvertedIndex
198+
|
199+
result = getChildEdgeLabelInternal(nonConvertedIndex) + " converted"
200+
)
201+
}
202+
162203
/**
163204
* Gets the `Function` that contains this node.
164205
*/
@@ -205,9 +246,7 @@ class ExprNode extends ASTNode {
205246

206247
ExprNode() { expr = ast }
207248

208-
override ASTNode getChild(int childIndex) {
209-
result.getAST() = expr.getChild(childIndex).getFullyConverted()
210-
}
249+
override ASTNode getChildInternal(int childIndex) { result.getAST() = expr.getChild(childIndex) }
211250

212251
override string getProperty(string key) {
213252
result = super.getProperty(key)
@@ -247,12 +286,13 @@ class ConversionNode extends ExprNode {
247286

248287
ConversionNode() { conv = expr }
249288

250-
override ASTNode getChild(int childIndex) {
289+
override ASTNode getChildInternal(int childIndex) {
251290
childIndex = 0 and
252-
result.getAST() = conv.getExpr()
291+
result.getAST() = conv.getExpr() and
292+
conv.getExpr() instanceof Conversion
253293
}
254294

255-
override string getChildEdgeLabel(int childIndex) { childIndex = 0 and result = "expr" }
295+
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "expr" }
256296
}
257297

258298
/**
@@ -280,7 +320,7 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode {
280320

281321
DeclarationEntryNode() { this = TDeclarationEntryNode(declStmt, ast) }
282322

283-
override PrintASTNode getChild(int childIndex) { none() }
323+
override PrintASTNode getChildInternal(int childIndex) { none() }
284324

285325
override string getProperty(string key) {
286326
result = BaseASTNode.super.getProperty(key)
@@ -296,12 +336,12 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode {
296336
class VariableDeclarationEntryNode extends DeclarationEntryNode {
297337
override VariableDeclarationEntry ast;
298338

299-
override ASTNode getChild(int childIndex) {
339+
override ASTNode getChildInternal(int childIndex) {
300340
childIndex = 0 and
301341
result.getAST() = ast.getVariable().getInitializer()
302342
}
303343

304-
override string getChildEdgeLabel(int childIndex) { childIndex = 0 and result = "init" }
344+
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "init" }
305345
}
306346

307347
/**
@@ -312,11 +352,11 @@ class StmtNode extends ASTNode {
312352

313353
StmtNode() { stmt = ast }
314354

315-
override BaseASTNode getChild(int childIndex) {
355+
override BaseASTNode getChildInternal(int childIndex) {
316356
exists(Locatable child |
317357
child = stmt.getChild(childIndex) and
318358
(
319-
result.getAST() = child.(Expr).getFullyConverted() or
359+
result.getAST() = child.(Expr) or
320360
result.getAST() = child.(Stmt)
321361
)
322362
)
@@ -331,7 +371,7 @@ class DeclStmtNode extends StmtNode {
331371

332372
DeclStmtNode() { declStmt = stmt }
333373

334-
override DeclarationEntryNode getChild(int childIndex) {
374+
override DeclarationEntryNode getChildInternal(int childIndex) {
335375
exists(DeclarationEntry entry |
336376
declStmt.getDeclarationEntry(childIndex) = entry and
337377
result = TDeclarationEntryNode(declStmt, entry)
@@ -347,7 +387,7 @@ class ParameterNode extends ASTNode {
347387

348388
ParameterNode() { param = ast }
349389

350-
final override PrintASTNode getChild(int childIndex) { none() }
390+
final override PrintASTNode getChildInternal(int childIndex) { none() }
351391

352392
final override string getProperty(string key) {
353393
result = super.getProperty(key)
@@ -365,12 +405,12 @@ class InitializerNode extends ASTNode {
365405

366406
InitializerNode() { init = ast }
367407

368-
override ASTNode getChild(int childIndex) {
408+
override ASTNode getChildInternal(int childIndex) {
369409
childIndex = 0 and
370-
result.getAST() = init.getExpr().getFullyConverted()
410+
result.getAST() = init.getExpr()
371411
}
372412

373-
override string getChildEdgeLabel(int childIndex) {
413+
override string getChildEdgeLabelInternal(int childIndex) {
374414
childIndex = 0 and
375415
result = "expr"
376416
}
@@ -388,7 +428,9 @@ class ParametersNode extends PrintASTNode, TParametersNode {
388428

389429
final override Location getLocation() { result = getRepresentativeLocation(func) }
390430

391-
override ASTNode getChild(int childIndex) { result.getAST() = func.getParameter(childIndex) }
431+
override ASTNode getChildInternal(int childIndex) {
432+
result.getAST() = func.getParameter(childIndex)
433+
}
392434

393435
/**
394436
* Gets the `Function` for which this node represents the parameters.
@@ -408,7 +450,7 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers
408450

409451
final override Location getLocation() { result = getRepresentativeLocation(ctor) }
410452

411-
final override ASTNode getChild(int childIndex) {
453+
final override ASTNode getChildInternal(int childIndex) {
412454
result.getAST() = ctor.getInitializer(childIndex)
413455
}
414456

@@ -430,7 +472,7 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo
430472

431473
final override Location getLocation() { result = getRepresentativeLocation(dtor) }
432474

433-
final override ASTNode getChild(int childIndex) {
475+
final override ASTNode getChildInternal(int childIndex) {
434476
result.getAST() = dtor.getDestruction(childIndex)
435477
}
436478

@@ -450,7 +492,7 @@ class FunctionNode extends ASTNode {
450492

451493
override string toString() { result = qlClass(func) + getIdentityString(func) }
452494

453-
override PrintASTNode getChild(int childIndex) {
495+
override PrintASTNode getChildInternal(int childIndex) {
454496
childIndex = 0 and
455497
result.(ParametersNode).getFunction() = func
456498
or
@@ -464,7 +506,7 @@ class FunctionNode extends ASTNode {
464506
result.(DestructorDestructionsNode).getDestructor() = func
465507
}
466508

467-
override string getChildEdgeLabel(int childIndex) {
509+
override string getChildEdgeLabelInternal(int childIndex) {
468510
childIndex = 0 and result = "params"
469511
or
470512
childIndex = 1 and result = "initializations"
@@ -504,7 +546,7 @@ class ClassAggregateLiteralNode extends ExprNode {
504546

505547
ClassAggregateLiteralNode() { list = ast }
506548

507-
override string getChildEdgeLabel(int childIndex) {
549+
override string getChildEdgeLabelInternal(int childIndex) {
508550
exists(Field field |
509551
list.getFieldExpr(field) = list.getChild(childIndex) and
510552
result = "." + field.getName()
@@ -520,7 +562,7 @@ class ArrayAggregateLiteralNode extends ExprNode {
520562

521563
ArrayAggregateLiteralNode() { list = ast }
522564

523-
override string getChildEdgeLabel(int childIndex) {
565+
override string getChildEdgeLabelInternal(int childIndex) {
524566
exists(int elementIndex |
525567
list.getElementExpr(elementIndex) = list.getChild(childIndex) and
526568
result = "[" + elementIndex.toString() + "]"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
void Conversion4(int x) {
22
x = ((int)7);
3+
}
4+
5+
char * retfn(void * v) {
6+
return (char*)(void*)(int*)v;
7+
}
8+
9+
void Conversion4_vardecl(int x) {
10+
long y = (long) x;
311
}

0 commit comments

Comments
 (0)