mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
Merge pull request #4562 from criemen/printast-labels
C++: Change PrintAST to provide the predicates that can be used to traverse the AST.
This commit is contained in:
@@ -124,23 +124,38 @@ class PrintASTNode extends TPrintASTNode {
|
||||
* regular parent/child relation traversal.
|
||||
*/
|
||||
final PrintASTNode getChild(int childIndex) {
|
||||
result = getChildInternal(childIndex)
|
||||
or
|
||||
// We first compute the first available child index that is not used by
|
||||
// `getChildInternal`, then we synthesize the child for fully converted
|
||||
// expressions at `nextAvailableIndex` plus the childIndex of the non-converted
|
||||
// expression. This ensures that both disjuncts are disjoint.
|
||||
exists(int nonConvertedIndex, int nextAvailableIndex, Expr expr |
|
||||
nextAvailableIndex = max(int idx | exists(this.getChildInternal(idx))) + 1 and
|
||||
childIndex - nextAvailableIndex = nonConvertedIndex and
|
||||
expr = getChildInternal(nonConvertedIndex).(ASTNode).getAST()
|
||||
|
|
||||
// The exact value of `childIndex` doesn't matter, as long as we preserve the correct order.
|
||||
result =
|
||||
rank[childIndex](PrintASTNode child, int nonConvertedIndex, boolean isConverted |
|
||||
childAndAccessorPredicate(child, _, nonConvertedIndex, isConverted)
|
||||
|
|
||||
// Unconverted children come first, then sort by original child index within each group.
|
||||
child order by isConverted, nonConvertedIndex
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node for the `.getFullyConverted()` version of the child originally at index
|
||||
* `childIndex`, if that node has any conversions.
|
||||
*/
|
||||
private PrintASTNode getConvertedChild(int childIndex) {
|
||||
exists(Expr expr |
|
||||
expr = getChildInternal(childIndex).(ASTNode).getAST() and
|
||||
expr.getFullyConverted() instanceof Conversion and
|
||||
result.(ASTNode).getAST() = expr.getFullyConverted() and
|
||||
not expr instanceof Conversion
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child access predicate for the `.getFullyConverted()` version of the child originally
|
||||
* at index `childIndex`, if that node has any conversions.
|
||||
*/
|
||||
private string getConvertedChildAccessorPredicate(int childIndex) {
|
||||
exists(getConvertedChild(childIndex)) and
|
||||
result = getChildAccessorPredicateInternal(childIndex) + ".getFullyConverted()"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node should be printed in the output. By default, all nodes
|
||||
* within a function are printed, but the query can override
|
||||
@@ -173,33 +188,46 @@ class PrintASTNode extends TPrintASTNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the label for the edge from this node to the specified child. By
|
||||
* default, this is just the index of the child, but subclasses can override
|
||||
* this.
|
||||
* Holds if there is a child node `child` for original child index `nonConvertedIndex` with
|
||||
* predicate name `childPredicate`. If the original child at that index has any conversions, there
|
||||
* will be two result tuples for this predicate: one with the original child and predicate, with
|
||||
* `isConverted = false`, and the other with the `.getFullyConverted()` version of the child and
|
||||
* predicate, with `isConverted = true`. For a child without any conversions, there will be only
|
||||
* one result tuple, with `isConverted = false`.
|
||||
*/
|
||||
string getChildEdgeLabelInternal(int childIndex) {
|
||||
exists(getChild(childIndex)) and
|
||||
result = childIndex.toString()
|
||||
private predicate childAndAccessorPredicate(
|
||||
PrintASTNode child, string childPredicate, int nonConvertedIndex, boolean isConverted
|
||||
) {
|
||||
child = getChildInternal(nonConvertedIndex) and
|
||||
childPredicate = getChildAccessorPredicateInternal(nonConvertedIndex) and
|
||||
isConverted = false
|
||||
or
|
||||
child = getConvertedChild(nonConvertedIndex) and
|
||||
childPredicate = getConvertedChildAccessorPredicate(nonConvertedIndex) and
|
||||
isConverted = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the label for the edge from this node to the specified child,
|
||||
* including labels for edges to nodes that represent conversions.
|
||||
* Gets the QL predicate that can be used to access the child at `childIndex`.
|
||||
* May not always return a QL predicate, see for example `FunctionNode`.
|
||||
*/
|
||||
final string getChildEdgeLabel(int childIndex) {
|
||||
exists(getChildInternal(childIndex)) and
|
||||
result = getChildEdgeLabelInternal(childIndex)
|
||||
or
|
||||
not exists(getChildInternal(childIndex)) and
|
||||
exists(getChild(childIndex)) and
|
||||
exists(int nonConvertedIndex, int nextAvailableIndex |
|
||||
nextAvailableIndex = max(int idx | exists(this.getChildInternal(idx))) + 1 and
|
||||
childIndex - nextAvailableIndex = nonConvertedIndex
|
||||
|
|
||||
result = getChildEdgeLabelInternal(nonConvertedIndex) + " converted"
|
||||
)
|
||||
final string getChildAccessorPredicate(int childIndex) {
|
||||
// The exact value of `childIndex` doesn't matter, as long as we preserve the correct order.
|
||||
result =
|
||||
rank[childIndex](string childPredicate, int nonConvertedIndex, boolean isConverted |
|
||||
childAndAccessorPredicate(_, childPredicate, nonConvertedIndex, isConverted)
|
||||
|
|
||||
// Unconverted children come first, then sort by original child index within each group.
|
||||
childPredicate order by isConverted, nonConvertedIndex
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the QL predicate that can be used to access the child at `childIndex`.
|
||||
* INTERNAL DO NOT USE: Does not contain accessors for the synthesized nodes for conversions.
|
||||
*/
|
||||
abstract string getChildAccessorPredicateInternal(int childIndex);
|
||||
|
||||
/**
|
||||
* Gets the `Function` that contains this node.
|
||||
*/
|
||||
@@ -261,6 +289,10 @@ class ExprNode extends ASTNode {
|
||||
result = expr.getValueCategoryString()
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAST())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this expression, if it is a constant.
|
||||
*/
|
||||
@@ -291,8 +323,6 @@ class ConversionNode extends ExprNode {
|
||||
result.getAST() = conv.getExpr() and
|
||||
conv.getExpr() instanceof Conversion
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "expr" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,6 +352,8 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode {
|
||||
|
||||
override PrintASTNode getChildInternal(int childIndex) { none() }
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) { none() }
|
||||
|
||||
override string getProperty(string key) {
|
||||
result = BaseASTNode.super.getProperty(key)
|
||||
or
|
||||
@@ -341,7 +373,10 @@ class VariableDeclarationEntryNode extends DeclarationEntryNode {
|
||||
result.getAST() = ast.getVariable().getInitializer()
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "init" }
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result = "getVariable().getInitializer()"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,6 +396,10 @@ class StmtNode extends ASTNode {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAST())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,6 +428,8 @@ class ParameterNode extends ASTNode {
|
||||
|
||||
final override PrintASTNode getChildInternal(int childIndex) { none() }
|
||||
|
||||
final override string getChildAccessorPredicateInternal(int childIndex) { none() }
|
||||
|
||||
final override string getProperty(string key) {
|
||||
result = super.getProperty(key)
|
||||
or
|
||||
@@ -410,9 +451,9 @@ class InitializerNode extends ASTNode {
|
||||
result.getAST() = init.getExpr()
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) {
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result = "expr"
|
||||
result = "getExpr()"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,6 +473,11 @@ class ParametersNode extends PrintASTNode, TParametersNode {
|
||||
result.getAST() = func.getParameter(childIndex)
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
exists(getChildInternal(childIndex)) and
|
||||
result = "getParameter(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Function` for which this node represents the parameters.
|
||||
*/
|
||||
@@ -454,6 +500,11 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers
|
||||
result.getAST() = ctor.getInitializer(childIndex)
|
||||
}
|
||||
|
||||
final override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
exists(getChildInternal(childIndex)) and
|
||||
result = "getInitializer(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Constructor` for which this node represents the initializer list.
|
||||
*/
|
||||
@@ -476,6 +527,11 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo
|
||||
result.getAST() = dtor.getDestruction(childIndex)
|
||||
}
|
||||
|
||||
final override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
exists(getChildInternal(childIndex)) and
|
||||
result = "getDestruction(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Destructor` for which this node represents the destruction list.
|
||||
*/
|
||||
@@ -506,14 +562,14 @@ class FunctionNode extends ASTNode {
|
||||
result.(DestructorDestructionsNode).getDestructor() = func
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) {
|
||||
childIndex = 0 and result = "params"
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
childIndex = 0 and result = "<params>"
|
||||
or
|
||||
childIndex = 1 and result = "initializations"
|
||||
childIndex = 1 and result = "<initializations>"
|
||||
or
|
||||
childIndex = 2 and result = "body"
|
||||
childIndex = 2 and result = "getEntryPoint()"
|
||||
or
|
||||
childIndex = 3 and result = "destructions"
|
||||
childIndex = 3 and result = "<destructions>"
|
||||
}
|
||||
|
||||
private int getOrder() {
|
||||
@@ -538,36 +594,237 @@ class FunctionNode extends ASTNode {
|
||||
final Function getFunction() { result = func }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing an `ClassAggregateLiteral`.
|
||||
*/
|
||||
class ClassAggregateLiteralNode extends ExprNode {
|
||||
ClassAggregateLiteral list;
|
||||
|
||||
ClassAggregateLiteralNode() { list = ast }
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) {
|
||||
exists(Field field |
|
||||
list.getFieldExpr(field) = list.getChild(childIndex) and
|
||||
result = "." + field.getName()
|
||||
private string getChildAccessorWithoutConversions(Locatable parent, Element child) {
|
||||
shouldPrintFunction(getEnclosingFunction(parent)) and
|
||||
(
|
||||
exists(Stmt s | s = parent |
|
||||
namedStmtChildPredicates(s, child, result)
|
||||
or
|
||||
not namedStmtChildPredicates(s, child, _) and
|
||||
exists(int n | s.getChild(n) = child and result = "getChild(" + n + ")")
|
||||
)
|
||||
}
|
||||
or
|
||||
exists(Expr expr | expr = parent |
|
||||
namedExprChildPredicates(expr, child, result)
|
||||
or
|
||||
not namedExprChildPredicates(expr, child, _) and
|
||||
exists(int n | expr.getChild(n) = child and result = "getChild(" + n + ")")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing an `ArrayAggregateLiteral`.
|
||||
*/
|
||||
class ArrayAggregateLiteralNode extends ExprNode {
|
||||
ArrayAggregateLiteral list;
|
||||
|
||||
ArrayAggregateLiteralNode() { list = ast }
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) {
|
||||
exists(int elementIndex |
|
||||
list.getElementExpr(elementIndex) = list.getChild(childIndex) and
|
||||
result = "[" + elementIndex.toString() + "]"
|
||||
private predicate namedStmtChildPredicates(Locatable s, Element e, string pred) {
|
||||
shouldPrintFunction(getEnclosingFunction(s)) and
|
||||
(
|
||||
exists(int n | s.(BlockStmt).getStmt(n) = e and pred = "getStmt(" + n + ")")
|
||||
or
|
||||
s.(ComputedGotoStmt).getExpr() = e and pred = "getExpr()"
|
||||
or
|
||||
s.(ConstexprIfStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(ConstexprIfStmt).getThen() = e and pred = "getThen()"
|
||||
or
|
||||
s.(ConstexprIfStmt).getElse() = e and pred = "getElse()"
|
||||
or
|
||||
s.(IfStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(IfStmt).getThen() = e and pred = "getThen()"
|
||||
or
|
||||
s.(IfStmt).getElse() = e and pred = "getElse()"
|
||||
or
|
||||
s.(SwitchStmt).getExpr() = e and pred = "getExpr()"
|
||||
or
|
||||
s.(SwitchStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
s.(DoStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(DoStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
s.(ForStmt).getInitialization() = e and pred = "getInitialization()"
|
||||
or
|
||||
s.(ForStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(ForStmt).getUpdate() = e and pred = "getUpdate()"
|
||||
or
|
||||
s.(ForStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
s.(RangeBasedForStmt).getChild(0) = e and pred = "getChild(0)"
|
||||
or
|
||||
s.(RangeBasedForStmt).getBeginEndDeclaration() = e and pred = "getBeginEndDeclaration()"
|
||||
or
|
||||
s.(RangeBasedForStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(RangeBasedForStmt).getUpdate() = e and pred = "getUpdate()"
|
||||
or
|
||||
s.(RangeBasedForStmt).getChild(4) = e and pred = "getChild(4)"
|
||||
or
|
||||
s.(RangeBasedForStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
s.(WhileStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(WhileStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
exists(int n |
|
||||
s.(DeclStmt).getDeclarationEntry(n) = e and pred = "getDeclarationEntry(" + n.toString() + ")"
|
||||
)
|
||||
}
|
||||
or
|
||||
// EmptyStmt does not have children
|
||||
s.(ExprStmt).getExpr() = e and pred = "getExpr()"
|
||||
or
|
||||
s.(Handler).getBlock() = e and pred = "getBlock()"
|
||||
or
|
||||
s.(JumpStmt).getTarget() = e and pred = "getTarget()"
|
||||
or
|
||||
s.(MicrosoftTryStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
s.(MicrosoftTryExceptStmt).getCondition() = e and pred = "getCondition()"
|
||||
or
|
||||
s.(MicrosoftTryExceptStmt).getExcept() = e and pred = "getExcept()"
|
||||
or
|
||||
s.(MicrosoftTryFinallyStmt).getFinally() = e and pred = "getFinally()"
|
||||
or
|
||||
s.(ReturnStmt).getExpr() = e and pred = "getExpr()"
|
||||
or
|
||||
s.(SwitchCase).getExpr() = e and pred = "getExpr()"
|
||||
or
|
||||
s.(SwitchCase).getEndExpr() = e and pred = "getEndExpr()"
|
||||
or
|
||||
s.(TryStmt).getStmt() = e and pred = "getStmt()"
|
||||
or
|
||||
s.(VlaDimensionStmt).getDimensionExpr() = e and pred = "getDimensionExpr()"
|
||||
)
|
||||
}
|
||||
|
||||
private predicate namedExprChildPredicates(Expr expr, Element ele, string pred) {
|
||||
shouldPrintFunction(expr.getEnclosingFunction()) and
|
||||
(
|
||||
expr.(Access).getTarget() = ele and pred = "getTarget()"
|
||||
or
|
||||
expr.(VariableAccess).getQualifier() = ele and pred = "getQualifier()"
|
||||
or
|
||||
exists(Field f |
|
||||
expr.(ClassAggregateLiteral).getFieldExpr(f) = ele and
|
||||
pred = "getFieldExpr(" + f.toString() + ")"
|
||||
)
|
||||
or
|
||||
exists(int n |
|
||||
expr.(ArrayOrVectorAggregateLiteral).getElementExpr(n) = ele and
|
||||
pred = "getElementExpr(" + n.toString() + ")"
|
||||
)
|
||||
or
|
||||
expr.(AlignofExprOperator).getExprOperand() = ele and pred = "getExprOperand()"
|
||||
or
|
||||
expr.(ArrayExpr).getArrayBase() = ele and pred = "getArrayBase()"
|
||||
or
|
||||
expr.(ArrayExpr).getArrayOffset() = ele and pred = "getArrayOffset()"
|
||||
or
|
||||
expr.(AssumeExpr).getOperand() = ele and pred = "getOperand()"
|
||||
or
|
||||
expr.(BuiltInComplexOperation).getRealOperand() = ele and pred = "getRealOperand()"
|
||||
or
|
||||
expr.(BuiltInComplexOperation).getImaginaryOperand() = ele and pred = "getImaginaryOperand()"
|
||||
or
|
||||
expr.(BuiltInVarArg).getVAList() = ele and pred = "getVAList()"
|
||||
or
|
||||
expr.(BuiltInVarArgCopy).getDestinationVAList() = ele and pred = "getDestinationVAList()"
|
||||
or
|
||||
expr.(BuiltInVarArgCopy).getSourceVAList() = ele and pred = "getSourceVAList()"
|
||||
or
|
||||
expr.(BuiltInVarArgsEnd).getVAList() = ele and pred = "getVAList()"
|
||||
or
|
||||
expr.(BuiltInVarArgsStart).getVAList() = ele and pred = "getVAList()"
|
||||
or
|
||||
expr.(BuiltInVarArgsStart).getLastNamedParameter() = ele and pred = "getLastNamedParameter()"
|
||||
or
|
||||
expr.(Call).getQualifier() = ele and pred = "getQualifier()"
|
||||
or
|
||||
exists(int n | expr.(Call).getArgument(n) = ele and pred = "getArgument(" + n.toString() + ")")
|
||||
or
|
||||
expr.(ExprCall).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(OverloadedArrayExpr).getArrayBase() = ele and pred = "getArrayBase()"
|
||||
or
|
||||
expr.(OverloadedArrayExpr).getArrayOffset() = ele and pred = "getArrayOffset()"
|
||||
or
|
||||
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(CommaExpr).getLeftOperand() = ele and pred = "getLeftOperand()"
|
||||
or
|
||||
expr.(CommaExpr).getRightOperand() = ele and pred = "getRightOperand()"
|
||||
or
|
||||
expr.(ConditionDeclExpr).getVariableAccess() = ele and pred = "getVariableAccess()"
|
||||
or
|
||||
expr.(ConstructorFieldInit).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(Conversion).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(DeleteArrayExpr).getAllocatorCall() = ele and pred = "getAllocatorCall()"
|
||||
or
|
||||
expr.(DeleteArrayExpr).getDestructorCall() = ele and pred = "getDestructorCall()"
|
||||
or
|
||||
expr.(DeleteArrayExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(DeleteExpr).getAllocatorCall() = ele and pred = "getAllocatorCall()"
|
||||
or
|
||||
expr.(DeleteExpr).getDestructorCall() = ele and pred = "getDestructorCall()"
|
||||
or
|
||||
expr.(DeleteExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(DestructorFieldDestruction).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(FoldExpr).getInitExpr() = ele and pred = "getInitExpr()"
|
||||
or
|
||||
expr.(FoldExpr).getPackExpr() = ele and pred = "getPackExpr()"
|
||||
or
|
||||
expr.(LambdaExpression).getInitializer() = ele and pred = "getInitializer()"
|
||||
or
|
||||
expr.(NewOrNewArrayExpr).getAllocatorCall() = ele and pred = "getAllocatorCall()"
|
||||
or
|
||||
expr.(NewOrNewArrayExpr).getAlignmentArgument() = ele and pred = "getAlignmentArgument()"
|
||||
or
|
||||
expr.(NewArrayExpr).getInitializer() = ele and pred = "getInitializer()"
|
||||
or
|
||||
expr.(NewArrayExpr).getExtent() = ele and pred = "getExtent()"
|
||||
or
|
||||
expr.(NewExpr).getInitializer() = ele and pred = "getInitializer()"
|
||||
or
|
||||
expr.(NoExceptExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(Assignment).getLValue() = ele and pred = "getLValue()"
|
||||
or
|
||||
expr.(Assignment).getRValue() = ele and pred = "getRValue()"
|
||||
or
|
||||
not expr instanceof RelationalOperation and
|
||||
expr.(BinaryOperation).getLeftOperand() = ele and
|
||||
pred = "getLeftOperand()"
|
||||
or
|
||||
not expr instanceof RelationalOperation and
|
||||
expr.(BinaryOperation).getRightOperand() = ele and
|
||||
pred = "getRightOperand()"
|
||||
or
|
||||
expr.(RelationalOperation).getGreaterOperand() = ele and pred = "getGreaterOperand()"
|
||||
or
|
||||
expr.(RelationalOperation).getLesserOperand() = ele and pred = "getLesserOperand()"
|
||||
or
|
||||
expr.(ConditionalExpr).getCondition() = ele and pred = "getCondition()"
|
||||
or
|
||||
// If ConditionalExpr is in two-operand form, getThen() = getCondition() holds
|
||||
not expr.(ConditionalExpr).isTwoOperand() and
|
||||
expr.(ConditionalExpr).getThen() = ele and
|
||||
pred = "getThen()"
|
||||
or
|
||||
expr.(ConditionalExpr).getElse() = ele and pred = "getElse()"
|
||||
or
|
||||
expr.(UnaryOperation).getOperand() = ele and pred = "getOperand()"
|
||||
or
|
||||
expr.(SizeofExprOperator).getExprOperand() = ele and pred = "getExprOperand()"
|
||||
or
|
||||
expr.(StmtExpr).getStmt() = ele and pred = "getStmt()"
|
||||
or
|
||||
expr.(ThrowExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(TypeidOperator).getExpr() = ele and pred = "getExpr()"
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
|
||||
@@ -586,7 +843,7 @@ query predicate edges(PrintASTNode source, PrintASTNode target, string key, stri
|
||||
target.shouldPrint() and
|
||||
target = source.getChild(childIndex) and
|
||||
(
|
||||
key = "semmle.label" and value = source.getChildEdgeLabel(childIndex)
|
||||
key = "semmle.label" and value = source.getChildAccessorPredicate(childIndex)
|
||||
or
|
||||
key = "semmle.order" and value = childIndex.toString()
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user