C++: Provide the predicates that can be used to traverse the AST as metadata.

This commit is contained in:
Cornelius Riemenschneider
2020-10-28 11:51:51 +01:00
parent fa344d216f
commit 8c925a20a7
3 changed files with 5494 additions and 5205 deletions

View File

@@ -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