Skip to content

Commit e86d2f8

Browse files
committed
C++: Remove workaround for missing comparisons against 0 in C code.
1 parent c47a92d commit e86d2f8

File tree

4 files changed

+46
-502
lines changed

4 files changed

+46
-502
lines changed

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 27 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,19 @@ private module Cached {
797797
Instruction getSuccessor(CaseEdge kind) { result = switch.getSuccessor(kind) }
798798
}
799799

800+
/**
801+
* A value number such that at least one of the instructions provides
802+
* the operand to a `ConditionalBranchInstruction`.
803+
*/
804+
private class ConditionalBranchConditionValueNumber extends ValueNumber {
805+
ConditionalBranchInstruction branch;
806+
807+
pragma[nomagic]
808+
ConditionalBranchConditionValueNumber() { this.getAnInstruction() = branch.getCondition() }
809+
810+
Operand getConditionOperand() { result = branch.getConditionOperand() }
811+
}
812+
800813
private class BuiltinExpectCallValueNumber extends ValueNumber {
801814
BuiltinExpectCallInstruction instr;
802815

@@ -895,55 +908,6 @@ private module Cached {
895908
value.(BooleanValue).getValue() = false
896909
}
897910

898-
/**
899-
* Holds if `op` is an operand that is eventually used in a unary comparison
900-
* with a constant.
901-
*/
902-
private predicate isRelevantUnaryComparisonOperand(Operand op) {
903-
// Base case: `op` is an operand of a `CompareEQInstruction` or `CompareNEInstruction`,
904-
// and the other operand is a constant.
905-
exists(CompareInstruction eq, Instruction instr |
906-
eq.hasOperands(op, instr.getAUse()) and
907-
exists(int_value(instr))
908-
|
909-
eq instanceof CompareEQInstruction
910-
or
911-
eq instanceof CompareNEInstruction
912-
)
913-
or
914-
// C doesn't have int-to-bool conversions, so `if(x)` will just generate:
915-
// r2_1(glval<int>) = VariableAddress[x]
916-
// r2_2(int) = Load[x] : &:r2_1, m1_6
917-
// v2_3(void) = ConditionalBranch : r2_2
918-
exists(ConditionalBranchInstruction branch | branch.getConditionOperand() = op)
919-
or
920-
// If `!x` is a relevant unary comparison then so is `x`.
921-
exists(LogicalNotInstruction logicalNot |
922-
isRelevantUnaryComparisonOperand(unique( | | logicalNot.getAUse())) and
923-
logicalNot.getUnaryOperand() = op
924-
)
925-
or
926-
// If `y` is a relevant unary comparison and `y = x` then so is `x`.
927-
not op.isDefinitionInexact() and
928-
exists(CopyInstruction copy |
929-
isRelevantUnaryComparisonOperand(unique( | | copy.getAUse())) and
930-
op = copy.getSourceValueOperand()
931-
)
932-
or
933-
// If phi(x1, x2) is a relevant unary comparison then so are `x1` and `x2`.
934-
not op.isDefinitionInexact() and
935-
exists(PhiInstruction phi |
936-
isRelevantUnaryComparisonOperand(unique( | | phi.getAUse())) and
937-
op = phi.getAnInputOperand()
938-
)
939-
or
940-
// If `__builtin_expect(x)` is a relevant unary comparison then so is `x`.
941-
exists(BuiltinExpectCallInstruction call |
942-
isRelevantUnaryComparisonOperand(unique( | | call.getAUse())) and
943-
op = call.getConditionOperand()
944-
)
945-
}
946-
947911
/** Rearrange various simple comparisons into `op == k` form. */
948912
private predicate unary_simple_comparison_eq(
949913
ValueNumber test, Operand op, int k, AbstractValue value
@@ -956,14 +920,23 @@ private module Cached {
956920
case.getValue().toInt() = k
957921
)
958922
or
959-
isRelevantUnaryComparisonOperand(op) and
960-
op.getDef() = test.getAnInstruction() and
961-
(
962-
k = 1 and
963-
value.(BooleanValue).getValue() = true
923+
exists(Instruction const | int_value(const) = k |
924+
value.(BooleanValue).getValue() = true and
925+
test.(CompareEQValueNumber).hasOperands(op, const.getAUse())
964926
or
927+
value.(BooleanValue).getValue() = false and
928+
test.(CompareNEValueNumber).hasOperands(op, const.getAUse())
929+
)
930+
or
931+
test.(ConditionalBranchConditionValueNumber).getConditionOperand() = op and
932+
// Don't include comparisons since these are already included in the binary relation.
933+
not test instanceof CompareValueNumber and
934+
(
965935
k = 0 and
966936
value.(BooleanValue).getValue() = false
937+
or
938+
k = 1 and
939+
value.(BooleanValue).getValue() = true
967940
)
968941
}
969942

0 commit comments

Comments
 (0)