Skip to content

Commit f03146d

Browse files
committed
Refactor fieldSign
1 parent 21ff1a0 commit f03146d

4 files changed

Lines changed: 78 additions & 30 deletions

File tree

csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,20 @@ private Sign implicitSsaDefSign(SsaVariable v) {
277277
anySign(result) and nonFieldImplicitSsaDefinition(v)
278278
}
279279

280+
/** Gets a possible sign for `f`. */
281+
Sign fieldSign(Field f) {
282+
if not fieldWithUnknownSign(f)
283+
then
284+
result = exprSign(getAssignedValueToField(f))
285+
or
286+
fieldIncrementOperationOperand(f) and result = fieldSign(f).inc()
287+
or
288+
fieldDecrementOperationOperand(f) and result = fieldSign(f).dec()
289+
or
290+
result = specificFieldSign(f)
291+
else anySign(result)
292+
}
293+
280294
/** Gets a possible sign for `e`. */
281295
cached
282296
Sign exprSign(Expr e) {

csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ module Private {
3636

3737
class ExprWithPossibleValue = CS::Expr;
3838

39+
class Field = CS::Field;
40+
3941
predicate ssaRead = SU::ssaRead/2;
4042
}
4143

@@ -133,22 +135,29 @@ private module Impl {
133135
not getImplicitSsaDeclaration(v) instanceof Field
134136
}
135137

136-
/** Gets a possible sign for `f`. */
137-
Sign fieldSign(Field f) {
138-
if f.fromSource() and f.isEffectivelyPrivate()
139-
then
140-
result = exprSign(f.getAnAssignedValue())
141-
or
142-
any(IncrementOperation inc).getOperand() = f.getAnAccess() and result = fieldSign(f).inc()
143-
or
144-
any(DecrementOperation dec).getOperand() = f.getAnAccess() and result = fieldSign(f).dec()
145-
or
146-
exists(AssignOperation a | a.getLValue() = f.getAnAccess() | result = exprSign(a))
147-
or
148-
not exists(f.getInitializer()) and result = TZero()
149-
else anySign(result)
138+
/** Returned an expression that is assigned to `f`. */
139+
Expr getAssignedValueToField(Field f) {
140+
result = f.getAnAssignedValue() or
141+
result = any(AssignOperation a | a.getLValue() = f.getAnAccess())
150142
}
151143

144+
/** Holds if `f` can have any sign. */
145+
predicate fieldWithUnknownSign(Field f) { not f.fromSource() or not f.isEffectivelyPrivate() }
146+
147+
/** Holds if `f` is accessed in an increment operation. */
148+
predicate fieldIncrementOperationOperand(Field f) {
149+
any(IncrementOperation inc).getOperand() = f.getAnAccess()
150+
}
151+
152+
/** Holds if `f` is accessed in a decrement operation. */
153+
predicate fieldDecrementOperationOperand(Field f) {
154+
any(DecrementOperation dec).getOperand() = f.getAnAccess()
155+
}
156+
157+
/** Returns possible signs of `f` based on the declaration. */
158+
pragma[inline]
159+
Sign specificFieldSign(Field f) { not exists(f.getInitializer()) and result = TZero() }
160+
152161
/**
153162
* Holds if `e` has type `NumericOrCharType`, but the sign of `e` is unknown.
154163
*/

java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,20 @@ private Sign implicitSsaDefSign(SsaVariable v) {
277277
anySign(result) and nonFieldImplicitSsaDefinition(v)
278278
}
279279

280+
/** Gets a possible sign for `f`. */
281+
Sign fieldSign(Field f) {
282+
if not fieldWithUnknownSign(f)
283+
then
284+
result = exprSign(getAssignedValueToField(f))
285+
or
286+
fieldIncrementOperationOperand(f) and result = fieldSign(f).inc()
287+
or
288+
fieldDecrementOperationOperand(f) and result = fieldSign(f).dec()
289+
or
290+
result = specificFieldSign(f)
291+
else anySign(result)
292+
}
293+
280294
/** Gets a possible sign for `e`. */
281295
cached
282296
Sign exprSign(Expr e) {

java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ module Private {
4040

4141
class ExprWithPossibleValue = J::Literal;
4242

43+
class Field = J::Field;
44+
4345
predicate ssaRead = RU::ssaRead/2;
4446

4547
predicate guardControlsSsaRead = RU::guardControlsSsaRead/3;
@@ -128,22 +130,31 @@ private module Impl {
128130
exists(Parameter p | v.isParameterDefinition(p))
129131
}
130132

131-
/** Gets a possible sign for `f`. */
132-
Sign fieldSign(Field f) {
133-
result = exprSign(f.getAnAssignedValue())
134-
or
135-
exists(PostIncExpr inc | inc.getExpr() = f.getAnAccess() and result = fieldSign(f).inc())
136-
or
137-
exists(PreIncExpr inc | inc.getExpr() = f.getAnAccess() and result = fieldSign(f).inc())
138-
or
139-
exists(PostDecExpr inc | inc.getExpr() = f.getAnAccess() and result = fieldSign(f).dec())
140-
or
141-
exists(PreDecExpr inc | inc.getExpr() = f.getAnAccess() and result = fieldSign(f).dec())
142-
or
143-
exists(AssignOp a | a.getDest() = f.getAnAccess() | result = exprSign(a))
144-
or
145-
anySign(result) and exists(ReflectiveFieldAccess rfa | rfa.inferAccessedField() = f)
146-
or
133+
/** Returned an expression that is assigned to `f`. */
134+
Expr getAssignedValueToField(Field f) {
135+
result = f.getAnAssignedValue() or
136+
result = any(AssignOp a | a.getDest() = f.getAnAccess())
137+
}
138+
139+
/** Holds if `f` can have any sign. */
140+
predicate fieldWithUnknownSign(Field f) {
141+
exists(ReflectiveFieldAccess rfa | rfa.inferAccessedField() = f)
142+
}
143+
144+
/** Holds if `f` is accessed in an increment operation. */
145+
predicate fieldIncrementOperationOperand(Field f) {
146+
any(PostIncExpr inc).getExpr() = f.getAnAccess() or
147+
any(PreIncExpr inc).getExpr() = f.getAnAccess()
148+
}
149+
150+
/** Holds if `f` is accessed in a decrement operation. */
151+
predicate fieldDecrementOperationOperand(Field f) {
152+
any(PostDecExpr dec).getExpr() = f.getAnAccess() or
153+
any(PreDecExpr dec).getExpr() = f.getAnAccess()
154+
}
155+
156+
/** Returns possible signs of `f` based on the declaration. */
157+
Sign specificFieldSign(Field f) {
147158
if f.fromSource()
148159
then not exists(f.getInitializer()) and result = TZero()
149160
else

0 commit comments

Comments
 (0)