Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++: Generate int-to-bool conversions in C code #18490

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6dd1c5e
C++: Split out 'NotExpr' to its own class.
MathiasVP Nov 19, 2024
9429b03
C++: Provide a hook for overriding 'getResultType'.
MathiasVP Nov 19, 2024
5acd2bb
C++: Adjust the result type at 'NotExpr' and at comparisons.
MathiasVP Nov 19, 2024
2e3d349
C++: Accept test changes.
MathiasVP Nov 19, 2024
dd39b97
C++: Insert int-to-bool conversions at conditions.
MathiasVP Nov 20, 2024
1e33593
C++: Accept test changes.
MathiasVP Nov 19, 2024
f30bfb6
C++: Insert int-to-bool conversions at 'NotExpr's.
MathiasVP Nov 20, 2024
9d3bc7f
C++: Accept test changes.
MathiasVP Nov 19, 2024
6577161
C++: Insert int-to-bool conversions at binary conditional expressions.
MathiasVP Nov 20, 2024
5da57cd
C++: Accept test changes.
MathiasVP Nov 19, 2024
0d7adac
C++: Accept Guards test changes.
MathiasVP Nov 19, 2024
9810a4f
C++: Remove 'inNonZeroCase' from IRGuards since we now always have im…
MathiasVP Jan 11, 2025
ebb7f28
C++: Remove workaround for missing comparisons against 0 in C code.
MathiasVP Jan 11, 2025
2d9036e
C++: Make 'getInstructionConvertedResultExpression' equivalent in C a…
MathiasVP Nov 20, 2024
b5897e5
C++: Accept sign analysis changes.
MathiasVP Jan 13, 2025
14db788
C++: Ensure that 'x' in 'if(!x) is also an AST-based GuardCondition.
MathiasVP Jan 14, 2025
7cca213
C++: Accept test changes.
MathiasVP Jan 14, 2025
5373e22
C++: Improve IRGuads logic for 'unlikely' expressions.
MathiasVP Jan 15, 2025
6ba5f3e
Merge branch 'main' into generate-int-to-bool-conversion-instructions-2
MathiasVP Jan 16, 2025
2076c1c
C++: Add an copy of a (slightly modified) syntax-zoo test as an IR test.
MathiasVP Jan 16, 2025
00a1978
C++: Add a guard condition test with an example of a negated less-tha…
MathiasVP Jan 16, 2025
54faba2
C++: Add more tests.
MathiasVP Jan 16, 2025
d0bd6eb
C++: Remove the type restriction on 'GuardConditionFromNotExpr' since…
MathiasVP Jan 16, 2025
d5b31eb
C++: Add more tests.
MathiasVP Jan 16, 2025
b39a932
C++: Update comment in the char pred of 'GuardConditionFromNotExpr'.
MathiasVP Jan 17, 2025
21f9e67
C++: Remove an unnecessary conjunct.
MathiasVP Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
300 changes: 179 additions & 121 deletions cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,23 @@ module Raw {
// forwarded the result of another translated expression.
instruction = translatedExpr.getInstruction(_)
)
or
// Consider the snippet `if(x) { ... }` where `x` is an integer.
// In C++ there is a `BoolConversion` conversion on `x` which generates a
// `CompareNEInstruction` whose `getInstructionConvertedResultExpression`
// is the `BoolConversion` (by the logic in the disjunct above). Thus,
// calling `getInstructionUnconvertedResultExpression` on the
// `CompareNEInstruction` gives `x` in C++ code.
// However, in C there is no such conversion to return. So instead we have
// to map the result of `getInstructionConvertedResultExpression` on the
// `CompareNEInstruction` to `x` manually. This ensures that calling
// `getInstructionUnconvertedResultExpression` on the `CompareNEInstruction`
// gives `x` in both the C case and C++ case.
exists(TranslatedValueCondition translatedValueCondition |
translatedValueCondition = getTranslatedCondition(result) and
translatedValueCondition.shouldGenerateCompareNE() and
instruction = translatedValueCondition.getInstruction(ValueConditionCompareTag())
)
}

cached
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ newtype TInstructionTag =
AllocationSizeTag() or
AllocationElementSizeTag() or
AllocationExtentConvertTag() or
ValueConditionCompareTag() or
ValueConditionConstantTag() or
ValueConditionConditionalBranchTag() or
ValueConditionConditionalConstantTag() or
ValueConditionConditionalCompareTag() or
ConditionValueTrueTempAddressTag() or
ConditionValueTrueConstantTag() or
ConditionValueTrueStoreTag() or
Expand All @@ -49,6 +53,8 @@ newtype TInstructionTag =
ConditionValueResultLoadTag() or
BoolConversionConstantTag() or
BoolConversionCompareTag() or
NotExprOperationTag() or
NotExprConstantTag() or
ResultCopyTag() or
LoadTag() or // Implicit load due to lvalue-to-rvalue conversion
CatchTag() or
Expand Down Expand Up @@ -167,6 +173,14 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = ValueConditionConditionalBranchTag() and result = "ValCondCondBranch"
or
tag = ValueConditionConditionalConstantTag() and result = "ValueConditionConditionalConstant"
or
tag = ValueConditionConditionalCompareTag() and result = "ValueConditionConditionalCompare"
or
tag = ValueConditionCompareTag() and result = "ValCondCondCompare"
or
tag = ValueConditionConstantTag() and result = "ValCondConstant"
or
tag = ConditionValueTrueTempAddressTag() and result = "CondValTrueTempAddr"
or
tag = ConditionValueTrueConstantTag() and result = "CondValTrueConst"
Expand All @@ -187,6 +201,10 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = BoolConversionCompareTag() and result = "BoolConvComp"
or
tag = NotExprOperationTag() and result = "NotExprOperation"
or
tag = NotExprConstantTag() and result = "NotExprWithBoolConversionConstant"
or
tag = ResultCopyTag() and result = "ResultCopy"
or
tag = LoadTag() and result = "Load" // Implicit load due to lvalue-to-rvalue conversion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,49 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond

final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors

private Type getValueExprType() {
result = this.getValueExpr().getExprType().getUnspecifiedType()
}

predicate shouldGenerateCompareNE() { not this.getValueExprType() instanceof BoolType }

override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
this.shouldGenerateCompareNE() and
(
tag = ValueConditionCompareTag() and
opcode instanceof Opcode::CompareNE and
resultType = getBoolType()
or
tag = ValueConditionConstantTag() and
opcode instanceof Opcode::Constant and
resultType = getTypeForPRValue(this.getValueExprType())
)
or
tag = ValueConditionConditionalBranchTag() and
opcode instanceof Opcode::ConditionalBranch and
resultType = getVoidType()
}

override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
child = this.getValueExpr() and
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
kind instanceof GotoEdge
kind instanceof GotoEdge and
if this.shouldGenerateCompareNE()
then result = this.getInstruction(ValueConditionConstantTag())
else result = this.getInstruction(ValueConditionConditionalBranchTag())
}

override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
this.shouldGenerateCompareNE() and
(
tag = ValueConditionConstantTag() and
kind instanceof GotoEdge and
result = this.getInstruction(ValueConditionCompareTag())
or
tag = ValueConditionCompareTag() and
kind instanceof GotoEdge and
result = this.getInstruction(ValueConditionConditionalBranchTag())
)
or
tag = ValueConditionConditionalBranchTag() and
(
kind instanceof TrueEdge and
Expand All @@ -211,9 +241,26 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
}

override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
this.shouldGenerateCompareNE() and
tag = ValueConditionCompareTag() and
(
operandTag instanceof LeftOperandTag and
result = this.getValueExpr().getResult()
or
operandTag instanceof RightOperandTag and
result = this.getInstruction(ValueConditionConstantTag())
)
or
tag = ValueConditionConditionalBranchTag() and
operandTag instanceof ConditionOperandTag and
result = this.getValueExpr().getResult()
if this.shouldGenerateCompareNE()
then result = this.getInstruction(ValueConditionCompareTag())
else result = this.getValueExpr().getResult()
}

override string getInstructionConstantValue(InstructionTag tag) {
tag = ValueConditionConstantTag() and
result = "0"
}

private TranslatedExpr getValueExpr() { result = getTranslatedExpr(expr) }
Expand Down
Loading