diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll index 8725ce299d8fd..d897627acd40e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll @@ -41,6 +41,8 @@ newtype TInstructionTag = ValueConditionCompareTag() or ValueConditionConstantTag() or ValueConditionConditionalBranchTag() or + ValueConditionConditionalConstantTag() or + ValueConditionConditionalCompareTag() or ConditionValueTrueTempAddressTag() or ConditionValueTrueConstantTag() or ConditionValueTrueStoreTag() or @@ -172,6 +174,10 @@ 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" diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 9f2621a05b83c..76ed9a6ec0b14 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -2957,6 +2957,8 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { result = this.getCondition().getFirstInstruction(kind) } + private Type getConditionType() { result = this.getCondition().getExprType() } + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { super.hasInstruction(opcode, tag, resultType) or @@ -2964,11 +2966,33 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { tag = ValueConditionConditionalBranchTag() and opcode instanceof Opcode::ConditionalBranch and resultType = getVoidType() + or + not this.getConditionType() instanceof BoolType and + ( + tag = ValueConditionConditionalConstantTag() and + opcode instanceof Opcode::Constant and + resultType = getIntType() + or + tag = ValueConditionConditionalCompareTag() and + opcode instanceof Opcode::CompareNE and + resultType = getBoolType() + ) } override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { result = super.getInstructionSuccessorInternal(tag, kind) or + not this.getConditionType() instanceof BoolType and + ( + tag = ValueConditionConditionalConstantTag() and + kind instanceof GotoEdge and + result = this.getInstruction(ValueConditionConditionalCompareTag()) + or + tag = ValueConditionConditionalCompareTag() and + kind instanceof GotoEdge and + result = this.getInstruction(ValueConditionConditionalBranchTag()) + ) + or tag = ValueConditionConditionalBranchTag() and ( kind instanceof TrueEdge and @@ -2984,7 +3008,19 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { or tag = ValueConditionConditionalBranchTag() and operandTag instanceof ConditionOperandTag and - result = this.getCondition().getResult() + if this.getConditionType() instanceof BoolType + then result = this.getCondition().getResult() + else result = this.getInstruction(ValueConditionConditionalCompareTag()) + or + not this.getConditionType() instanceof BoolType and + tag = ValueConditionConditionalCompareTag() and + ( + operandTag instanceof LeftOperandTag and + result = this.getCondition().getResult() + or + operandTag instanceof RightOperandTag and + result = this.getInstruction(ValueConditionConditionalConstantTag()) + ) } override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { @@ -2992,7 +3028,9 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { or kind instanceof GotoEdge and child = this.getCondition() and - result = this.getInstruction(ValueConditionConditionalBranchTag()) + if this.getConditionType() instanceof BoolType + then result = this.getInstruction(ValueConditionConditionalBranchTag()) + else result = this.getInstruction(ValueConditionConditionalConstantTag()) } private TranslatedExpr getCondition() { @@ -3009,6 +3047,11 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { // always converting the "then" operand to `bool`, which is almost always the wrong type. result = getTranslatedExpr(expr.getThen().getExplicitlyConverted()) } + + override string getInstructionConstantValue(InstructionTag tag) { + tag = ValueConditionConditionalConstantTag() and + result = "0" + } } /**