diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index dc178f77547..25de37d096a 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -7,6 +7,7 @@ private import semmle.code.cpp.ir.IR as IR private import Semantic private import experimental.semmle.code.cpp.rangeanalysis.Bound as IRBound private import semmle.code.cpp.controlflow.IRGuards as IRGuards +private import semmle.code.cpp.ir.ValueNumbering module SemanticExprConfig { class Location = Cpp::Location; @@ -119,8 +120,17 @@ module SemanticExprConfig { int getBasicBlockUniqueId(BasicBlock block) { idOf(block.getFirstInstruction().getAst(), result) } newtype TSsaVariable = - TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or - TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } + TSsaInstruction(IR::Instruction instr) { + instr.hasMemoryResult() + } or + TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } or + TSsaPointerArithmeticGuard(IR::PointerArithmeticInstruction instr) { + exists(Guard g, IR::Operand use | use = instr.getAUse() | + g.comparesLt(use, _, _, _, _) or + g.comparesLt(_, use, _, _, _) or + g.comparesEq(use, _, _, _, _) or + g.comparesEq(_, use, _, _, _)) + } class SsaVariable extends TSsaVariable { string toString() { none() } @@ -129,6 +139,8 @@ module SemanticExprConfig { IR::Instruction asInstruction() { none() } + IR::PointerArithmeticInstruction asPointerArithGuard() { none() } + IR::Operand asOperand() { none() } } @@ -144,6 +156,18 @@ module SemanticExprConfig { final override IR::Instruction asInstruction() { result = instr } } + class SsaPointerArithmeticGuard extends SsaVariable, TSsaPointerArithmeticGuard { + IR::PointerArithmeticInstruction instr; + + SsaPointerArithmeticGuard() { this = TSsaPointerArithmeticGuard(instr) } + + final override string toString() { result = instr.toString() } + + final override Location getLocation() { result = instr.getLocation() } + + final override IR::PointerArithmeticInstruction asPointerArithGuard() { result = instr } + } + class SsaOperand extends SsaVariable, TSsaOperand { IR::Operand op; @@ -168,7 +192,11 @@ module SemanticExprConfig { ) } - Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() } + Expr getAUse(SsaVariable v) { + result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() + or + result = valueNumber(v.asPointerArithGuard()).getAnInstruction() + } SemType getSsaVariableType(SsaVariable v) { result = getSemanticType(v.asInstruction().getResultIRType()) @@ -208,7 +236,9 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::Operand operand | - operand.getDef() = v.asInstruction() and + operand.getDef() = v.asInstruction() or + operand.getDef() = valueNumber(v.asPointerArithGuard()).getAnInstruction() + | not operand instanceof IR::PhiInputOperand and operand.getUse().getBlock() = block ) @@ -227,7 +257,9 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::PhiInputOperand operand | - operand.getDef() = v.asInstruction() and + operand.getDef() = v.asInstruction() or + operand.getDef() = valueNumber(v.asPointerArithGuard()).getAnInstruction() + | operand.getPredecessorBlock() = pred and operand.getUse().getBlock() = succ ) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticSSA.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticSSA.qll index 80e1d6c84a6..307f6e386b5 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticSSA.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticSSA.qll @@ -10,7 +10,7 @@ class SemSsaVariable instanceof Specific::SsaVariable { final Specific::Location getLocation() { result = super.getLocation() } - final SemLoadExpr getAUse() { result = Specific::getAUse(this) } + final SemExpr getAUse() { result = Specific::getAUse(this) } final SemType getType() { result = Specific::getSsaVariableType(this) }