Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3a48857

Browse files
committed
C++: Rewrite the PartialDefinitionNode classes to match the new StoreNodes.
1 parent 8bef795 commit 3a48857

4 files changed

Lines changed: 533 additions & 491 deletions

File tree

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 16 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ abstract class PostUpdateNode extends Node {
498498
* value, but does not necessarily replace it entirely. For example:
499499
* ```
500500
* x.y = 1; // a partial definition of the object `x`.
501-
* x.y.z = 1; // a partial definition of the object `x.y`.
501+
* x.y.z = 1; // a partial definition of the object `x.y` and `x`.
502502
* x.setY(1); // a partial definition of the object `x`.
503503
* setY(&x); // a partial definition of the object `x`.
504504
* ```
@@ -507,135 +507,34 @@ abstract private class PartialDefinitionNode extends PostUpdateNode {
507507
abstract Expr getDefinedExpr();
508508
}
509509

510-
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
511-
override ChiInstruction instr;
512-
StoreInstruction store;
513-
514-
ExplicitFieldStoreQualifierNode() {
515-
not instr.isResultConflated() and
516-
instr.getPartial() = store and
517-
(
518-
instr.getUpdatedInterval(_, _) or
519-
store.getDestinationAddress() instanceof FieldAddressInstruction
520-
)
521-
}
522-
523-
// By using an operand as the result of this predicate we avoid the dataflow inconsistency errors
524-
// caused by having multiple nodes sharing the same pre update node. This inconsistency error can cause
525-
// a tuple explosion in the big step dataflow relation since it can make many nodes be the entry node
526-
// into a big step.
527-
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
528-
529-
override Expr getDefinedExpr() {
530-
result =
531-
store
532-
.getDestinationAddress()
533-
.(FieldAddressInstruction)
534-
.getObjectAddress()
535-
.getUnconvertedResultExpression()
536-
}
537-
}
538-
539-
/**
540-
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
541-
* For instance, an update to a field of a struct containing only one field. Even if the store does
542-
* have a chi instruction, a subsequent use of the result of the store may be linked directly to the
543-
* result of the store as an inexact definition if the store totally overlaps the use. For these
544-
* cases we attach the PostUpdateNode to the store instruction. There's no obvious pre update node
545-
* for this case (as the entire memory is updated), so `getPreUpdateNode` is implemented as
546-
* `none()`.
547-
*/
548-
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
549-
override StoreInstruction instr;
550-
551-
ExplicitSingleFieldStoreQualifierNode() {
552-
(
553-
instr.getAUse().isDefinitionInexact()
554-
or
555-
not exists(ChiInstruction chi | chi.getPartial() = instr)
556-
) and
557-
// Without this condition any store would create a `PostUpdateNode`.
558-
instr.getDestinationAddress() instanceof FieldAddressInstruction
510+
private class FieldPartialDefinitionNode extends PartialDefinitionNode, StoreNodeInstr {
511+
FieldPartialDefinitionNode() {
512+
this.getInstruction() = any(FieldAddressInstruction fai).getObjectAddress()
559513
}
560514

561-
override Node getPreUpdateNode() { none() }
515+
override Node getPreUpdateNode() { result.asInstruction() = this.getInstruction() }
562516

563-
override Expr getDefinedExpr() {
564-
result =
565-
instr
566-
.getDestinationAddress()
567-
.(FieldAddressInstruction)
568-
.getObjectAddress()
569-
.getUnconvertedResultExpression()
570-
}
571-
}
517+
override Expr getDefinedExpr() { result = this.getInstruction().getUnconvertedResultExpression() }
572518

573-
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
574-
result = instr or
575-
result = instr.(CopyValueInstruction).getUnary()
519+
override string toString() { result = PartialDefinitionNode.super.toString() }
576520
}
577521

578-
/**
579-
* The target of a `fieldStoreStepAfterArraySuppression` store step, which is used to convert
580-
* an `ArrayContent` to a `FieldContent` when the `WriteSideEffect` instruction stores
581-
* into a field. See the QLDoc for `suppressArrayRead` for an example of where such a conversion
582-
* is inserted.
583-
*/
584-
private class WriteSideEffectFieldStoreQualifierNode extends PartialDefinitionNode {
585-
override ChiInstruction instr;
586-
WriteSideEffectInstruction write;
587-
FieldAddressInstruction field;
588-
589-
WriteSideEffectFieldStoreQualifierNode() {
590-
not instr.isResultConflated() and
591-
instr.getPartial() = write and
592-
field = getFieldInstruction(write.getDestinationAddress())
593-
}
522+
private class NonPartialDefinitionPostUpdate extends PostUpdateNode, StoreNodeInstr {
523+
NonPartialDefinitionPostUpdate() { not this instanceof PartialDefinitionNode }
594524

595-
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
525+
override Node getPreUpdateNode() { result.asInstruction() = this.getInstruction() }
596526

597-
override Expr getDefinedExpr() {
598-
result = field.getObjectAddress().getUnconvertedResultExpression()
599-
}
527+
override string toString() { result = PostUpdateNode.super.toString() }
600528
}
601529

602-
/**
603-
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
604-
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
605-
*/
606-
private class ArrayStoreNode extends PartialDefinitionNode {
607-
override ChiInstruction instr;
608-
PointerAddInstruction add;
609-
610-
ArrayStoreNode() {
611-
not instr.isResultConflated() and
612-
exists(StoreInstruction store |
613-
instr.getPartial() = store and
614-
add = store.getDestinationAddress()
615-
)
616-
}
617-
618-
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
619-
620-
override Expr getDefinedExpr() { result = add.getLeft().getUnconvertedResultExpression() }
621-
}
530+
private class ArgumentPostUpdateNode extends PartialDefinitionNode, StoreNodeOperand {
531+
override ArgumentNode getPreUpdateNode() { result.asOperand() = operand }
622532

623-
/**
624-
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
625-
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
626-
*/
627-
private class PointerStoreNode extends PostUpdateNode {
628-
override ChiInstruction instr;
629-
630-
PointerStoreNode() {
631-
not instr.isResultConflated() and
632-
exists(StoreInstruction store |
633-
instr.getPartial() = store and
634-
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
635-
)
533+
override Expr getDefinedExpr() {
534+
result = this.getOperand().getDef().getUnconvertedResultExpression()
636535
}
637536

638-
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
537+
override string toString() { result = PartialDefinitionNode.super.toString() }
639538
}
640539

641540
/**

0 commit comments

Comments
 (0)