diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 24598bdaf12..30b26b59ad9 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -268,6 +268,7 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo.(PhiInstruction).getAnOperand().getDef() = iFrom or // Treat all conversions as flow, even conversions between different numeric types. iTo.(ConvertInstruction).getUnary() = iFrom or + iTo.(CheckedConvertOrNullInstruction).getUnary() = iFrom or iTo.(InheritanceConversionInstruction).getUnary() = iFrom or // A chi instruction represents a point where a new value (the _partial_ // operand) may overwrite an old value (the _total_ operand), but the alias diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 7514f580813..4f4b0eafe62 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -947,6 +947,10 @@ class ConvertInstruction extends UnaryInstruction { ConvertInstruction() { getOpcode() instanceof Opcode::Convert } } +class CheckedConvertOrNullInstruction extends UnaryInstruction { + CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull } +} + /** * Represents an instruction that converts between two addresses * related by inheritance. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll index 99f6b545806..6fe55c49d8f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll @@ -96,6 +96,10 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8) ) or + // Conversion using dynamic_cast results in an unknown offset + instr instanceof CheckedConvertOrNullInstruction and + bitOffset = Ints::unknown() + or // Converting to a derived class subtracts the offset of the base class. exists(ConvertToDerivedInstruction convert | convert = instr and diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 7514f580813..4f4b0eafe62 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -947,6 +947,10 @@ class ConvertInstruction extends UnaryInstruction { ConvertInstruction() { getOpcode() instanceof Opcode::Convert } } +class CheckedConvertOrNullInstruction extends UnaryInstruction { + CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull } +} + /** * Represents an instruction that converts between two addresses * related by inheritance. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 7514f580813..4f4b0eafe62 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -947,6 +947,10 @@ class ConvertInstruction extends UnaryInstruction { ConvertInstruction() { getOpcode() instanceof Opcode::Convert } } +class CheckedConvertOrNullInstruction extends UnaryInstruction { + CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull } +} + /** * Represents an instruction that converts between two addresses * related by inheritance. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll index 99f6b545806..6fe55c49d8f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll @@ -96,6 +96,10 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8) ) or + // Conversion using dynamic_cast results in an unknown offset + instr instanceof CheckedConvertOrNullInstruction and + bitOffset = Ints::unknown() + or // Converting to a derived class subtracts the offset of the base class. exists(ConvertToDerivedInstruction convert | convert = instr and