Skip to content

Commit ab42ddb

Browse files
committed
C++: Adjust code for the conversions PR, provide correct childIndexes for the new nodes.
1 parent 4276d1f commit ab42ddb

3 files changed

Lines changed: 971 additions & 1003 deletions

File tree

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

Lines changed: 77 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,18 @@ class PrintASTNode extends TPrintASTNode {
124124
* regular parent/child relation traversal.
125125
*/
126126
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()
127+
exists(int nonConvertedIndex, boolean isConverted |
128+
deconstructIndex(childIndex, nonConvertedIndex, isConverted)
137129
|
138-
expr.getFullyConverted() instanceof Conversion and
139-
result.(ASTNode).getAST() = expr.getFullyConverted() and
140-
not expr instanceof Conversion
130+
if isConverted = false
131+
then result = getChildInternal(childIndex)
132+
else
133+
exists(Expr expr |
134+
expr = getChildInternal(nonConvertedIndex).(ASTNode).getAST() and
135+
expr.getFullyConverted() instanceof Conversion and
136+
result.(ASTNode).getAST() = expr.getFullyConverted() and
137+
not expr instanceof Conversion
138+
)
141139
)
142140
}
143141

@@ -173,36 +171,57 @@ class PrintASTNode extends TPrintASTNode {
173171
}
174172

175173
/**
176-
* Gets the label for the edge from this node to the specified child. By
177-
* default, this is just the index of the child, but subclasses can override
178-
* this.
174+
* Gets the QL predicate that can be used to access the child at `childIndex`.
175+
* May not always return a QL predicate, see for example `FunctionNode`.
179176
*/
180-
string getChildEdgeLabelInternal(int childIndex) {
177+
final string getChildAccessorPredicate(int childIndex) {
181178
exists(getChild(childIndex)) and
182-
result = childIndex.toString()
179+
exists(int nonConvertedIndex, boolean isConverted |
180+
deconstructIndex(childIndex, nonConvertedIndex, isConverted)
181+
|
182+
if isConverted = false
183+
then result = getChildAccessorPredicateInternal(childIndex)
184+
else result = getChildAccessorPredicateInternal(nonConvertedIndex) + ".getFullyConverted()"
185+
)
183186
}
184187

185188
/**
186189
* Gets the QL predicate that can be used to access the child at `childIndex`.
187-
* May not hold for all children, see for example `FunctionNode`.
190+
* INTERNAL DO NOT USE: Does not contain accessors for the synthesized nodes for conversions.
188191
*/
189-
abstract string getChildAccessorPredicate(int childIndex);
192+
abstract string getChildAccessorPredicateInternal(int childIndex);
190193

191194
/**
192-
* Gets the label for the edge from this node to the specified child,
193-
* including labels for edges to nodes that represent conversions.
195+
* Holds either if a `childIndex` is a synthesized child coming from a conversion (`isConverted = true`)
196+
* or if the child is a regular child node.
197+
* In the former case, `nonConvertedIndex` is the index of the regular, unconverted child node.
198+
* Note: This predicate contains the mapping between the converted and nonconverted indexes, but
199+
* if `nonConvertedIndex` does not have conversions attached, there will be no node at `childIndex`.
194200
*/
195-
final string getChildEdgeLabel(int childIndex) {
201+
final predicate deconstructIndex(int childIndex, int nonConvertedIndex, boolean isConverted) {
196202
exists(getChildInternal(childIndex)) and
197-
result = getChildEdgeLabelInternal(childIndex)
203+
nonConvertedIndex = childIndex and
204+
isConverted = false
198205
or
199206
not exists(getChildInternal(childIndex)) and
200-
exists(getChild(childIndex)) and
201-
exists(int nonConvertedIndex, int nextAvailableIndex |
202-
nextAvailableIndex = max(int idx | exists(this.getChildInternal(idx))) + 1 and
203-
childIndex - nextAvailableIndex = nonConvertedIndex
207+
exists(getChildInternal(nonConvertedIndex)) and
208+
isConverted = true and
209+
// to get the desired order of the extended `childIndex`es (including the synthesized children for conversions)
210+
// we keep the indexes in the following three disjoint intervals:
211+
// [minIndex, maxIndex: original children, without conversion
212+
// [|-1| + |maxIndex|, |minIndex| + |maxIndex|]: conversion children with negative `nonConvertedIndex`
213+
// [0 + |maxIndex| + |minIndex| + 1, maxIndex + |maxIndex| + |minIndex| + 1]: for conversion children
214+
// with positive `nonConvertedIndex`
215+
exists(int minIndex, int maxIndex |
216+
minIndex = min(int n | exists(getChildInternal(n))) and
217+
maxIndex = max(int n | exists(getChildInternal(n)))
204218
|
205-
result = getChildEdgeLabelInternal(nonConvertedIndex) + " converted"
219+
if nonConvertedIndex < 0
220+
then
221+
// note that we swap the order of the negative indexes here, so that the conversion child for `-2`
222+
// comes before the conversion child for `-1`
223+
childIndex = (minIndex - 1 - nonConvertedIndex).abs() + maxIndex.abs()
224+
else childIndex = nonConvertedIndex + maxIndex.abs() + minIndex.abs() + 1
206225
)
207226
}
208227

@@ -267,8 +286,8 @@ class ExprNode extends ASTNode {
267286
result = expr.getValueCategoryString()
268287
}
269288

270-
override string getChildAccessorPredicate(int childIndex) {
271-
result = getChildAccessor(ast, getChildInternal(childIndex).getAST())
289+
override string getChildAccessorPredicateInternal(int childIndex) {
290+
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAST())
272291
}
273292

274293
/**
@@ -301,8 +320,6 @@ class ConversionNode extends ExprNode {
301320
result.getAST() = conv.getExpr() and
302321
conv.getExpr() instanceof Conversion
303322
}
304-
305-
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "expr" }
306323
}
307324

308325
/**
@@ -332,7 +349,7 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode {
332349

333350
override PrintASTNode getChildInternal(int childIndex) { none() }
334351

335-
override string getChildAccessorPredicate(int childIndex) { none() }
352+
override string getChildAccessorPredicateInternal(int childIndex) { none() }
336353

337354
override string getProperty(string key) {
338355
result = BaseASTNode.super.getProperty(key)
@@ -353,12 +370,10 @@ class VariableDeclarationEntryNode extends DeclarationEntryNode {
353370
result.getAST() = ast.getVariable().getInitializer()
354371
}
355372

356-
override string getChildAccessorPredicate(int childIndex) {
373+
override string getChildAccessorPredicateInternal(int childIndex) {
357374
childIndex = 0 and
358375
result = "getVariable().getInitializer()"
359376
}
360-
361-
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "init" }
362377
}
363378

364379
/**
@@ -379,8 +394,8 @@ class StmtNode extends ASTNode {
379394
)
380395
}
381396

382-
override string getChildAccessorPredicate(int childIndex) {
383-
result = getChildAccessor(ast, getChildInternal(childIndex).getAST())
397+
override string getChildAccessorPredicateInternal(int childIndex) {
398+
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAST())
384399
}
385400
}
386401

@@ -410,7 +425,7 @@ class ParameterNode extends ASTNode {
410425

411426
final override PrintASTNode getChildInternal(int childIndex) { none() }
412427

413-
final override string getChildAccessorPredicate(int childIndex) { none() }
428+
final override string getChildAccessorPredicateInternal(int childIndex) { none() }
414429

415430
final override string getProperty(string key) {
416431
result = super.getProperty(key)
@@ -433,15 +448,10 @@ class InitializerNode extends ASTNode {
433448
result.getAST() = init.getExpr()
434449
}
435450

436-
override string getChildAccessorPredicate(int childIndex) {
451+
override string getChildAccessorPredicateInternal(int childIndex) {
437452
childIndex = 0 and
438453
result = "getExpr()"
439454
}
440-
441-
override string getChildEdgeLabelInternal(int childIndex) {
442-
childIndex = 0 and
443-
result = "expr"
444-
}
445455
}
446456

447457
/**
@@ -460,8 +470,8 @@ class ParametersNode extends PrintASTNode, TParametersNode {
460470
result.getAST() = func.getParameter(childIndex)
461471
}
462472

463-
override string getChildAccessorPredicate(int childIndex) {
464-
exists(getChild(childIndex)) and
473+
override string getChildAccessorPredicateInternal(int childIndex) {
474+
exists(getChildInternal(childIndex)) and
465475
result = "getParameter(" + childIndex.toString() + ")"
466476
}
467477

@@ -487,8 +497,8 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers
487497
result.getAST() = ctor.getInitializer(childIndex)
488498
}
489499

490-
final override string getChildAccessorPredicate(int childIndex) {
491-
exists(getChild(childIndex)) and
500+
final override string getChildAccessorPredicateInternal(int childIndex) {
501+
exists(getChildInternal(childIndex)) and
492502
result = "getInitializer(" + childIndex.toString() + ")"
493503
}
494504

@@ -514,8 +524,8 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo
514524
result.getAST() = dtor.getDestruction(childIndex)
515525
}
516526

517-
final override string getChildAccessorPredicate(int childIndex) {
518-
exists(getChild(childIndex)) and
527+
final override string getChildAccessorPredicateInternal(int childIndex) {
528+
exists(getChildInternal(childIndex)) and
519529
result = "getDestruction(" + childIndex.toString() + ")"
520530
}
521531

@@ -549,21 +559,14 @@ class FunctionNode extends ASTNode {
549559
result.(DestructorDestructionsNode).getDestructor() = func
550560
}
551561

552-
override string getChildAccessorPredicate(int childIndex) {
553-
// all other children of this node are not reachable via the AST `getChild` relation
554-
// or other getters. Thus, this predicate does not hold for them.
555-
childIndex = 2 and
556-
result = "getEntryPoint()"
557-
}
558-
559-
override string getChildEdgeLabelInternal(int childIndex) {
560-
childIndex = 0 and result = "params"
562+
override string getChildAccessorPredicateInternal(int childIndex) {
563+
childIndex = 0 and result = "<params>"
561564
or
562-
childIndex = 1 and result = "initializations"
565+
childIndex = 1 and result = "<initializations>"
563566
or
564-
childIndex = 2 and result = "body"
567+
childIndex = 2 and result = "getEntryPoint()"
565568
or
566-
childIndex = 3 and result = "destructions"
569+
childIndex = 3 and result = "<destructions>"
567570
}
568571

569572
private int getOrder() {
@@ -588,52 +591,20 @@ class FunctionNode extends ASTNode {
588591
final Function getFunction() { result = func }
589592
}
590593

591-
/**
592-
* A node representing an `ClassAggregateLiteral`.
593-
*/
594-
class ClassAggregateLiteralNode extends ExprNode {
595-
ClassAggregateLiteral list;
596-
597-
ClassAggregateLiteralNode() { list = ast }
598-
599-
override string getChildEdgeLabelInternal(int childIndex) {
600-
exists(Field field |
601-
list.getFieldExpr(field) = list.getChild(childIndex) and
602-
result = "." + field.getName()
603-
)
604-
}
605-
}
606-
607-
/**
608-
* A node representing an `ArrayAggregateLiteral`.
609-
*/
610-
class ArrayAggregateLiteralNode extends ExprNode {
611-
ArrayAggregateLiteral list;
612-
613-
ArrayAggregateLiteralNode() { list = ast }
614-
615-
override string getChildEdgeLabelInternal(int childIndex) {
616-
exists(int elementIndex |
617-
list.getElementExpr(elementIndex) = list.getChild(childIndex) and
618-
result = "[" + elementIndex.toString() + "]"
619-
)
620-
}
621-
}
622-
623-
private string getChildAccessor(Locatable parent, Element child) {
594+
private string getChildAccessorWithoutConversions(Locatable parent, Element child) {
624595
shouldPrintFunction(getEnclosingFunction(parent)) and
625596
(
626-
exists(Stmt s | s = parent.(Stmt) |
597+
exists(Stmt s | s = parent |
627598
namedStmtChildPredicates(s, child, result)
628599
or
629-
not exists(string p | namedStmtChildPredicates(s, child, p)) and
600+
not namedStmtChildPredicates(s, child, _) and
630601
exists(int n | s.getChild(n) = child and result = "getChild(" + n + ")")
631602
)
632603
or
633-
exists(Expr expr | expr = parent.(Expr) |
604+
exists(Expr expr | expr = parent |
634605
namedExprChildPredicates(expr, child, result)
635606
or
636-
not exists(string p | namedExprChildPredicates(expr, child, p)) and
607+
not namedExprChildPredicates(expr, child, _) and
637608
exists(int n | expr.getChild(n) = child and result = "getChild(" + n + ")")
638609
)
639610
)
@@ -674,15 +645,15 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
674645
or
675646
s.(ForStmt).getStmt() = e and pred = "getStmt()"
676647
or
677-
s.(RangeBasedForStmt).getChild(0) = e and pred = "getChild(0)" // TODO: could be omitted
648+
s.(RangeBasedForStmt).getChild(0) = e and pred = "getChild(0)"
678649
or
679650
s.(RangeBasedForStmt).getBeginEndDeclaration() = e and pred = "getBeginEndDeclaration()"
680651
or
681652
s.(RangeBasedForStmt).getCondition() = e and pred = "getCondition()"
682653
or
683654
s.(RangeBasedForStmt).getUpdate() = e and pred = "getUpdate()"
684655
or
685-
s.(RangeBasedForStmt).getChild(4) = e and pred = "getChild(4)" // TODO: could be omitted
656+
s.(RangeBasedForStmt).getChild(4) = e and pred = "getChild(4)"
686657
or
687658
s.(RangeBasedForStmt).getStmt() = e and pred = "getStmt()"
688659
or
@@ -845,8 +816,8 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
845816
or
846817
expr.(SizeofExprOperator).getExprOperand() = ele and pred = "getExprOperand()"
847818
or
848-
//expr.(StmtExpr).getStmt() = ele and pred = "getStmt()" // TODO confirm via test that this is a/the child
849-
//or
819+
expr.(StmtExpr).getStmt() = ele and pred = "getStmt()"
820+
or
850821
expr.(ThrowExpr).getExpr() = ele and pred = "getExpr()"
851822
or
852823
expr.(TypeidOperator).getExpr() = ele and pred = "getExpr()"
@@ -869,12 +840,9 @@ query predicate edges(PrintASTNode source, PrintASTNode target, string key, stri
869840
target.shouldPrint() and
870841
target = source.getChild(childIndex) and
871842
(
872-
key = "semmle.label" and value = source.getChildAccessorPredicate(childIndex) //source.getChildEdgeLabel(childIndex)
843+
key = "semmle.label" and value = source.getChildAccessorPredicate(childIndex)
873844
or
874845
key = "semmle.order" and value = childIndex.toString()
875-
or
876-
key = "semmle.predicate" and
877-
value = source.getChildAccessorPredicate(childIndex)
878846
)
879847
)
880848
}

0 commit comments

Comments
 (0)