mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Merge pull request #1744 from jbj/ast-field-flow-aggregate-init
C++: Field flow through ClassAggregateLiteral
This commit is contained in:
@@ -6,7 +6,7 @@ private import DataFlowDispatch
|
||||
private Node getInstanceArgument(Call call) {
|
||||
result.asExpr() = call.getQualifier()
|
||||
or
|
||||
result.(PreConstructorCallNode).getConstructorCall() = call
|
||||
result.(PreObjectInitializerNode).getExpr().(ConstructorCall) = call
|
||||
// This does not include the implicit `this` argument on auto-generated
|
||||
// base class destructor calls as those do not have an AST element.
|
||||
}
|
||||
@@ -169,6 +169,14 @@ private class ArrayContent extends Content, TArrayContent {
|
||||
* value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
|
||||
exists(ClassAggregateLiteral aggr, Field field |
|
||||
// The following line requires `node2` to be both an `ExprNode` and a
|
||||
// `PostUpdateNode`, which means it must be an `ObjectInitializerNode`.
|
||||
node2.asExpr() = aggr and
|
||||
f.(FieldContent).getField() = field and
|
||||
aggr.getFieldExpr(field) = node1.asExpr()
|
||||
)
|
||||
or
|
||||
exists(FieldAccess fa |
|
||||
exists(Assignment a |
|
||||
node1.asExpr() = a and
|
||||
|
||||
@@ -10,7 +10,11 @@ cached
|
||||
private newtype TNode =
|
||||
TExprNode(Expr e) or
|
||||
TPartialDefinitionNode(PartialDefinition pd) or
|
||||
TPreConstructorCallNode(ConstructorCall call) or
|
||||
TPreObjectInitializerNode(Expr e) {
|
||||
e instanceof ConstructorCall
|
||||
or
|
||||
e instanceof ClassAggregateLiteral
|
||||
} or
|
||||
TExplicitParameterNode(Parameter p) { exists(p.getFunction().getBlock()) } or
|
||||
TInstanceParameterNode(MemberFunction f) { exists(f.getBlock()) and not f.isStatic() } or
|
||||
TUninitializedNode(LocalVariable v) { not v.hasInitializer() }
|
||||
@@ -256,16 +260,24 @@ class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing the object that was just constructed and is identified
|
||||
* with the "return value" of the constructor call.
|
||||
* A node representing the temporary value of an object that was just
|
||||
* constructed by a constructor call or an aggregate initializer. This is only
|
||||
* for objects, not for pointers to objects.
|
||||
*
|
||||
* These expressions are their own post-update nodes but instead have synthetic
|
||||
* pre-update nodes.
|
||||
*/
|
||||
private class PostConstructorCallNode extends PostUpdateNode, TExprNode {
|
||||
PostConstructorCallNode() { this = TExprNode(any(ConstructorCall c)) }
|
||||
private class ObjectInitializerNode extends PostUpdateNode, TExprNode {
|
||||
PreObjectInitializerNode pre;
|
||||
|
||||
override PreConstructorCallNode getPreUpdateNode() {
|
||||
TExprNode(result.getConstructorCall()) = this
|
||||
ObjectInitializerNode() {
|
||||
// If a `Node` is associated with a `PreObjectInitializerNode`, then it's
|
||||
// an `ObjectInitializerNode`.
|
||||
pre.getExpr() = this.asExpr()
|
||||
}
|
||||
|
||||
override PreObjectInitializerNode getPreUpdateNode() { result = pre }
|
||||
|
||||
// No override of `toString` since these nodes already have a `toString` from
|
||||
// their overlap with `ExprNode`.
|
||||
}
|
||||
@@ -273,19 +285,19 @@ private class PostConstructorCallNode extends PostUpdateNode, TExprNode {
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A synthetic data-flow node that plays the role of the qualifier (or
|
||||
* `this`-argument) to a constructor call.
|
||||
* A synthetic data-flow node that plays the role of a temporary object that
|
||||
* has not yet been initialized.
|
||||
*/
|
||||
class PreConstructorCallNode extends Node, TPreConstructorCallNode {
|
||||
ConstructorCall getConstructorCall() { this = TPreConstructorCallNode(result) }
|
||||
class PreObjectInitializerNode extends Node, TPreObjectInitializerNode {
|
||||
Expr getExpr() { this = TPreObjectInitializerNode(result) }
|
||||
|
||||
override Function getFunction() { result = getConstructorCall().getEnclosingFunction() }
|
||||
override Function getFunction() { result = getExpr().getEnclosingFunction() }
|
||||
|
||||
override Type getType() { result = getConstructorCall().getType() }
|
||||
override Type getType() { result = getExpr().getType() }
|
||||
|
||||
override Location getLocation() { result = getConstructorCall().getLocation() }
|
||||
override Location getLocation() { result = getExpr().getLocation() }
|
||||
|
||||
override string toString() { result = getConstructorCall().toString() + " [pre constructor call]" }
|
||||
override string toString() { result = getExpr().toString() + " [pre init]" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user