mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
C++: Provide the predicates that can be used to traverse the AST as metadata.
This commit is contained in:
@@ -182,6 +182,8 @@ class PrintASTNode extends TPrintASTNode {
|
||||
result = childIndex.toString()
|
||||
}
|
||||
|
||||
abstract string getChildAccessorPredicate(int childIndex);
|
||||
|
||||
/**
|
||||
* Gets the label for the edge from this node to the specified child,
|
||||
* including labels for edges to nodes that represent conversions.
|
||||
@@ -261,6 +263,10 @@ class ExprNode extends ASTNode {
|
||||
result = expr.getValueCategoryString()
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) {
|
||||
result = getChildAccessor(ast, getChildInternal(childIndex).getAST())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of this expression, if it is a constant.
|
||||
*/
|
||||
@@ -322,6 +328,8 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode {
|
||||
|
||||
override PrintASTNode getChildInternal(int childIndex) { none() }
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) { none() }
|
||||
|
||||
override string getProperty(string key) {
|
||||
result = BaseASTNode.super.getProperty(key)
|
||||
or
|
||||
@@ -341,6 +349,11 @@ class VariableDeclarationEntryNode extends DeclarationEntryNode {
|
||||
result.getAST() = ast.getVariable().getInitializer()
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result = "getVariable().getInitializer()"
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) { childIndex = 0 and result = "init" }
|
||||
}
|
||||
|
||||
@@ -361,6 +374,10 @@ class StmtNode extends ASTNode {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) {
|
||||
result = getChildAccessor(ast, getChildInternal(childIndex).getAST())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,6 +406,8 @@ class ParameterNode extends ASTNode {
|
||||
|
||||
final override PrintASTNode getChildInternal(int childIndex) { none() }
|
||||
|
||||
final override string getChildAccessorPredicate(int childIndex) { none() }
|
||||
|
||||
final override string getProperty(string key) {
|
||||
result = super.getProperty(key)
|
||||
or
|
||||
@@ -410,6 +429,11 @@ class InitializerNode extends ASTNode {
|
||||
result.getAST() = init.getExpr()
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result = "getExpr()"
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result = "expr"
|
||||
@@ -432,6 +456,11 @@ class ParametersNode extends PrintASTNode, TParametersNode {
|
||||
result.getAST() = func.getParameter(childIndex)
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) {
|
||||
exists(getChild(childIndex)) and
|
||||
result = "getParameter(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Function` for which this node represents the parameters.
|
||||
*/
|
||||
@@ -454,6 +483,11 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers
|
||||
result.getAST() = ctor.getInitializer(childIndex)
|
||||
}
|
||||
|
||||
final override string getChildAccessorPredicate(int childIndex) {
|
||||
exists(getChild(childIndex)) and
|
||||
result = "getInitializer(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Constructor` for which this node represents the initializer list.
|
||||
*/
|
||||
@@ -476,6 +510,11 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo
|
||||
result.getAST() = dtor.getDestruction(childIndex)
|
||||
}
|
||||
|
||||
final override string getChildAccessorPredicate(int childIndex) {
|
||||
exists(getChild(childIndex)) and
|
||||
result = "getDestruction(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `Destructor` for which this node represents the destruction list.
|
||||
*/
|
||||
@@ -506,6 +545,20 @@ class FunctionNode extends ASTNode {
|
||||
result.(DestructorDestructionsNode).getDestructor() = func
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicate(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result = "..."
|
||||
or
|
||||
childIndex = 1 and
|
||||
result = "..."
|
||||
or
|
||||
childIndex = 2 and
|
||||
result = "getEntryPoint()"
|
||||
or
|
||||
childIndex = 3 and
|
||||
result = "..."
|
||||
}
|
||||
|
||||
override string getChildEdgeLabelInternal(int childIndex) {
|
||||
childIndex = 0 and result = "params"
|
||||
or
|
||||
@@ -570,6 +623,239 @@ class ArrayAggregateLiteralNode extends ExprNode {
|
||||
}
|
||||
}
|
||||
|
||||
string getChildAccessor(Locatable parent, Element child) {
|
||||
shouldPrintFunction(getEnclosingFunction(parent)) and
|
||||
(
|
||||
exists(Stmt s | s = parent.(Stmt) |
|
||||
namedStmtChildPredicates(s, child, result)
|
||||
or
|
||||
not exists(string p | namedStmtChildPredicates(s, child, p)) and
|
||||
exists(int n | s.getChild(n) = child and result = "getChild(" + n + ")")
|
||||
)
|
||||
or
|
||||
exists(Expr expr | expr = parent.(Expr) |
|
||||
namedExprChildPredicates(expr, child, result)
|
||||
or
|
||||
not exists(string p | namedExprChildPredicates(expr, child, p)) and
|
||||
exists(int n | expr.getChild(n) = child and result = "getChild(" + n + ")")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
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)" // TODO: could be omitted
|
||||
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)" // TODO: could be omitted
|
||||
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()"
|
||||
)
|
||||
}
|
||||
|
||||
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()" // TODO confirm via test that this is a/the child
|
||||
//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`. */
|
||||
query predicate nodes(PrintASTNode node, string key, string value) {
|
||||
node.shouldPrint() and
|
||||
@@ -586,9 +872,12 @@ 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) //source.getChildEdgeLabel(childIndex)
|
||||
or
|
||||
key = "semmle.order" and value = childIndex.toString()
|
||||
or
|
||||
key = "semmle.predicate" and
|
||||
value = source.getChildAccessorPredicate(childIndex)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
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