Skip to content

Commit d8ec6dd

Browse files
authored
Merge pull request #18490 from MathiasVP/generate-int-to-bool-conversion-instructions-2
C++: Generate int-to-bool conversions in C code
2 parents 17d2e4a + 21f9e67 commit d8ec6dd

25 files changed

+1966
-1429
lines changed

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

+179-121
Large diffs are not rendered by default.

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

+17
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,23 @@ module Raw {
171171
// forwarded the result of another translated expression.
172172
instruction = translatedExpr.getInstruction(_)
173173
)
174+
or
175+
// Consider the snippet `if(x) { ... }` where `x` is an integer.
176+
// In C++ there is a `BoolConversion` conversion on `x` which generates a
177+
// `CompareNEInstruction` whose `getInstructionConvertedResultExpression`
178+
// is the `BoolConversion` (by the logic in the disjunct above). Thus,
179+
// calling `getInstructionUnconvertedResultExpression` on the
180+
// `CompareNEInstruction` gives `x` in C++ code.
181+
// However, in C there is no such conversion to return. So instead we have
182+
// to map the result of `getInstructionConvertedResultExpression` on the
183+
// `CompareNEInstruction` to `x` manually. This ensures that calling
184+
// `getInstructionUnconvertedResultExpression` on the `CompareNEInstruction`
185+
// gives `x` in both the C case and C++ case.
186+
exists(TranslatedValueCondition translatedValueCondition |
187+
translatedValueCondition = getTranslatedCondition(result) and
188+
translatedValueCondition.shouldGenerateCompareNE() and
189+
instruction = translatedValueCondition.getInstruction(ValueConditionCompareTag())
190+
)
174191
}
175192

176193
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll

+18
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ newtype TInstructionTag =
3838
AllocationSizeTag() or
3939
AllocationElementSizeTag() or
4040
AllocationExtentConvertTag() or
41+
ValueConditionCompareTag() or
42+
ValueConditionConstantTag() or
4143
ValueConditionConditionalBranchTag() or
44+
ValueConditionConditionalConstantTag() or
45+
ValueConditionConditionalCompareTag() or
4246
ConditionValueTrueTempAddressTag() or
4347
ConditionValueTrueConstantTag() or
4448
ConditionValueTrueStoreTag() or
@@ -49,6 +53,8 @@ newtype TInstructionTag =
4953
ConditionValueResultLoadTag() or
5054
BoolConversionConstantTag() or
5155
BoolConversionCompareTag() or
56+
NotExprOperationTag() or
57+
NotExprConstantTag() or
5258
ResultCopyTag() or
5359
LoadTag() or // Implicit load due to lvalue-to-rvalue conversion
5460
CatchTag() or
@@ -167,6 +173,14 @@ string getInstructionTagId(TInstructionTag tag) {
167173
or
168174
tag = ValueConditionConditionalBranchTag() and result = "ValCondCondBranch"
169175
or
176+
tag = ValueConditionConditionalConstantTag() and result = "ValueConditionConditionalConstant"
177+
or
178+
tag = ValueConditionConditionalCompareTag() and result = "ValueConditionConditionalCompare"
179+
or
180+
tag = ValueConditionCompareTag() and result = "ValCondCondCompare"
181+
or
182+
tag = ValueConditionConstantTag() and result = "ValCondConstant"
183+
or
170184
tag = ConditionValueTrueTempAddressTag() and result = "CondValTrueTempAddr"
171185
or
172186
tag = ConditionValueTrueConstantTag() and result = "CondValTrueConst"
@@ -187,6 +201,10 @@ string getInstructionTagId(TInstructionTag tag) {
187201
or
188202
tag = BoolConversionCompareTag() and result = "BoolConvComp"
189203
or
204+
tag = NotExprOperationTag() and result = "NotExprOperation"
205+
or
206+
tag = NotExprConstantTag() and result = "NotExprWithBoolConversionConstant"
207+
or
190208
tag = ResultCopyTag() and result = "ResultCopy"
191209
or
192210
tag = LoadTag() and result = "Load" // Implicit load due to lvalue-to-rvalue conversion

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll

+50-3
Original file line numberDiff line numberDiff line change
@@ -187,19 +187,49 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
187187

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

190+
private Type getValueExprType() {
191+
result = this.getValueExpr().getExprType().getUnspecifiedType()
192+
}
193+
194+
predicate shouldGenerateCompareNE() { not this.getValueExprType() instanceof BoolType }
195+
190196
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
197+
this.shouldGenerateCompareNE() and
198+
(
199+
tag = ValueConditionCompareTag() and
200+
opcode instanceof Opcode::CompareNE and
201+
resultType = getBoolType()
202+
or
203+
tag = ValueConditionConstantTag() and
204+
opcode instanceof Opcode::Constant and
205+
resultType = getTypeForPRValue(this.getValueExprType())
206+
)
207+
or
191208
tag = ValueConditionConditionalBranchTag() and
192209
opcode instanceof Opcode::ConditionalBranch and
193210
resultType = getVoidType()
194211
}
195212

196213
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
197214
child = this.getValueExpr() and
198-
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
199-
kind instanceof GotoEdge
215+
kind instanceof GotoEdge and
216+
if this.shouldGenerateCompareNE()
217+
then result = this.getInstruction(ValueConditionConstantTag())
218+
else result = this.getInstruction(ValueConditionConditionalBranchTag())
200219
}
201220

202221
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
222+
this.shouldGenerateCompareNE() and
223+
(
224+
tag = ValueConditionConstantTag() and
225+
kind instanceof GotoEdge and
226+
result = this.getInstruction(ValueConditionCompareTag())
227+
or
228+
tag = ValueConditionCompareTag() and
229+
kind instanceof GotoEdge and
230+
result = this.getInstruction(ValueConditionConditionalBranchTag())
231+
)
232+
or
203233
tag = ValueConditionConditionalBranchTag() and
204234
(
205235
kind instanceof TrueEdge and
@@ -211,9 +241,26 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
211241
}
212242

213243
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
244+
this.shouldGenerateCompareNE() and
245+
tag = ValueConditionCompareTag() and
246+
(
247+
operandTag instanceof LeftOperandTag and
248+
result = this.getValueExpr().getResult()
249+
or
250+
operandTag instanceof RightOperandTag and
251+
result = this.getInstruction(ValueConditionConstantTag())
252+
)
253+
or
214254
tag = ValueConditionConditionalBranchTag() and
215255
operandTag instanceof ConditionOperandTag and
216-
result = this.getValueExpr().getResult()
256+
if this.shouldGenerateCompareNE()
257+
then result = this.getInstruction(ValueConditionCompareTag())
258+
else result = this.getValueExpr().getResult()
259+
}
260+
261+
override string getInstructionConstantValue(InstructionTag tag) {
262+
tag = ValueConditionConstantTag() and
263+
result = "0"
217264
}
218265

219266
private TranslatedExpr getValueExpr() { result = getTranslatedExpr(expr) }

0 commit comments

Comments
 (0)