Make ImplicitFieldReadInstruction include implicit deref when needed

When an ImplicitFieldReadInstruction reads an embedded field which has
a pointer type, it now includes the implicit dereference.

It might be better to extend MkImplicitDeref to cover this case, so we have
an explicit instruction for this. Then it would be easier to see when
dereferences are happening, and hence when they might cause a nil pointer
dereference.
This commit is contained in:
Owen Mansel-Chan
2021-03-05 13:51:54 +00:00
parent 2d3caf48c1
commit 13cd19ee40
2 changed files with 29 additions and 8 deletions

View File

@@ -302,8 +302,11 @@ newtype TControlFlowNode =
)
} or
/**
* A control-flow node that represents the implicit selection of a field when accessing a
* promoted field.
* A control-flow node that represents the implicit selection of a field when
* accessing a promoted field.
*
* If that field has a pointer type then this control-flow node also
* represents an implicit dereference of it.
*/
MkImplicitFieldSelection(SelectorExpr e, int i, Field implicitField) {
exists(Type baseType, StructType baseStructType, Field eField, int minDepth |
@@ -313,8 +316,12 @@ newtype TControlFlowNode =
baseStructType.getFieldAtDepth(_, minDepth) = eField
|
baseStructType.getFieldAtDepth(_, i) = implicitField and
implicitField.getType().getUnderlyingType().(StructType).getFieldAtDepth(_, minDepth - i - 1) =
eField
exists(Type implicitFieldType, StructType implicitFieldStructType |
implicitFieldType = implicitField.getType().getUnderlyingType() and
implicitFieldStructType =
[implicitFieldType, implicitFieldType.(PointerType).getBaseType().getUnderlyingType()] and
implicitFieldStructType.getFieldAtDepth(_, minDepth - i - 1) = eField
)
)
} or
/**

View File

@@ -277,9 +277,15 @@ module IR {
not exists(MkImplicitDeref(se.getBase())) and
result = evalExprInstruction(se.getBase())
else
exists(ImplicitFieldReadInstruction ifri |
exists(
ImplicitFieldReadInstruction ifri, Type implicitFieldType,
StructType implicitFieldStructType
|
ifri.getSelectorExpr() = se and
ifri.getField().getType().getUnderlyingType().(StructType).getOwnField(_, _) = field
implicitFieldType = ifri.getField().getType().getUnderlyingType() and
implicitFieldStructType =
[implicitFieldType, implicitFieldType.(PointerType).getBaseType().getUnderlyingType()] and
implicitFieldStructType.getOwnField(_, _) = field
|
result = ifri
)
@@ -339,7 +345,11 @@ module IR {
}
/**
* An IR instruction for an implicit field read as part of reading a promoted field.
* An IR instruction for an implicit field read as part of reading a
* promoted field.
*
* If that field has a pointer type then this instruction also represents an
* implicit dereference of it.
*/
class ImplicitFieldReadInstruction extends Instruction, MkImplicitFieldSelection {
SelectorExpr e;
@@ -353,7 +363,11 @@ module IR {
override predicate reads(ValueEntity v) { v = implicitField }
override Type getResultType() { result = implicitField.getType() }
override Type getResultType() {
if implicitField.getType() instanceof PointerType
then result = implicitField.getType().(PointerType).getBaseType()
else result = implicitField.getType()
}
override ControlFlow::Root getRoot() { result.isRootOf(e) }