Skip to content

Commit 89fd287

Browse files
authored
Merge pull request github#18773 from MathiasVP/cleanup-ssa-internals-2
C++: Clean up some stuff in `SsaInternals`
2 parents a9b9410 + 9cfd339 commit 89fd287

File tree

3 files changed

+62
-165
lines changed

3 files changed

+62
-165
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,14 +1765,14 @@ module IteratorFlow {
17651765
* Note: Unlike `def.getAnUltimateDefinition()` this predicate also
17661766
* traverses back through iterator increment and decrement operations.
17671767
*/
1768-
private Ssa::Def getAnUltimateDefinition(Ssa::Def def) {
1768+
private Ssa::DefinitionExt getAnUltimateDefinition(Ssa::DefinitionExt def) {
17691769
result = def.getAnUltimateDefinition()
17701770
or
17711771
exists(IRBlock bb, int i, IteratorCrementCall crementCall, Ssa::SourceVariable sv |
17721772
crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and
17731773
sv = def.getSourceVariable() and
17741774
bb.getInstruction(i) = crementCall and
1775-
Ssa::ssaDefReachesReadExt(sv, result.asDef(), bb, i)
1775+
Ssa::ssaDefReachesReadExt(sv, result, bb, i)
17761776
)
17771777
}
17781778

@@ -1800,13 +1800,13 @@ module IteratorFlow {
18001800
GetsIteratorCall beginCall, Instruction writeToDeref
18011801
) {
18021802
exists(
1803-
StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Def def,
1804-
IteratorPointerDereferenceCall starCall, Ssa::Def ultimate, Operand address
1803+
StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::DefinitionExt def,
1804+
IteratorPointerDereferenceCall starCall, Ssa::DefinitionExt ultimate, Operand address
18051805
|
18061806
isIteratorWrite(writeToDeref, address) and
18071807
operandForFullyConvertedCall(address, starCall) and
18081808
bbStar.getInstruction(iStar) = starCall and
1809-
Ssa::ssaDefReachesReadExt(_, def.asDef(), bbStar, iStar) and
1809+
Ssa::ssaDefReachesReadExt(_, def, bbStar, iStar) and
18101810
ultimate = getAnUltimateDefinition*(def) and
18111811
beginStore = ultimate.getValue().asInstruction() and
18121812
operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall)

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -842,18 +842,11 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
842842
result.asSourceCallable() = this.getFunction()
843843
}
844844

845-
override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() }
845+
override Declaration getFunction() { result = globalDef.getFunction() }
846846

847847
final override predicate isGLValue() { globalDef.getIndirectionIndex() = 0 }
848848

849-
override DataFlowType getType() {
850-
exists(DataFlowType type |
851-
type = globalDef.getUnderlyingType() and
852-
if this.isGLValue()
853-
then result = type
854-
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
855-
)
856-
}
849+
override DataFlowType getType() { result = globalDef.getUnderlyingType() }
857850

858851
final override Location getLocationImpl() { result = globalDef.getLocation() }
859852

@@ -1312,7 +1305,7 @@ class UninitializedNode extends Node {
13121305
LocalVariable v;
13131306

13141307
UninitializedNode() {
1315-
exists(Ssa::Def def, Ssa::SourceVariable sv |
1308+
exists(Ssa::DefinitionExt def, Ssa::SourceVariable sv |
13161309
def.getIndirectionIndex() = 0 and
13171310
def.getValue().asInstruction() instanceof UninitializedInstruction and
13181311
Ssa::defToNode(this, def, sv, _, _, _) and
@@ -2299,7 +2292,7 @@ class ContentSet instanceof Content {
22992292

23002293
pragma[nomagic]
23012294
private predicate guardControlsPhiInput(
2302-
IRGuardCondition g, boolean branch, Ssa::Definition def, IRBlock input, Ssa::PhiNode phi
2295+
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
23032296
) {
23042297
phi.hasInputFromBlock(def, _, _, _, input) and
23052298
(

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

Lines changed: 53 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,16 @@ abstract class DefImpl extends TDefImpl {
225225
)
226226
}
227227

228+
/**
229+
* Holds if this definition is guaranteed to totally overwrite the
230+
* destination buffer.
231+
*/
228232
abstract predicate isCertain();
229233

234+
/** Gets the value written to the destination variable by this definition. */
230235
abstract Node0Impl getValue();
231236

237+
/** Gets the operand that represents the address of this definition, if any. */
232238
Operand getAddressOperand() { none() }
233239
}
234240

@@ -691,8 +697,10 @@ predicate outNodeHasAddressAndIndex(
691697
*
692698
* Holds if `node` is the node that corresponds to the definition of `def`.
693699
*/
694-
predicate defToNode(Node node, Def def, SourceVariable sv, IRBlock bb, int i, boolean uncertain) {
695-
def.hasIndexInBlock(bb, i, sv) and
700+
predicate defToNode(
701+
Node node, DefinitionExt def, SourceVariable sv, IRBlock bb, int i, boolean uncertain
702+
) {
703+
def.definesAt(sv, bb, i, _) and
696704
(
697705
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
698706
or
@@ -1057,7 +1065,7 @@ module SsaCached {
10571065
}
10581066

10591067
cached
1060-
Definition phiHasInputFromBlockExt(PhiNode phi, IRBlock bb) {
1068+
DefinitionExt phiHasInputFromBlockExt(PhiNode phi, IRBlock bb) {
10611069
SsaImpl::phiHasInputFromBlockExt(phi, result, bb)
10621070
}
10631071

@@ -1071,157 +1079,24 @@ module SsaCached {
10711079
predicate variableWrite = SsaInput::variableWrite/4;
10721080
}
10731081

1074-
cached
1075-
private newtype TSsaDef =
1076-
TDef(DefinitionExt def) or
1077-
TPhi(PhiNode phi)
1078-
1079-
abstract private class SsaDef extends TSsaDef {
1080-
/** Gets a textual representation of this element. */
1081-
string toString() { none() }
1082-
1083-
/** Gets the underlying non-phi definition or use. */
1084-
DefinitionExt asDef() { none() }
1085-
1086-
/** Gets the underlying phi node. */
1087-
PhiNode asPhi() { none() }
1088-
1089-
/** Gets the location of this element. */
1090-
abstract Location getLocation();
1091-
}
1092-
1093-
abstract class Def extends SsaDef, TDef {
1094-
DefinitionExt def;
1095-
1096-
Def() { this = TDef(def) }
1097-
1098-
final override DefinitionExt asDef() { result = def }
1099-
1100-
/** Gets the source variable underlying this SSA definition. */
1101-
final SourceVariable getSourceVariable() { result = def.getSourceVariable() }
1102-
1103-
override string toString() { result = def.toString() }
1104-
1105-
/**
1106-
* Holds if this definition (or use) has index `index` in block `block`,
1107-
* and is a definition (or use) of the variable `sv`.
1108-
*/
1109-
predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
1110-
def.definesAt(sv, block, index, _)
1111-
}
1112-
1113-
/** Gets the value written by this definition, if any. */
1114-
Node0Impl getValue() { none() }
1115-
1116-
/**
1117-
* Holds if this definition is guaranteed to overwrite the entire
1118-
* destination's allocation.
1119-
*/
1120-
abstract predicate isCertain();
1121-
1122-
/** Gets the address operand written to by this definition. */
1123-
Operand getAddressOperand() { none() }
1124-
1125-
/** Gets the address written to by this definition. */
1126-
final Instruction getAddress() { result = this.getAddressOperand().getDef() }
1127-
1128-
/** Gets the indirection index of this definition. */
1129-
abstract int getIndirectionIndex();
1130-
1131-
/**
1132-
* Gets the indirection level that this definition is writing to.
1133-
* For instance, `x = y` is a definition of `x` at indirection level 1 and
1134-
* `*x = y` is a definition of `x` at indirection level 2.
1135-
*/
1136-
abstract int getIndirection();
1137-
1138-
/**
1139-
* Gets a definition that ultimately defines this SSA definition and is not
1140-
* itself a phi node.
1141-
*/
1142-
Def getAnUltimateDefinition() { result.asDef() = def.getAnUltimateDefinition() }
1143-
}
1144-
1145-
private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) {
1082+
/** Gets the `DefImpl` corresponding to `def`. */
1083+
private DefImpl getDefImpl(SsaImpl::DefinitionExt def) {
11461084
exists(SourceVariable sv, IRBlock bb, int i |
11471085
def.definesAt(sv, bb, i, _) and
1148-
global.hasIndexInBlock(bb, i, sv)
1086+
result.hasIndexInBlock(bb, i, sv)
11491087
)
11501088
}
11511089

1152-
private class NonGlobalDef extends Def {
1153-
NonGlobalDef() { not isGlobal(def, _) }
1154-
1155-
final override Location getLocation() { result = this.getImpl().getLocation() }
1156-
1157-
private DefImpl getImpl() {
1158-
exists(SourceVariable sv, IRBlock bb, int i |
1159-
this.hasIndexInBlock(bb, i, sv) and
1160-
result.hasIndexInBlock(bb, i, sv)
1161-
)
1162-
}
1163-
1164-
override Node0Impl getValue() { result = this.getImpl().getValue() }
1165-
1166-
override predicate isCertain() { this.getImpl().isCertain() }
1090+
class GlobalDef extends DefinitionExt {
1091+
GlobalDefImpl impl;
11671092

1168-
override Operand getAddressOperand() { result = this.getImpl().getAddressOperand() }
1169-
1170-
override int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
1171-
1172-
override int getIndirection() { result = this.getImpl().getIndirection() }
1173-
}
1174-
1175-
class GlobalDef extends Def {
1176-
GlobalDefImpl global;
1177-
1178-
GlobalDef() { isGlobal(def, global) }
1179-
1180-
/** Gets a textual representation of this definition. */
1181-
override string toString() { result = global.toString() }
1182-
1183-
final override Location getLocation() { result = global.getLocation() }
1184-
1185-
/**
1186-
* Gets the type of this definition after specifiers have been deeply stripped
1187-
* and typedefs have been resolved.
1188-
*/
1189-
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
1093+
GlobalDef() { impl = getDefImpl(this) }
11901094

11911095
/**
1192-
* Gets the type of this definition, after typedefs have been resolved.
1096+
* Gets the global (or `static` local) variable written to by this SSA
1097+
* definition.
11931098
*/
1194-
DataFlowType getUnderlyingType() { result = global.getUnderlyingType() }
1195-
1196-
/** Gets the `IRFunction` whose body is evaluated after this definition. */
1197-
IRFunction getIRFunction() { result = global.getIRFunction() }
1198-
1199-
/** Gets the global variable associated with this definition. */
1200-
GlobalLikeVariable getVariable() { result = global.getVariable() }
1201-
1202-
override predicate isCertain() { any() }
1203-
1204-
final override int getIndirectionIndex() { result = global.getIndirectionIndex() }
1205-
1206-
final override int getIndirection() { result = global.getIndirection() }
1207-
}
1208-
1209-
class Phi extends TPhi, SsaDef {
1210-
PhiNode phi;
1211-
1212-
Phi() { this = TPhi(phi) }
1213-
1214-
final override PhiNode asPhi() { result = phi }
1215-
1216-
final override Location getLocation() { result = phi.getBasicBlock().getLocation() }
1217-
1218-
override string toString() { result = phi.toString() }
1219-
1220-
SsaPhiInputNode getNode(IRBlock block) { result.getPhiNode() = phi and result.getBlock() = block }
1221-
1222-
predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlockExt(phi, bb) }
1223-
1224-
final Definition getAnInput() { this.hasInputFromBlock(result, _) }
1099+
GlobalLikeVariable getVariable() { result = impl.getVariable() }
12251100
}
12261101

12271102
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
@@ -1259,12 +1134,12 @@ class PhiNode extends SsaImpl::DefinitionExt {
12591134
}
12601135

12611136
/** Gets a definition that is an input to this phi node. */
1262-
final Definition getAnInput() { this.hasInputFromBlock(result, _, _, _, _) }
1137+
final DefinitionExt getAnInput() { this.hasInputFromBlock(result, _, _, _, _) }
12631138
}
12641139

12651140
/** An static single assignment (SSA) definition. */
12661141
class DefinitionExt extends SsaImpl::DefinitionExt {
1267-
private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
1142+
private DefinitionExt getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
12681143

12691144
/**
12701145
* Gets a definition that ultimately defines this SSA definition and is
@@ -1275,6 +1150,37 @@ class DefinitionExt extends SsaImpl::DefinitionExt {
12751150
not result instanceof PhiNode
12761151
}
12771152

1153+
/**
1154+
* INTERNAL: Do not use.
1155+
*/
1156+
Node0Impl getValue() { result = getDefImpl(this).getValue() }
1157+
1158+
/** Gets the indirection index of this definition. */
1159+
int getIndirectionIndex() { result = getDefImpl(this).getIndirectionIndex() }
1160+
1161+
/** Gets the indirection of this definition. */
1162+
int getIndirection() { result = getDefImpl(this).getIndirection() }
1163+
1164+
/**
1165+
* Holds if this definition is guaranteed to totally overwrite the buffer
1166+
* being written to.
1167+
*/
1168+
predicate isCertain() { getDefImpl(this).isCertain() }
1169+
1170+
/**
1171+
* Gets the enclosing declaration of this definition.
1172+
*
1173+
* Note that this may be a variable when this definition defines a global, or
1174+
* a static local, variable.
1175+
*/
1176+
Declaration getFunction() { result = getDefImpl(this).getBlock().getEnclosingFunction() }
1177+
1178+
/** Gets the underlying type of the variable being defined by this definition. */
1179+
Type getUnderlyingType() { result = this.getSourceVariable().getType() }
1180+
1181+
/** Gets the unspecified type of the variable being defined by this definition. */
1182+
Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() }
1183+
12781184
/** Gets a node that represents a read of this SSA definition. */
12791185
pragma[nomagic]
12801186
Node getARead() {
@@ -1286,6 +1192,4 @@ class DefinitionExt extends SsaImpl::DefinitionExt {
12861192
}
12871193
}
12881194

1289-
class Definition = SsaImpl::Definition;
1290-
12911195
import SsaCached

0 commit comments

Comments
 (0)