diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index 9385d6730e4d..dbeefae48808 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -199,7 +199,27 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) { // Flow through pointer dereference i2.(LoadInstruction).getSourceAddress() = i1 or - i2.(UnaryInstruction).getUnary() = i1 + // Flow through partial reads of arrays and unions + i2.(LoadInstruction).getSourceValueOperand().getAnyDef() = i1 and + not i1.isResultConflated() and + ( + i1.getResultType() instanceof ArrayType or + i1.getResultType() instanceof Union + ) + or + // Unary instructions tend to preserve enough information in practice that we + // want taint to flow through. + // The exception is `FieldAddressInstruction`. Together with the rule for + // `LoadInstruction` above and for `ChiInstruction` below, flow through + // `FieldAddressInstruction` could cause flow into one field to come out an + // unrelated field. This would happen across function boundaries, where the IR + // would not be able to match loads to stores. + i2.(UnaryInstruction).getUnary() = i1 and + ( + not i2 instanceof FieldAddressInstruction + or + i2.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union + ) or // Flow out of definition-by-reference i2.(ChiInstruction).getPartial() = i1.(WriteSideEffectInstruction) and @@ -213,7 +233,7 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) { or t instanceof ArrayType or - // Buffers or unknown size + // Buffers of unknown size t instanceof UnknownType ) or diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll index abb62b9a021c..1dd1d9ac4cc1 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll @@ -70,8 +70,7 @@ private module VirtualDispatch { // Call return exists(DataFlowCall call, ReturnKind returnKind | other = getAnOutNode(call, returnKind) and - src.(ReturnNode).getKind() = returnKind and - call.getStaticCallTarget() = src.getEnclosingCallable() + returnNodeWithKindAndEnclosingCallable(src, returnKind, call.getStaticCallTarget()) ) and allowFromArg = false or @@ -125,6 +124,18 @@ private module VirtualDispatch { } } + /** + * A ReturnNode with its ReturnKind and its enclosing callable. + * + * Used to fix a join ordering issue in flowsFrom. + */ + private predicate returnNodeWithKindAndEnclosingCallable( + ReturnNode node, ReturnKind kind, DataFlowCallable callable + ) { + node.getKind() = kind and + node.getEnclosingCallable() = callable + } + /** Call through a function pointer. */ private class DataSensitiveExprCall extends DataSensitiveCall { DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 9aa19d577854..c5cf4180765b 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -24,7 +24,9 @@ class ArgumentNode extends InstructionNode { DataFlowCall getCall() { this.argumentOf(result, _) } } -private newtype TReturnKind = TNormalReturnKind() +private newtype TReturnKind = + TNormalReturnKind() or + TIndirectReturnKind(ParameterIndex index) /** * A return kind. A return kind describes how a value can be returned @@ -32,23 +34,76 @@ private newtype TReturnKind = TNormalReturnKind() */ class ReturnKind extends TReturnKind { /** Gets a textual representation of this return kind. */ - string toString() { result = "return" } + abstract string toString(); +} + +private class NormalReturnKind extends ReturnKind, TNormalReturnKind { + override string toString() { result = "return" } +} + +private class IndirectReturnKind extends ReturnKind, TIndirectReturnKind { + ParameterIndex index; + + IndirectReturnKind() { this = TIndirectReturnKind(index) } + + override string toString() { result = "outparam[" + index.toString() + "]" } } /** A data flow node that occurs as the result of a `ReturnStmt`. */ class ReturnNode extends InstructionNode { - ReturnNode() { exists(ReturnValueInstruction ret | this.getInstruction() = ret.getReturnValue()) } + Instruction primary; + + ReturnNode() { + exists(ReturnValueInstruction ret | instr = ret.getReturnValue() and primary = ret) + or + exists(ReturnIndirectionInstruction rii | + instr = rii.getSideEffectOperand().getAnyDef() and primary = rii + ) + } /** Gets the kind of this returned value. */ - ReturnKind getKind() { result = TNormalReturnKind() } + abstract ReturnKind getKind(); +} + +class ReturnValueNode extends ReturnNode { + override ReturnValueInstruction primary; + + override ReturnKind getKind() { result = TNormalReturnKind() } +} + +class ReturnIndirectionNode extends ReturnNode { + override ReturnIndirectionInstruction primary; + + override ReturnKind getKind() { result = TIndirectReturnKind(primary.getParameter().getIndex()) } } /** A data flow node that represents the output of a call. */ class OutNode extends InstructionNode { - override CallInstruction instr; + OutNode() { + instr instanceof CallInstruction or + instr instanceof WriteSideEffectInstruction + } /** Gets the underlying call. */ - DataFlowCall getCall() { result = instr } + abstract DataFlowCall getCall(); + + abstract ReturnKind getReturnKind(); +} + +private class CallOutNode extends OutNode { + override CallInstruction instr; + + override DataFlowCall getCall() { result = instr } + + override ReturnKind getReturnKind() { result instanceof NormalReturnKind } +} + +private class SideEffectOutNode extends OutNode { + override WriteSideEffectInstruction instr; + + override DataFlowCall getCall() { result = instr.getPrimaryInstruction() } + + override ReturnKind getReturnKind() { result = TIndirectReturnKind(instr.getIndex()) } } /** @@ -57,7 +112,7 @@ class OutNode extends InstructionNode { */ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { result.getCall() = call and - kind = TNormalReturnKind() + result.getReturnKind() = kind } /** 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 fc9d0758125f..38216872f2b8 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 @@ -525,7 +525,7 @@ class ReturnValueInstruction extends ReturnInstruction { final Instruction getReturnValue() { result = getReturnValueOperand().getDef() } } -class ReturnIndirectionInstruction extends Instruction { +class ReturnIndirectionInstruction extends VariableInstruction { ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection } final SideEffectOperand getSideEffectOperand() { result = getAnOperand() } @@ -535,6 +535,12 @@ class ReturnIndirectionInstruction extends Instruction { final AddressOperand getSourceAddressOperand() { result = getAnOperand() } final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() } + + /** + * Gets the parameter for which this instruction reads the final pointed-to value within the + * function. + */ + final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } } class CopyInstruction extends Instruction { 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 fc9d0758125f..38216872f2b8 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 @@ -525,7 +525,7 @@ class ReturnValueInstruction extends ReturnInstruction { final Instruction getReturnValue() { result = getReturnValueOperand().getDef() } } -class ReturnIndirectionInstruction extends Instruction { +class ReturnIndirectionInstruction extends VariableInstruction { ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection } final SideEffectOperand getSideEffectOperand() { result = getAnOperand() } @@ -535,6 +535,12 @@ class ReturnIndirectionInstruction extends Instruction { final AddressOperand getSourceAddressOperand() { result = getAnOperand() } final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() } + + /** + * Gets the parameter for which this instruction reads the final pointed-to value within the + * function. + */ + final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } } class CopyInstruction extends Instruction { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll index 1bfc1c8275f7..2c54fdf539a1 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll @@ -744,4 +744,9 @@ class TranslatedReadEffect extends TranslatedElement, TTranslatedReadEffect { operandTag = sideEffectOperand() and result = getUnknownType() } + + final override IRVariable getInstructionVariable(InstructionTag tag) { + tag = OnlyInstructionTag() and + result = getIRUserVariable(getFunction(), param) + } } 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 fc9d0758125f..38216872f2b8 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 @@ -525,7 +525,7 @@ class ReturnValueInstruction extends ReturnInstruction { final Instruction getReturnValue() { result = getReturnValueOperand().getDef() } } -class ReturnIndirectionInstruction extends Instruction { +class ReturnIndirectionInstruction extends VariableInstruction { ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection } final SideEffectOperand getSideEffectOperand() { result = getAnOperand() } @@ -535,6 +535,12 @@ class ReturnIndirectionInstruction extends Instruction { final AddressOperand getSourceAddressOperand() { result = getAnOperand() } final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() } + + /** + * Gets the parameter for which this instruction reads the final pointed-to value within the + * function. + */ + final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } } class CopyInstruction extends Instruction { diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp index 02ae1e07154f..25fbdba93c14 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp @@ -86,4 +86,14 @@ namespace std { void test_std_move() { sink(std::move(getenv("VAR"))); +} + +void flow_to_outparam(char ** ret, char *arg) { + *ret = arg; +} + +void test_outparams() { + char *p2 = nullptr; + flow_to_outparam(&p2, getenv("VAR")); + sink(p2); // tainted } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected index 99e970c9b400..4f98b1bead0c 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected @@ -101,6 +101,14 @@ | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:18:88:23 | call to getenv | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:18:88:30 | (reference to) | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:91:42:91:44 | arg | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:12:92:14 | arg | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:96:11:96:12 | p2 | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:97:27:97:32 | call to getenv | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | | globals.cpp:5:20:5:25 | call to getenv | globals.cpp:2:17:2:25 | sinkParam | | globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:12:5:16 | local | | globals.cpp:5:20:5:25 | call to getenv | globals.cpp:5:20:5:25 | call to getenv | diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected index 335cca91c33b..858965a069b4 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected @@ -15,6 +15,14 @@ | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:8:88:32 | (reference dereference) | IR only | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | defaulttainttracking.cpp:88:18:88:30 | (reference to) | IR only | | defaulttainttracking.cpp:88:18:88:23 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | IR only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | IR only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:91:31:91:33 | ret | AST only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:5:92:8 | * ... | AST only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:6:92:8 | ret | AST only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:96:11:96:12 | p2 | IR only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | IR only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only | +| defaulttainttracking.cpp:97:27:97:32 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | IR only | | globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only | | globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only | | test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index 6c445fb76c1b..666edf7a1779 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -460,3 +460,13 @@ void throughStmtExpr(int source1, int clean1) { }); sink(local); // tainted } + +void intOutparamSource(int *p) { + *p = source(); +} + +void viaOutparam() { + int x = 0; + intOutparamSource(&x); + sink(x); // tainted [FALSE NEGATIVE] +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index d74ce2920b0d..10ec2a63dc2d 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -79,7 +79,7 @@ bad_asts.cpp: # 27| r27_6(Point) = Load : &:r27_5, ~mu26_4 # 27| mu27_7(Point) = Store : &:r27_1, r27_6 # 28| v28_1(void) = NoOp : -# 26| v26_9(void) = ReturnIndirection : &:r26_7, ~mu26_4 +# 26| v26_9(void) = ReturnIndirection[a] : &:r26_7, ~mu26_4 # 26| v26_10(void) = ReturnVoid : # 26| v26_11(void) = UnmodeledUse : mu* # 26| v26_12(void) = AliasedUse : ~mu26_4 @@ -836,7 +836,7 @@ ir.cpp: # 168| r168_6(glval) = VariableAddress[b] : # 168| mu168_7(bool) = Store : &:r168_6, r168_5 # 169| v169_1(void) = NoOp : -# 153| v153_11(void) = ReturnIndirection : &:r153_7, ~mu153_4 +# 153| v153_11(void) = ReturnIndirection[p] : &:r153_7, ~mu153_4 # 153| v153_12(void) = ReturnVoid : # 153| v153_13(void) = UnmodeledUse : mu* # 153| v153_14(void) = AliasedUse : ~mu153_4 @@ -923,7 +923,7 @@ ir.cpp: # 184| r184_7(glval) = PointerAdd[4] : r184_4, r184_6 # 184| mu184_8(int) = Store : &:r184_7, r184_2 # 185| v185_1(void) = NoOp : -# 171| v171_11(void) = ReturnIndirection : &:r171_7, ~mu171_4 +# 171| v171_11(void) = ReturnIndirection[p] : &:r171_7, ~mu171_4 # 171| v171_12(void) = ReturnVoid : # 171| v171_13(void) = UnmodeledUse : mu* # 171| v171_14(void) = AliasedUse : ~mu171_4 @@ -1023,8 +1023,8 @@ ir.cpp: # 201| r201_6(glval) = VariableAddress[b] : # 201| mu201_7(bool) = Store : &:r201_6, r201_5 # 202| v202_1(void) = NoOp : -# 193| v193_13(void) = ReturnIndirection : &:r193_7, ~mu193_4 -# 193| v193_14(void) = ReturnIndirection : &:r193_11, ~mu193_4 +# 193| v193_13(void) = ReturnIndirection[p] : &:r193_7, ~mu193_4 +# 193| v193_14(void) = ReturnIndirection[q] : &:r193_11, ~mu193_4 # 193| v193_15(void) = ReturnVoid : # 193| v193_16(void) = UnmodeledUse : mu* # 193| v193_17(void) = AliasedUse : ~mu193_4 @@ -1073,7 +1073,7 @@ ir.cpp: # 210| r210_7(glval) = VariableAddress[q] : # 210| mu210_8(int *) = Store : &:r210_7, r210_6 # 211| v211_1(void) = NoOp : -# 204| v204_9(void) = ReturnIndirection : &:r204_7, ~mu204_4 +# 204| v204_9(void) = ReturnIndirection[p] : &:r204_7, ~mu204_4 # 204| v204_10(void) = ReturnVoid : # 204| v204_11(void) = UnmodeledUse : mu* # 204| v204_12(void) = AliasedUse : ~mu204_4 @@ -1684,7 +1684,7 @@ ir.cpp: # 343| r343_3(int *) = Load : &:r343_2, ~mu341_4 # 343| r343_4(int) = Load : &:r343_3, ~mu341_4 # 343| mu343_5(int) = Store : &:r343_1, r343_4 -# 341| v341_9(void) = ReturnIndirection : &:r341_7, ~mu341_4 +# 341| v341_9(void) = ReturnIndirection[p] : &:r341_7, ~mu341_4 # 341| r341_10(glval) = VariableAddress[#return] : # 341| v341_11(void) = ReturnValue : &:r341_10, ~mu341_4 # 341| v341_12(void) = UnmodeledUse : mu* @@ -2984,8 +2984,8 @@ ir.cpp: # 625| v625_6(void) = ^BufferReadSideEffect[-1] : &:r625_2, ~mu622_4 # 625| mu625_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r625_2 # 626| v626_1(void) = NoOp : -# 622| v622_15(void) = ReturnIndirection : &:r622_7, ~mu622_4 -# 622| v622_16(void) = ReturnIndirection : &:r622_11, ~mu622_4 +# 622| v622_15(void) = ReturnIndirection[r] : &:r622_7, ~mu622_4 +# 622| v622_16(void) = ReturnIndirection[p] : &:r622_11, ~mu622_4 # 622| v622_17(void) = ReturnVoid : # 622| v622_18(void) = UnmodeledUse : mu* # 622| v622_19(void) = AliasedUse : ~mu622_4 @@ -3198,7 +3198,7 @@ ir.cpp: # 676| r676_3(int &) = Load : &:r676_2, ~mu675_4 # 676| r676_4(int) = Load : &:r676_3, ~mu675_4 # 676| mu676_5(int) = Store : &:r676_1, r676_4 -# 675| v675_9(void) = ReturnIndirection : &:r675_7, ~mu675_4 +# 675| v675_9(void) = ReturnIndirection[r] : &:r675_7, ~mu675_4 # 675| r675_10(glval) = VariableAddress[#return] : # 675| v675_11(void) = ReturnValue : &:r675_10, ~mu675_4 # 675| v675_12(void) = UnmodeledUse : mu* @@ -3391,7 +3391,7 @@ ir.cpp: # 716| r716_1(glval) = VariableAddress[#return] : # 716| r716_2(long) = Constant[0] : # 716| mu716_3(long) = Store : &:r716_1, r716_2 -# 715| v715_11(void) = ReturnIndirection : &:r715_7, ~mu715_4 +# 715| v715_11(void) = ReturnIndirection[x] : &:r715_7, ~mu715_4 # 715| r715_12(glval) = VariableAddress[#return] : # 715| v715_13(void) = ReturnValue : &:r715_12, ~mu715_4 # 715| v715_14(void) = UnmodeledUse : mu* @@ -3578,7 +3578,7 @@ ir.cpp: #-----| r0_20(glval) = CopyValue : r0_19 #-----| r0_21(Base &) = CopyValue : r0_20 #-----| mu0_22(Base &) = Store : &:r0_18, r0_21 -#-----| v0_23(void) = ReturnIndirection : &:r0_3, ~mu745_4 +#-----| v0_23(void) = ReturnIndirection[p#0] : &:r0_3, ~mu745_4 # 745| r745_9(glval) = VariableAddress[#return] : # 745| v745_10(void) = ReturnValue : &:r745_9, ~mu745_4 # 745| v745_11(void) = UnmodeledUse : mu* @@ -3602,7 +3602,7 @@ ir.cpp: # 745| mu745_9(unknown) = ^CallSideEffect : ~mu745_4 # 745| mu745_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r745_6 # 745| v745_11(void) = NoOp : -#-----| v0_5(void) = ReturnIndirection : &:r0_3, ~mu745_4 +#-----| v0_5(void) = ReturnIndirection[p#0] : &:r0_3, ~mu745_4 # 745| v745_12(void) = ReturnVoid : # 745| v745_13(void) = UnmodeledUse : mu* # 745| v745_14(void) = AliasedUse : ~mu745_4 @@ -3692,7 +3692,7 @@ ir.cpp: #-----| r0_34(glval) = CopyValue : r0_33 #-----| r0_35(Middle &) = CopyValue : r0_34 #-----| mu0_36(Middle &) = Store : &:r0_32, r0_35 -#-----| v0_37(void) = ReturnIndirection : &:r0_3, ~mu754_4 +#-----| v0_37(void) = ReturnIndirection[p#0] : &:r0_3, ~mu754_4 # 754| r754_12(glval) = VariableAddress[#return] : # 754| v754_13(void) = ReturnValue : &:r754_12, ~mu754_4 # 754| v754_14(void) = UnmodeledUse : mu* @@ -3792,7 +3792,7 @@ ir.cpp: #-----| r0_34(glval) = CopyValue : r0_33 #-----| r0_35(Derived &) = CopyValue : r0_34 #-----| mu0_36(Derived &) = Store : &:r0_32, r0_35 -#-----| v0_37(void) = ReturnIndirection : &:r0_3, ~mu763_4 +#-----| v0_37(void) = ReturnIndirection[p#0] : &:r0_3, ~mu763_4 # 763| r763_12(glval) = VariableAddress[#return] : # 763| v763_13(void) = ReturnValue : &:r763_12, ~mu763_4 # 763| v763_14(void) = UnmodeledUse : mu* @@ -4496,7 +4496,7 @@ ir.cpp: # 885| r885_4(glval<..(*)(..)>) = VariableAddress[pfn] : # 885| mu885_5(..(*)(..)) = Store : &:r885_4, r885_3 # 886| v886_1(void) = NoOp : -# 883| v883_11(void) = ReturnIndirection : &:r883_9, ~mu883_4 +# 883| v883_11(void) = ReturnIndirection[p] : &:r883_9, ~mu883_4 # 883| v883_12(void) = ReturnVoid : # 883| v883_13(void) = UnmodeledUse : mu* # 883| v883_14(void) = AliasedUse : ~mu883_4 @@ -4545,7 +4545,7 @@ ir.cpp: # 893| r893_2(__va_list_tag *) = Convert : r893_1 # 893| v893_3(void) = VarArgsEnd : r893_2 # 894| v894_1(void) = NoOp : -# 888| v888_11(void) = ReturnIndirection : &:r888_9, ~mu888_4 +# 888| v888_11(void) = ReturnIndirection[args] : &:r888_9, ~mu888_4 # 888| v888_12(void) = ReturnVoid : # 888| v888_13(void) = UnmodeledUse : mu* # 888| v888_14(void) = AliasedUse : ~mu888_4 @@ -5065,7 +5065,7 @@ ir.cpp: # 997| mu997_11(unknown) = ^CallSideEffect : ~mu996_4 # 997| r997_12(int) = Add : r997_6, r997_10 # 997| mu997_13(int) = Store : &:r997_1, r997_12 -# 996| v996_11(void) = ReturnIndirection : &:r996_7, ~mu996_4 +# 996| v996_11(void) = ReturnIndirection[a] : &:r996_7, ~mu996_4 # 996| r996_12(glval) = VariableAddress[#return] : # 996| v996_13(void) = ReturnValue : &:r996_12, ~mu996_4 # 996| v996_14(void) = UnmodeledUse : mu* @@ -5375,7 +5375,7 @@ ir.cpp: # 1055| v1055_7(void) = ^BufferReadSideEffect[-1] : &:r1055_2, ~mu1040_4 # 1055| mu1055_8(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r1055_2 # 1056| v1056_1(void) = NoOp : -# 1040| v1040_11(void) = ReturnIndirection : &:r1040_9, ~mu1040_4 +# 1040| v1040_11(void) = ReturnIndirection[s] : &:r1040_9, ~mu1040_4 # 1040| v1040_12(void) = ReturnVoid : # 1040| v1040_13(void) = UnmodeledUse : mu* # 1040| v1040_14(void) = AliasedUse : ~mu1040_4 @@ -5726,13 +5726,13 @@ ir.cpp: #-----| Goto -> Block 5 # 1088| Block 5 -# 1088| v1088_1(void) = NoOp : -# 1089| v1089_1(void) = NoOp : -# 1077| v1077_9(void) = ReturnIndirection : &:r1077_7, ~mu1077_4 -# 1077| v1077_10(void) = ReturnVoid : -# 1077| v1077_11(void) = UnmodeledUse : mu* -# 1077| v1077_12(void) = AliasedUse : ~mu1077_4 -# 1077| v1077_13(void) = ExitFunction : +# 1088| v1088_1(void) = NoOp : +# 1089| v1089_1(void) = NoOp : +# 1077| v1077_9(void) = ReturnIndirection[v] : &:r1077_7, ~mu1077_4 +# 1077| v1077_10(void) = ReturnVoid : +# 1077| v1077_11(void) = UnmodeledUse : mu* +# 1077| v1077_12(void) = AliasedUse : ~mu1077_4 +# 1077| v1077_13(void) = ExitFunction : #-----| Block 6 #-----| r0_24(glval) = VariableAddress[(__begin)] : @@ -5859,8 +5859,8 @@ ir.cpp: # 1118| r1118_9(unsigned int) = Load : &:r1118_8, ~mu1113_4 # 1115| mu1115_1(unknown) = InlineAsm : ~mu1113_4, 0:r1118_3, 1:r1118_4, 2:r1118_7, 3:r1118_9 # 1120| v1120_1(void) = NoOp : -# 1113| v1113_17(void) = ReturnIndirection : &:r1113_7, ~mu1113_4 -# 1113| v1113_18(void) = ReturnIndirection : &:r1113_13, ~mu1113_4 +# 1113| v1113_17(void) = ReturnIndirection[a] : &:r1113_7, ~mu1113_4 +# 1113| v1113_18(void) = ReturnIndirection[c] : &:r1113_13, ~mu1113_4 # 1113| v1113_19(void) = ReturnVoid : # 1113| v1113_20(void) = UnmodeledUse : mu* # 1113| v1113_21(void) = AliasedUse : ~mu1113_4 @@ -6436,12 +6436,12 @@ ir.cpp: #-----| Goto -> Block 5 # 1244| Block 5 -# 1244| v1244_1(void) = NoOp : -# 1240| v1240_9(void) = ReturnIndirection : &:r1240_7, ~mu1240_4 -# 1240| v1240_10(void) = ReturnVoid : -# 1240| v1240_11(void) = UnmodeledUse : mu* -# 1240| v1240_12(void) = AliasedUse : ~mu1240_4 -# 1240| v1240_13(void) = ExitFunction : +# 1244| v1244_1(void) = NoOp : +# 1240| v1240_9(void) = ReturnIndirection[dynamic] : &:r1240_7, ~mu1240_4 +# 1240| v1240_10(void) = ReturnVoid : +# 1240| v1240_11(void) = UnmodeledUse : mu* +# 1240| v1240_12(void) = AliasedUse : ~mu1240_4 +# 1240| v1240_13(void) = ExitFunction : # 1241| Block 6 # 1241| r1241_4(glval) = VariableAddress[a] : @@ -6497,8 +6497,8 @@ ir.cpp: # 1255| v1255_9(void) = ^BufferReadSideEffect[1] : &:r1255_6, ~mu1251_4 # 1255| mu1255_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r1255_3 # 1256| v1256_1(void) = NoOp : -# 1251| v1251_13(void) = ReturnIndirection : &:r1251_7, ~mu1251_4 -# 1251| v1251_14(void) = ReturnIndirection : &:r1251_11, ~mu1251_4 +# 1251| v1251_13(void) = ReturnIndirection[s1] : &:r1251_7, ~mu1251_4 +# 1251| v1251_14(void) = ReturnIndirection[s2] : &:r1251_11, ~mu1251_4 # 1251| v1251_15(void) = ReturnVoid : # 1251| v1251_16(void) = UnmodeledUse : mu* # 1251| v1251_17(void) = AliasedUse : ~mu1251_4 @@ -6523,7 +6523,7 @@ ir.cpp: # 1262| r1262_5(glval) = FieldAddress[member] : r1262_4 # 1262| mu1262_6(int) = Store : &:r1262_5, r1262_2 # 1263| v1263_1(void) = NoOp : -# 1261| v1261_11(void) = ReturnIndirection : &:r1261_7, ~mu1261_4 +# 1261| v1261_11(void) = ReturnIndirection[a] : &:r1261_7, ~mu1261_4 # 1261| v1261_12(void) = ReturnVoid : # 1261| v1261_13(void) = UnmodeledUse : mu* # 1261| v1261_14(void) = AliasedUse : ~mu1261_4 @@ -6625,7 +6625,7 @@ ir.cpp: # 1286| v1286_5(void) = Call : func:r1286_4 # 1286| mu1286_6(unknown) = ^CallSideEffect : ~mu1270_4 # 1287| v1287_1(void) = NoOp : -# 1270| v1270_11(void) = ReturnIndirection : &:r1270_9, ~mu1270_4 +# 1270| v1270_11(void) = ReturnIndirection[a_arg] : &:r1270_9, ~mu1270_4 # 1270| v1270_12(void) = ReturnVoid : # 1270| v1270_13(void) = UnmodeledUse : mu* # 1270| v1270_14(void) = AliasedUse : ~mu1270_4 @@ -6693,7 +6693,7 @@ struct_init.cpp: # 17| r17_3(glval) = VariableAddress[global_pointer] : # 17| mu17_4(Info *) = Store : &:r17_3, r17_2 # 18| v18_1(void) = NoOp : -# 16| v16_9(void) = ReturnIndirection : &:r16_7, ~mu16_4 +# 16| v16_9(void) = ReturnIndirection[info] : &:r16_7, ~mu16_4 # 16| v16_10(void) = ReturnVoid : # 16| v16_11(void) = UnmodeledUse : mu* # 16| v16_12(void) = AliasedUse : ~mu16_4 @@ -6783,7 +6783,7 @@ struct_init.cpp: # 41| v41_6(void) = ^BufferReadSideEffect[0] : &:r41_3, ~mu36_4 # 41| mu41_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r41_3 # 42| v42_1(void) = NoOp : -# 36| v36_9(void) = ReturnIndirection : &:r36_7, ~mu36_4 +# 36| v36_9(void) = ReturnIndirection[name1] : &:r36_7, ~mu36_4 # 36| v36_10(void) = ReturnVoid : # 36| v36_11(void) = UnmodeledUse : mu* # 36| v36_12(void) = AliasedUse : ~mu36_4 diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index 2f69b579c302..8fdffc0569a0 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -89,7 +89,7 @@ ssa.cpp: # 28| r28_12(int) = Load : &:r28_11, m28_1 # 28| r28_13(int) = Add : r28_8, r28_12 # 28| m28_14(int) = Store : &:r28_4, r28_13 -# 13| v13_14(void) = ReturnIndirection : &:r13_8, m28_3 +# 13| v13_14(void) = ReturnIndirection[p] : &:r13_8, m28_3 # 13| r13_15(glval) = VariableAddress[#return] : # 13| v13_16(void) = ReturnValue : &:r13_15, m28_14 # 13| v13_17(void) = UnmodeledUse : mu* @@ -257,12 +257,12 @@ ssa.cpp: #-----| Goto (back edge) -> Block 1 # 71| Block 3 -# 71| v71_1(void) = NoOp : -# 68| v68_12(void) = ReturnIndirection : &:r68_10, m68_11 -# 68| v68_13(void) = ReturnVoid : -# 68| v68_14(void) = UnmodeledUse : mu* -# 68| v68_15(void) = AliasedUse : ~m69_3 -# 68| v68_16(void) = ExitFunction : +# 71| v71_1(void) = NoOp : +# 68| v68_12(void) = ReturnIndirection[p] : &:r68_10, m68_11 +# 68| v68_13(void) = ReturnVoid : +# 68| v68_14(void) = UnmodeledUse : mu* +# 68| v68_15(void) = AliasedUse : ~m69_3 +# 68| v68_16(void) = ExitFunction : # 75| void ScalarPhi(bool) # 75| Block 0 @@ -806,7 +806,7 @@ ssa.cpp: # 181| r181_3(int *) = Load : &:r181_2, m179_7 # 181| r181_4(int) = Load : &:r181_3, ~m179_9 # 181| m181_5(int) = Store : &:r181_1, r181_4 -# 179| v179_10(void) = ReturnIndirection : &:r179_8, m179_9 +# 179| v179_10(void) = ReturnIndirection[p] : &:r179_8, m179_9 # 179| r179_11(glval) = VariableAddress[#return] : # 179| v179_12(void) = ReturnValue : &:r179_11, m181_5 # 179| v179_13(void) = UnmodeledUse : mu* @@ -853,10 +853,10 @@ ssa.cpp: # 186| m186_1(unknown) = InlineAsm : ~m184_15, 0:r189_3, 1:r189_6, 2:r190_3, 3:r190_6 # 186| m186_2(unknown) = Chi : total:m184_15, partial:m186_1 # 192| v192_1(void) = NoOp : -# 184| v184_24(void) = ReturnIndirection : &:r184_8, ~m186_2 -# 184| v184_25(void) = ReturnIndirection : &:r184_13, ~m186_2 -# 184| v184_26(void) = ReturnIndirection : &:r184_18, m184_19 -# 184| v184_27(void) = ReturnIndirection : &:r184_22, m184_23 +# 184| v184_24(void) = ReturnIndirection[a] : &:r184_8, ~m186_2 +# 184| v184_25(void) = ReturnIndirection[b] : &:r184_13, ~m186_2 +# 184| v184_26(void) = ReturnIndirection[c] : &:r184_18, m184_19 +# 184| v184_27(void) = ReturnIndirection[d] : &:r184_22, m184_23 # 184| v184_28(void) = ReturnVoid : # 184| v184_29(void) = UnmodeledUse : mu* # 184| v184_30(void) = AliasedUse : ~m186_2 @@ -913,8 +913,8 @@ ssa.cpp: # 202| r202_2(glval) = VariableAddress[ret] : # 202| r202_3(int) = Load : &:r202_2, m201_8 # 202| m202_4(int) = Store : &:r202_1, r202_3 -# 198| v198_16(void) = ReturnIndirection : &:r198_8, m198_9 -# 198| v198_17(void) = ReturnIndirection : &:r198_12, m198_13 +# 198| v198_16(void) = ReturnIndirection[str1] : &:r198_8, m198_9 +# 198| v198_17(void) = ReturnIndirection[str2] : &:r198_12, m198_13 # 198| r198_18(glval) = VariableAddress[#return] : # 198| v198_19(void) = ReturnValue : &:r198_18, m202_4 # 198| v198_20(void) = UnmodeledUse : mu* @@ -1189,7 +1189,7 @@ ssa.cpp: # 251| r251_2(glval) = VariableAddress[dst] : # 251| r251_3(char *) = Load : &:r251_2, m248_14 # 251| m251_4(char *) = Store : &:r251_1, r251_3 -# 247| v247_13(void) = ReturnIndirection : &:r247_8, ~m250_13 +# 247| v247_13(void) = ReturnIndirection[src] : &:r247_8, ~m250_13 # 247| r247_14(glval) = VariableAddress[#return] : # 247| v247_15(void) = ReturnValue : &:r247_14, m251_4 # 247| v247_16(void) = UnmodeledUse : mu* @@ -1283,7 +1283,7 @@ ssa.cpp: # 271| r271_2(glval) = VariableAddress[buf] : # 271| r271_3(void *) = Load : &:r271_2, m269_10 # 271| m271_4(void *) = Store : &:r271_1, r271_3 -# 268| v268_13(void) = ReturnIndirection : &:r268_8, ~m270_11 +# 268| v268_13(void) = ReturnIndirection[s] : &:r268_8, ~m270_11 # 268| r268_14(glval) = VariableAddress[#return] : # 268| v268_15(void) = ReturnValue : &:r268_14, m271_4 # 268| v268_16(void) = UnmodeledUse : mu* @@ -1377,7 +1377,7 @@ ssa.cpp: # 287| r287_9(A *) = Load : &:r287_7, m287_8 # 287| m287_10(unknown) = InitializeIndirection[p#0] : &:r287_9 # 287| v287_11(void) = NoOp : -# 287| v287_12(void) = ReturnIndirection : &:r287_9, m287_10 +# 287| v287_12(void) = ReturnIndirection[p#0] : &:r287_9, m287_10 # 287| v287_13(void) = ReturnVoid : # 287| v287_14(void) = UnmodeledUse : mu* # 287| v287_15(void) = AliasedUse : m287_3 @@ -1483,3 +1483,53 @@ ssa.cpp: # 291| v291_10(void) = UnmodeledUse : mu* # 291| v291_11(void) = AliasedUse : ~m295_12 # 291| v291_12(void) = ExitFunction : + +# 301| int main(int, char**) +# 301| Block 0 +# 301| v301_1(void) = EnterFunction : +# 301| m301_2(unknown) = AliasedDefinition : +# 301| m301_3(unknown) = InitializeNonLocal : +# 301| m301_4(unknown) = Chi : total:m301_2, partial:m301_3 +# 301| mu301_5(unknown) = UnmodeledDefinition : +# 301| r301_6(glval) = VariableAddress[argc] : +# 301| m301_7(int) = InitializeParameter[argc] : &:r301_6 +# 301| r301_8(glval) = VariableAddress[argv] : +# 301| m301_9(char **) = InitializeParameter[argv] : &:r301_8 +# 301| r301_10(char **) = Load : &:r301_8, m301_9 +# 301| m301_11(unknown) = InitializeIndirection[argv] : &:r301_10 +# 301| m301_12(unknown) = Chi : total:m301_4, partial:m301_11 +# 302| r302_1(glval) = FunctionAddress[unknownFunction] : +# 302| r302_2(glval) = VariableAddress[argc] : +# 302| r302_3(int) = Load : &:r302_2, m301_7 +# 302| r302_4(glval) = VariableAddress[argv] : +# 302| r302_5(char **) = Load : &:r302_4, m301_9 +# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5 +# 302| m302_7(unknown) = ^CallSideEffect : ~m301_12 +# 302| m302_8(unknown) = Chi : total:m301_12, partial:m302_7 +# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m302_8 +# 302| m302_10(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5 +# 302| m302_11(unknown) = Chi : total:m302_8, partial:m302_10 +# 303| r303_1(glval) = FunctionAddress[unknownFunction] : +# 303| r303_2(glval) = VariableAddress[argc] : +# 303| r303_3(int) = Load : &:r303_2, m301_7 +# 303| r303_4(glval) = VariableAddress[argv] : +# 303| r303_5(char **) = Load : &:r303_4, m301_9 +# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5 +# 303| m303_7(unknown) = ^CallSideEffect : ~m302_11 +# 303| m303_8(unknown) = Chi : total:m302_11, partial:m303_7 +# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m303_8 +# 303| m303_10(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5 +# 303| m303_11(unknown) = Chi : total:m303_8, partial:m303_10 +# 304| r304_1(glval) = VariableAddress[#return] : +# 304| r304_2(glval) = VariableAddress[argv] : +# 304| r304_3(char **) = Load : &:r304_2, m301_9 +# 304| r304_4(char *) = Load : &:r304_3, ~m303_11 +# 304| r304_5(char) = Load : &:r304_4, ~m303_11 +# 304| r304_6(int) = Convert : r304_5 +# 304| m304_7(int) = Store : &:r304_1, r304_6 +# 301| v301_13(void) = ReturnIndirection[argv] : &:r301_10, ~m303_11 +# 301| r301_14(glval) = VariableAddress[#return] : +# 301| v301_15(void) = ReturnValue : &:r301_14, m304_7 +# 301| v301_16(void) = UnmodeledUse : mu* +# 301| v301_17(void) = AliasedUse : ~m303_11 +# 301| v301_18(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index e71995247cc0..01af278d8d9d 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -89,7 +89,7 @@ ssa.cpp: # 28| r28_12(int) = Load : &:r28_11, m28_1 # 28| r28_13(int) = Add : r28_8, r28_12 # 28| m28_14(int) = Store : &:r28_4, r28_13 -# 13| v13_14(void) = ReturnIndirection : &:r13_8, m28_3 +# 13| v13_14(void) = ReturnIndirection[p] : &:r13_8, m28_3 # 13| r13_15(glval) = VariableAddress[#return] : # 13| v13_16(void) = ReturnValue : &:r13_15, m28_14 # 13| v13_17(void) = UnmodeledUse : mu* @@ -257,12 +257,12 @@ ssa.cpp: #-----| Goto (back edge) -> Block 1 # 71| Block 3 -# 71| v71_1(void) = NoOp : -# 68| v68_12(void) = ReturnIndirection : &:r68_10, m68_11 -# 68| v68_13(void) = ReturnVoid : -# 68| v68_14(void) = UnmodeledUse : mu* -# 68| v68_15(void) = AliasedUse : ~m69_3 -# 68| v68_16(void) = ExitFunction : +# 71| v71_1(void) = NoOp : +# 68| v68_12(void) = ReturnIndirection[p] : &:r68_10, m68_11 +# 68| v68_13(void) = ReturnVoid : +# 68| v68_14(void) = UnmodeledUse : mu* +# 68| v68_15(void) = AliasedUse : ~m69_3 +# 68| v68_16(void) = ExitFunction : # 75| void ScalarPhi(bool) # 75| Block 0 @@ -803,7 +803,7 @@ ssa.cpp: # 181| r181_3(int *) = Load : &:r181_2, m179_7 # 181| r181_4(int) = Load : &:r181_3, ~m179_9 # 181| m181_5(int) = Store : &:r181_1, r181_4 -# 179| v179_10(void) = ReturnIndirection : &:r179_8, m179_9 +# 179| v179_10(void) = ReturnIndirection[p] : &:r179_8, m179_9 # 179| r179_11(glval) = VariableAddress[#return] : # 179| v179_12(void) = ReturnValue : &:r179_11, m181_5 # 179| v179_13(void) = UnmodeledUse : mu* @@ -848,10 +848,10 @@ ssa.cpp: # 186| m186_1(unknown) = InlineAsm : ~m184_4, 0:r189_3, 1:r189_6, 2:r190_3, 3:r190_6 # 186| m186_2(unknown) = Chi : total:m184_4, partial:m186_1 # 192| v192_1(void) = NoOp : -# 184| v184_22(void) = ReturnIndirection : &:r184_8, m184_9 -# 184| v184_23(void) = ReturnIndirection : &:r184_12, m184_13 -# 184| v184_24(void) = ReturnIndirection : &:r184_16, m184_17 -# 184| v184_25(void) = ReturnIndirection : &:r184_20, m184_21 +# 184| v184_22(void) = ReturnIndirection[a] : &:r184_8, m184_9 +# 184| v184_23(void) = ReturnIndirection[b] : &:r184_12, m184_13 +# 184| v184_24(void) = ReturnIndirection[c] : &:r184_16, m184_17 +# 184| v184_25(void) = ReturnIndirection[d] : &:r184_20, m184_21 # 184| v184_26(void) = ReturnVoid : # 184| v184_27(void) = UnmodeledUse : mu* # 184| v184_28(void) = AliasedUse : ~m186_2 @@ -908,8 +908,8 @@ ssa.cpp: # 202| r202_2(glval) = VariableAddress[ret] : # 202| r202_3(int) = Load : &:r202_2, m201_8 # 202| m202_4(int) = Store : &:r202_1, r202_3 -# 198| v198_16(void) = ReturnIndirection : &:r198_8, m198_9 -# 198| v198_17(void) = ReturnIndirection : &:r198_12, m198_13 +# 198| v198_16(void) = ReturnIndirection[str1] : &:r198_8, m198_9 +# 198| v198_17(void) = ReturnIndirection[str2] : &:r198_12, m198_13 # 198| r198_18(glval) = VariableAddress[#return] : # 198| v198_19(void) = ReturnValue : &:r198_18, m202_4 # 198| v198_20(void) = UnmodeledUse : mu* @@ -1180,7 +1180,7 @@ ssa.cpp: # 251| r251_2(glval) = VariableAddress[dst] : # 251| r251_3(char *) = Load : &:r251_2, m248_13 # 251| m251_4(char *) = Store : &:r251_1, r251_3 -# 247| v247_12(void) = ReturnIndirection : &:r247_8, m249_6 +# 247| v247_12(void) = ReturnIndirection[src] : &:r247_8, m249_6 # 247| r247_13(glval) = VariableAddress[#return] : # 247| v247_14(void) = ReturnValue : &:r247_13, m251_4 # 247| v247_15(void) = UnmodeledUse : mu* @@ -1272,7 +1272,7 @@ ssa.cpp: # 271| r271_2(glval) = VariableAddress[buf] : # 271| r271_3(void *) = Load : &:r271_2, m269_9 # 271| m271_4(void *) = Store : &:r271_1, r271_3 -# 268| v268_12(void) = ReturnIndirection : &:r268_8, m268_9 +# 268| v268_12(void) = ReturnIndirection[s] : &:r268_8, m268_9 # 268| r268_13(glval) = VariableAddress[#return] : # 268| v268_14(void) = ReturnValue : &:r268_13, m271_4 # 268| v268_15(void) = UnmodeledUse : mu* @@ -1365,7 +1365,7 @@ ssa.cpp: # 287| r287_9(A *) = Load : &:r287_7, m287_8 # 287| m287_10(unknown) = InitializeIndirection[p#0] : &:r287_9 # 287| v287_11(void) = NoOp : -# 287| v287_12(void) = ReturnIndirection : &:r287_9, m287_10 +# 287| v287_12(void) = ReturnIndirection[p#0] : &:r287_9, m287_10 # 287| v287_13(void) = ReturnVoid : # 287| v287_14(void) = UnmodeledUse : mu* # 287| v287_15(void) = AliasedUse : m287_3 @@ -1471,3 +1471,52 @@ ssa.cpp: # 291| v291_10(void) = UnmodeledUse : mu* # 291| v291_11(void) = AliasedUse : ~m295_12 # 291| v291_12(void) = ExitFunction : + +# 301| int main(int, char**) +# 301| Block 0 +# 301| v301_1(void) = EnterFunction : +# 301| m301_2(unknown) = AliasedDefinition : +# 301| m301_3(unknown) = InitializeNonLocal : +# 301| m301_4(unknown) = Chi : total:m301_2, partial:m301_3 +# 301| mu301_5(unknown) = UnmodeledDefinition : +# 301| r301_6(glval) = VariableAddress[argc] : +# 301| m301_7(int) = InitializeParameter[argc] : &:r301_6 +# 301| r301_8(glval) = VariableAddress[argv] : +# 301| m301_9(char **) = InitializeParameter[argv] : &:r301_8 +# 301| r301_10(char **) = Load : &:r301_8, m301_9 +# 301| m301_11(unknown) = InitializeIndirection[argv] : &:r301_10 +# 302| r302_1(glval) = FunctionAddress[unknownFunction] : +# 302| r302_2(glval) = VariableAddress[argc] : +# 302| r302_3(int) = Load : &:r302_2, m301_7 +# 302| r302_4(glval) = VariableAddress[argv] : +# 302| r302_5(char **) = Load : &:r302_4, m301_9 +# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5 +# 302| m302_7(unknown) = ^CallSideEffect : ~m301_4 +# 302| m302_8(unknown) = Chi : total:m301_4, partial:m302_7 +# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m301_11 +# 302| m302_10(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5 +# 302| m302_11(char *) = Chi : total:m301_11, partial:m302_10 +# 303| r303_1(glval) = FunctionAddress[unknownFunction] : +# 303| r303_2(glval) = VariableAddress[argc] : +# 303| r303_3(int) = Load : &:r303_2, m301_7 +# 303| r303_4(glval) = VariableAddress[argv] : +# 303| r303_5(char **) = Load : &:r303_4, m301_9 +# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5 +# 303| m303_7(unknown) = ^CallSideEffect : ~m302_8 +# 303| m303_8(unknown) = Chi : total:m302_8, partial:m303_7 +# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m302_11 +# 303| m303_10(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5 +# 303| m303_11(char *) = Chi : total:m302_11, partial:m303_10 +# 304| r304_1(glval) = VariableAddress[#return] : +# 304| r304_2(glval) = VariableAddress[argv] : +# 304| r304_3(char **) = Load : &:r304_2, m301_9 +# 304| r304_4(char *) = Load : &:r304_3, ~m303_11 +# 304| r304_5(char) = Load : &:r304_4, ~m303_8 +# 304| r304_6(int) = Convert : r304_5 +# 304| m304_7(int) = Store : &:r304_1, r304_6 +# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, ~m303_11, m303_11 +# 301| r301_13(glval) = VariableAddress[#return] : +# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7 +# 301| v301_15(void) = UnmodeledUse : mu* +# 301| v301_16(void) = AliasedUse : ~m303_8 +# 301| v301_17(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity_unsound.expected index 1e78ae87f40f..89002a5d3ca5 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity_unsound.expected @@ -1,6 +1,7 @@ missingOperand unexpectedOperand duplicateOperand +| ssa.cpp:301:27:301:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) | missingPhiOperand missingOperandType duplicateChiOperand @@ -19,6 +20,7 @@ switchInstructionWithoutDefaultEdge notMarkedAsConflated wronglyMarkedAsConflated invalidOverlap +| ssa.cpp:301:27:301:30 | SideEffect | MemoryOperand 'SideEffect' has a `getDefinitionOverlap()` of 'MayPartiallyOverlap'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) | missingCanonicalLanguageType multipleCanonicalLanguageTypes missingIRType diff --git a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp index 6c5fd5eaf871..5ea3ef77968d 100644 --- a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp +++ b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp @@ -294,4 +294,12 @@ Point *NewAliasing(int x) { int j = new A(new A(x))->i; A* a = new A; return p; +} + +void unknownFunction(int argc, char **argv); + +int main(int argc, char **argv) { + unknownFunction(argc, argv); + unknownFunction(argc, argv); + return **argv; // Chi chain goes through side effects from unknownFunction } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 1e6551dd15a5..b307db1cfc58 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -78,7 +78,7 @@ ssa.cpp: # 28| r28_9(int) = Load : &:r28_8, ~mu13_4 # 28| r28_10(int) = Add : r28_5, r28_9 # 28| m28_11(int) = Store : &:r28_1, r28_10 -# 13| v13_13(void) = ReturnIndirection : &:r13_7, ~mu13_4 +# 13| v13_13(void) = ReturnIndirection[p] : &:r13_7, ~mu13_4 # 13| r13_14(glval) = VariableAddress[#return] : # 13| v13_15(void) = ReturnValue : &:r13_14, m28_11 # 13| v13_16(void) = UnmodeledUse : mu* @@ -249,12 +249,12 @@ ssa.cpp: #-----| Goto (back edge) -> Block 1 # 71| Block 3 -# 71| v71_1(void) = NoOp : -# 68| v68_11(void) = ReturnIndirection : &:r68_9, ~mu68_4 -# 68| v68_12(void) = ReturnVoid : -# 68| v68_13(void) = UnmodeledUse : mu* -# 68| v68_14(void) = AliasedUse : ~mu68_4 -# 68| v68_15(void) = ExitFunction : +# 71| v71_1(void) = NoOp : +# 68| v68_11(void) = ReturnIndirection[p] : &:r68_9, ~mu68_4 +# 68| v68_12(void) = ReturnVoid : +# 68| v68_13(void) = UnmodeledUse : mu* +# 68| v68_14(void) = AliasedUse : ~mu68_4 +# 68| v68_15(void) = ExitFunction : # 75| void ScalarPhi(bool) # 75| Block 0 @@ -752,7 +752,7 @@ ssa.cpp: # 181| r181_3(int *) = Load : &:r181_2, m179_6 # 181| r181_4(int) = Load : &:r181_3, ~mu179_4 # 181| m181_5(int) = Store : &:r181_1, r181_4 -# 179| v179_9(void) = ReturnIndirection : &:r179_7, ~mu179_4 +# 179| v179_9(void) = ReturnIndirection[p] : &:r179_7, ~mu179_4 # 179| r179_10(glval) = VariableAddress[#return] : # 179| v179_11(void) = ReturnValue : &:r179_10, m181_5 # 179| v179_12(void) = UnmodeledUse : mu* @@ -795,10 +795,10 @@ ssa.cpp: # 190| r190_6(unsigned int) = Load : &:r190_5, ~mu184_4 # 186| mu186_1(unknown) = InlineAsm : ~mu184_4, 0:r189_3, 1:r189_6, 2:r190_3, 3:r190_6 # 192| v192_1(void) = NoOp : -# 184| v184_21(void) = ReturnIndirection : &:r184_7, ~mu184_4 -# 184| v184_22(void) = ReturnIndirection : &:r184_11, ~mu184_4 -# 184| v184_23(void) = ReturnIndirection : &:r184_15, ~mu184_4 -# 184| v184_24(void) = ReturnIndirection : &:r184_19, ~mu184_4 +# 184| v184_21(void) = ReturnIndirection[a] : &:r184_7, ~mu184_4 +# 184| v184_22(void) = ReturnIndirection[b] : &:r184_11, ~mu184_4 +# 184| v184_23(void) = ReturnIndirection[c] : &:r184_15, ~mu184_4 +# 184| v184_24(void) = ReturnIndirection[d] : &:r184_19, ~mu184_4 # 184| v184_25(void) = ReturnVoid : # 184| v184_26(void) = UnmodeledUse : mu* # 184| v184_27(void) = AliasedUse : ~mu184_4 @@ -854,8 +854,8 @@ ssa.cpp: # 202| r202_2(glval) = VariableAddress[ret] : # 202| r202_3(int) = Load : &:r202_2, m201_8 # 202| m202_4(int) = Store : &:r202_1, r202_3 -# 198| v198_15(void) = ReturnIndirection : &:r198_7, ~mu198_4 -# 198| v198_16(void) = ReturnIndirection : &:r198_11, ~mu198_4 +# 198| v198_15(void) = ReturnIndirection[str1] : &:r198_7, ~mu198_4 +# 198| v198_16(void) = ReturnIndirection[str2] : &:r198_11, ~mu198_4 # 198| r198_17(glval) = VariableAddress[#return] : # 198| v198_18(void) = ReturnValue : &:r198_17, m202_4 # 198| v198_19(void) = UnmodeledUse : mu* @@ -1098,7 +1098,7 @@ ssa.cpp: # 251| r251_2(glval) = VariableAddress[dst] : # 251| r251_3(char *) = Load : &:r251_2, m248_12 # 251| m251_4(char *) = Store : &:r251_1, r251_3 -# 247| v247_11(void) = ReturnIndirection : &:r247_7, ~mu247_4 +# 247| v247_11(void) = ReturnIndirection[src] : &:r247_7, ~mu247_4 # 247| r247_12(glval) = VariableAddress[#return] : # 247| v247_13(void) = ReturnValue : &:r247_12, m251_4 # 247| v247_14(void) = UnmodeledUse : mu* @@ -1183,7 +1183,7 @@ ssa.cpp: # 271| r271_2(glval) = VariableAddress[buf] : # 271| r271_3(void *) = Load : &:r271_2, m269_8 # 271| m271_4(void *) = Store : &:r271_1, r271_3 -# 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4 +# 268| v268_11(void) = ReturnIndirection[s] : &:r268_7, ~mu268_4 # 268| r268_12(glval) = VariableAddress[#return] : # 268| v268_13(void) = ReturnValue : &:r268_12, m271_4 # 268| v268_14(void) = UnmodeledUse : mu* @@ -1267,7 +1267,7 @@ ssa.cpp: # 287| r287_8(A *) = Load : &:r287_6, m287_7 # 287| mu287_9(unknown) = InitializeIndirection[p#0] : &:r287_8 # 287| v287_10(void) = NoOp : -# 287| v287_11(void) = ReturnIndirection : &:r287_8, ~mu287_4 +# 287| v287_11(void) = ReturnIndirection[p#0] : &:r287_8, ~mu287_4 # 287| v287_12(void) = ReturnVoid : # 287| v287_13(void) = UnmodeledUse : mu* # 287| v287_14(void) = AliasedUse : ~mu287_4 @@ -1359,3 +1359,47 @@ ssa.cpp: # 291| v291_9(void) = UnmodeledUse : mu* # 291| v291_10(void) = AliasedUse : ~mu291_4 # 291| v291_11(void) = ExitFunction : + +# 301| int main(int, char**) +# 301| Block 0 +# 301| v301_1(void) = EnterFunction : +# 301| mu301_2(unknown) = AliasedDefinition : +# 301| mu301_3(unknown) = InitializeNonLocal : +# 301| mu301_4(unknown) = UnmodeledDefinition : +# 301| r301_5(glval) = VariableAddress[argc] : +# 301| m301_6(int) = InitializeParameter[argc] : &:r301_5 +# 301| r301_7(glval) = VariableAddress[argv] : +# 301| m301_8(char **) = InitializeParameter[argv] : &:r301_7 +# 301| r301_9(char **) = Load : &:r301_7, m301_8 +# 301| mu301_10(unknown) = InitializeIndirection[argv] : &:r301_9 +# 302| r302_1(glval) = FunctionAddress[unknownFunction] : +# 302| r302_2(glval) = VariableAddress[argc] : +# 302| r302_3(int) = Load : &:r302_2, m301_6 +# 302| r302_4(glval) = VariableAddress[argv] : +# 302| r302_5(char **) = Load : &:r302_4, m301_8 +# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5 +# 302| mu302_7(unknown) = ^CallSideEffect : ~mu301_4 +# 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~mu301_4 +# 302| mu302_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5 +# 303| r303_1(glval) = FunctionAddress[unknownFunction] : +# 303| r303_2(glval) = VariableAddress[argc] : +# 303| r303_3(int) = Load : &:r303_2, m301_6 +# 303| r303_4(glval) = VariableAddress[argv] : +# 303| r303_5(char **) = Load : &:r303_4, m301_8 +# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5 +# 303| mu303_7(unknown) = ^CallSideEffect : ~mu301_4 +# 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~mu301_4 +# 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5 +# 304| r304_1(glval) = VariableAddress[#return] : +# 304| r304_2(glval) = VariableAddress[argv] : +# 304| r304_3(char **) = Load : &:r304_2, m301_8 +# 304| r304_4(char *) = Load : &:r304_3, ~mu301_4 +# 304| r304_5(char) = Load : &:r304_4, ~mu301_4 +# 304| r304_6(int) = Convert : r304_5 +# 304| m304_7(int) = Store : &:r304_1, r304_6 +# 301| v301_11(void) = ReturnIndirection[argv] : &:r301_9, ~mu301_4 +# 301| r301_12(glval) = VariableAddress[#return] : +# 301| v301_13(void) = ReturnValue : &:r301_12, m304_7 +# 301| v301_14(void) = UnmodeledUse : mu* +# 301| v301_15(void) = AliasedUse : ~mu301_4 +# 301| v301_16(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 1e6551dd15a5..b307db1cfc58 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -78,7 +78,7 @@ ssa.cpp: # 28| r28_9(int) = Load : &:r28_8, ~mu13_4 # 28| r28_10(int) = Add : r28_5, r28_9 # 28| m28_11(int) = Store : &:r28_1, r28_10 -# 13| v13_13(void) = ReturnIndirection : &:r13_7, ~mu13_4 +# 13| v13_13(void) = ReturnIndirection[p] : &:r13_7, ~mu13_4 # 13| r13_14(glval) = VariableAddress[#return] : # 13| v13_15(void) = ReturnValue : &:r13_14, m28_11 # 13| v13_16(void) = UnmodeledUse : mu* @@ -249,12 +249,12 @@ ssa.cpp: #-----| Goto (back edge) -> Block 1 # 71| Block 3 -# 71| v71_1(void) = NoOp : -# 68| v68_11(void) = ReturnIndirection : &:r68_9, ~mu68_4 -# 68| v68_12(void) = ReturnVoid : -# 68| v68_13(void) = UnmodeledUse : mu* -# 68| v68_14(void) = AliasedUse : ~mu68_4 -# 68| v68_15(void) = ExitFunction : +# 71| v71_1(void) = NoOp : +# 68| v68_11(void) = ReturnIndirection[p] : &:r68_9, ~mu68_4 +# 68| v68_12(void) = ReturnVoid : +# 68| v68_13(void) = UnmodeledUse : mu* +# 68| v68_14(void) = AliasedUse : ~mu68_4 +# 68| v68_15(void) = ExitFunction : # 75| void ScalarPhi(bool) # 75| Block 0 @@ -752,7 +752,7 @@ ssa.cpp: # 181| r181_3(int *) = Load : &:r181_2, m179_6 # 181| r181_4(int) = Load : &:r181_3, ~mu179_4 # 181| m181_5(int) = Store : &:r181_1, r181_4 -# 179| v179_9(void) = ReturnIndirection : &:r179_7, ~mu179_4 +# 179| v179_9(void) = ReturnIndirection[p] : &:r179_7, ~mu179_4 # 179| r179_10(glval) = VariableAddress[#return] : # 179| v179_11(void) = ReturnValue : &:r179_10, m181_5 # 179| v179_12(void) = UnmodeledUse : mu* @@ -795,10 +795,10 @@ ssa.cpp: # 190| r190_6(unsigned int) = Load : &:r190_5, ~mu184_4 # 186| mu186_1(unknown) = InlineAsm : ~mu184_4, 0:r189_3, 1:r189_6, 2:r190_3, 3:r190_6 # 192| v192_1(void) = NoOp : -# 184| v184_21(void) = ReturnIndirection : &:r184_7, ~mu184_4 -# 184| v184_22(void) = ReturnIndirection : &:r184_11, ~mu184_4 -# 184| v184_23(void) = ReturnIndirection : &:r184_15, ~mu184_4 -# 184| v184_24(void) = ReturnIndirection : &:r184_19, ~mu184_4 +# 184| v184_21(void) = ReturnIndirection[a] : &:r184_7, ~mu184_4 +# 184| v184_22(void) = ReturnIndirection[b] : &:r184_11, ~mu184_4 +# 184| v184_23(void) = ReturnIndirection[c] : &:r184_15, ~mu184_4 +# 184| v184_24(void) = ReturnIndirection[d] : &:r184_19, ~mu184_4 # 184| v184_25(void) = ReturnVoid : # 184| v184_26(void) = UnmodeledUse : mu* # 184| v184_27(void) = AliasedUse : ~mu184_4 @@ -854,8 +854,8 @@ ssa.cpp: # 202| r202_2(glval) = VariableAddress[ret] : # 202| r202_3(int) = Load : &:r202_2, m201_8 # 202| m202_4(int) = Store : &:r202_1, r202_3 -# 198| v198_15(void) = ReturnIndirection : &:r198_7, ~mu198_4 -# 198| v198_16(void) = ReturnIndirection : &:r198_11, ~mu198_4 +# 198| v198_15(void) = ReturnIndirection[str1] : &:r198_7, ~mu198_4 +# 198| v198_16(void) = ReturnIndirection[str2] : &:r198_11, ~mu198_4 # 198| r198_17(glval) = VariableAddress[#return] : # 198| v198_18(void) = ReturnValue : &:r198_17, m202_4 # 198| v198_19(void) = UnmodeledUse : mu* @@ -1098,7 +1098,7 @@ ssa.cpp: # 251| r251_2(glval) = VariableAddress[dst] : # 251| r251_3(char *) = Load : &:r251_2, m248_12 # 251| m251_4(char *) = Store : &:r251_1, r251_3 -# 247| v247_11(void) = ReturnIndirection : &:r247_7, ~mu247_4 +# 247| v247_11(void) = ReturnIndirection[src] : &:r247_7, ~mu247_4 # 247| r247_12(glval) = VariableAddress[#return] : # 247| v247_13(void) = ReturnValue : &:r247_12, m251_4 # 247| v247_14(void) = UnmodeledUse : mu* @@ -1183,7 +1183,7 @@ ssa.cpp: # 271| r271_2(glval) = VariableAddress[buf] : # 271| r271_3(void *) = Load : &:r271_2, m269_8 # 271| m271_4(void *) = Store : &:r271_1, r271_3 -# 268| v268_11(void) = ReturnIndirection : &:r268_7, ~mu268_4 +# 268| v268_11(void) = ReturnIndirection[s] : &:r268_7, ~mu268_4 # 268| r268_12(glval) = VariableAddress[#return] : # 268| v268_13(void) = ReturnValue : &:r268_12, m271_4 # 268| v268_14(void) = UnmodeledUse : mu* @@ -1267,7 +1267,7 @@ ssa.cpp: # 287| r287_8(A *) = Load : &:r287_6, m287_7 # 287| mu287_9(unknown) = InitializeIndirection[p#0] : &:r287_8 # 287| v287_10(void) = NoOp : -# 287| v287_11(void) = ReturnIndirection : &:r287_8, ~mu287_4 +# 287| v287_11(void) = ReturnIndirection[p#0] : &:r287_8, ~mu287_4 # 287| v287_12(void) = ReturnVoid : # 287| v287_13(void) = UnmodeledUse : mu* # 287| v287_14(void) = AliasedUse : ~mu287_4 @@ -1359,3 +1359,47 @@ ssa.cpp: # 291| v291_9(void) = UnmodeledUse : mu* # 291| v291_10(void) = AliasedUse : ~mu291_4 # 291| v291_11(void) = ExitFunction : + +# 301| int main(int, char**) +# 301| Block 0 +# 301| v301_1(void) = EnterFunction : +# 301| mu301_2(unknown) = AliasedDefinition : +# 301| mu301_3(unknown) = InitializeNonLocal : +# 301| mu301_4(unknown) = UnmodeledDefinition : +# 301| r301_5(glval) = VariableAddress[argc] : +# 301| m301_6(int) = InitializeParameter[argc] : &:r301_5 +# 301| r301_7(glval) = VariableAddress[argv] : +# 301| m301_8(char **) = InitializeParameter[argv] : &:r301_7 +# 301| r301_9(char **) = Load : &:r301_7, m301_8 +# 301| mu301_10(unknown) = InitializeIndirection[argv] : &:r301_9 +# 302| r302_1(glval) = FunctionAddress[unknownFunction] : +# 302| r302_2(glval) = VariableAddress[argc] : +# 302| r302_3(int) = Load : &:r302_2, m301_6 +# 302| r302_4(glval) = VariableAddress[argv] : +# 302| r302_5(char **) = Load : &:r302_4, m301_8 +# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5 +# 302| mu302_7(unknown) = ^CallSideEffect : ~mu301_4 +# 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~mu301_4 +# 302| mu302_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5 +# 303| r303_1(glval) = FunctionAddress[unknownFunction] : +# 303| r303_2(glval) = VariableAddress[argc] : +# 303| r303_3(int) = Load : &:r303_2, m301_6 +# 303| r303_4(glval) = VariableAddress[argv] : +# 303| r303_5(char **) = Load : &:r303_4, m301_8 +# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5 +# 303| mu303_7(unknown) = ^CallSideEffect : ~mu301_4 +# 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~mu301_4 +# 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5 +# 304| r304_1(glval) = VariableAddress[#return] : +# 304| r304_2(glval) = VariableAddress[argv] : +# 304| r304_3(char **) = Load : &:r304_2, m301_8 +# 304| r304_4(char *) = Load : &:r304_3, ~mu301_4 +# 304| r304_5(char) = Load : &:r304_4, ~mu301_4 +# 304| r304_6(int) = Convert : r304_5 +# 304| m304_7(int) = Store : &:r304_1, r304_6 +# 301| v301_11(void) = ReturnIndirection[argv] : &:r301_9, ~mu301_4 +# 301| r301_12(glval) = VariableAddress[#return] : +# 301| v301_13(void) = ReturnValue : &:r301_12, m304_7 +# 301| v301_14(void) = UnmodeledUse : mu* +# 301| v301_15(void) = AliasedUse : ~mu301_4 +# 301| v301_16(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected index a492fb47d41f..70a1977367fb 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected @@ -355,7 +355,7 @@ test.cpp: # 46| m46_4(int) = Store : &:r46_3, r46_2 # 46| valnum = m43_10, m45_10, m46_4, r43_8, r45_8, r46_2 # 47| v47_1(void) = NoOp : -# 39| v39_14(void) = ReturnIndirection : &:r39_12, m44_6 +# 39| v39_14(void) = ReturnIndirection[p2] : &:r39_12, m44_6 # 39| r39_15(glval) = VariableAddress[#return] : # 39| valnum = unique # 39| v39_16(void) = ReturnValue : &:r39_15 @@ -531,8 +531,8 @@ test.cpp: # 65| valnum = m53_1, m65_4, r62_2, r65_3 # 65| m65_4(unsigned int) = Store : &:r65_1, r65_3 # 65| valnum = m53_1, m65_4, r62_2, r65_3 -# 49| v49_14(void) = ReturnIndirection : &:r49_8, m49_9 -# 49| v49_15(void) = ReturnIndirection : &:r49_12, m49_13 +# 49| v49_14(void) = ReturnIndirection[str] : &:r49_8, m49_9 +# 49| v49_15(void) = ReturnIndirection[chars] : &:r49_12, m49_13 # 49| r49_16(glval) = VariableAddress[#return] : # 49| valnum = r49_16, r65_1 # 49| v49_17(void) = ReturnValue : &:r49_16, m65_4 @@ -625,14 +625,14 @@ test.cpp: #-----| Goto -> Block 2 # 82| Block 2 -# 82| m82_1(unknown) = Phi : from 0:~m77_5, from 1:~m80_4 +# 82| m82_1(unknown) = Phi : from 0:~m77_5, from 1:~m80_4 # 82| valnum = unique -# 82| v82_2(void) = NoOp : -# 75| v75_10(void) = ReturnIndirection : &:r75_8, m75_9 -# 75| v75_11(void) = ReturnVoid : -# 75| v75_12(void) = UnmodeledUse : mu* -# 75| v75_13(void) = AliasedUse : ~m82_1 -# 75| v75_14(void) = ExitFunction : +# 82| v82_2(void) = NoOp : +# 75| v75_10(void) = ReturnIndirection[vals] : &:r75_8, m75_9 +# 75| v75_11(void) = ReturnVoid : +# 75| v75_12(void) = UnmodeledUse : mu* +# 75| v75_13(void) = AliasedUse : ~m82_1 +# 75| v75_14(void) = ExitFunction : # 84| void test05(int, int, void*) # 84| Block 0 @@ -689,7 +689,7 @@ test.cpp: # 88| m88_10(int) = Store : &:r88_9, r88_8 # 88| valnum = m88_10, m88_6, r88_8 # 89| v89_1(void) = NoOp : -# 84| v84_14(void) = ReturnIndirection : &:r84_12, m84_13 +# 84| v84_14(void) = ReturnIndirection[p] : &:r84_12, m84_13 # 84| v84_15(void) = ReturnVoid : # 84| v84_16(void) = UnmodeledUse : mu* # 84| v84_17(void) = AliasedUse : m84_3 @@ -818,7 +818,7 @@ test.cpp: # 109| valnum = m105_7, m107_6, m109_4, r105_6, r107_5, r109_3 # 109| m109_4(int) = Store : &:r109_1, r109_3 # 109| valnum = m105_7, m107_6, m109_4, r105_6, r107_5, r109_3 -# 104| v104_10(void) = ReturnIndirection : &:r104_8, m104_9 +# 104| v104_10(void) = ReturnIndirection[pd] : &:r104_8, m104_9 # 104| r104_11(glval) = VariableAddress[#return] : # 104| valnum = r104_11, r109_1 # 104| v104_12(void) = ReturnValue : &:r104_11, m109_4 @@ -925,7 +925,7 @@ test.cpp: # 129| m129_6(int) = Store : &:r129_1, r129_5 # 129| valnum = m124_11, m128_6, m129_6, r128_2, r129_5 # 130| v130_1(void) = NoOp : -# 124| v124_12(void) = ReturnIndirection : &:r124_8, m128_7 +# 124| v124_12(void) = ReturnIndirection[pa] : &:r124_8, m128_7 # 124| v124_13(void) = ReturnVoid : # 124| v124_14(void) = UnmodeledUse : mu* # 124| v124_15(void) = AliasedUse : m124_3 @@ -1068,7 +1068,7 @@ test.cpp: # 149| m149_6(int) = Store : &:r149_1, r149_5 # 149| valnum = m144_6, m149_6, r144_5, r149_5 # 150| v150_1(void) = NoOp : -# 143| v143_10(void) = ReturnIndirection : &:r143_8, m147_7 +# 143| v143_10(void) = ReturnIndirection[pa] : &:r143_8, m147_7 # 143| v143_11(void) = ReturnVoid : # 143| v143_12(void) = UnmodeledUse : mu* # 143| v143_13(void) = AliasedUse : m143_3 diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected index 181414f12d00..0064b6d57153 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected @@ -55,6 +55,8 @@ edges | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... | @@ -65,6 +67,8 @@ edges | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ | @@ -73,12 +77,29 @@ edges | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:117:15:117:16 | array to pointer conversion | argvLocal.c:117:15:117:16 | printWrapper output argument | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:122:15:122:16 | i4 | argvLocal.c:122:15:122:16 | printWrapper output argument | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... | @@ -89,6 +110,11 @@ edges | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | +| argvLocal.c:128:15:128:16 | array to pointer conversion | argvLocal.c:128:15:128:16 | printWrapper output argument | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | (const char *)... | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | ... + ... | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | @@ -130,6 +156,8 @@ edges | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | nodes +| argvLocal.c:9:25:9:31 | correct | semmle.label | correct | +| argvLocal.c:10:9:10:15 | Chi | semmle.label | Chi | | argvLocal.c:95:9:95:12 | argv | semmle.label | argv | | argvLocal.c:95:9:95:12 | argv | semmle.label | argv | | argvLocal.c:95:9:95:15 | (const char *)... | semmle.label | (const char *)... | @@ -178,12 +206,14 @@ nodes | argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 | +| argvLocal.c:122:15:122:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:126:10:126:13 | argv | semmle.label | argv | | argvLocal.c:126:10:126:13 | argv | semmle.label | argv | | argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... | @@ -192,6 +222,7 @@ nodes | argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 | +| argvLocal.c:128:15:128:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected index c4dc83315e4c..a05e392ecf29 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected @@ -1,8 +1,12 @@ edges | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | (const char *)... | | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 | +| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | (const char *)... | +| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 | | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | (const char *)... | | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | +| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | (const char *)... | +| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | (const char *)... | | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 | | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | (const char *)... | @@ -65,6 +69,9 @@ nodes | funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 | | funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 | | funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 | +| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... | +| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... | +| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 | #select | funcsLocal.c:17:9:17:10 | i1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread | | funcsLocal.c:27:9:27:10 | i3 | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:26:8:26:9 | i3 | fgets | @@ -73,3 +80,4 @@ nodes | funcsLocal.c:37:9:37:10 | i5 | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:36:7:36:8 | i5 | gets | | funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:13:41:16 | call to gets | gets | | funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:18:41:20 | i61 | gets | +| funcsLocal.c:58:9:58:10 | e1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/ArithmeticUncontrolled.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/ArithmeticUncontrolled.expected index 461625d8b77a..f68464b6b38f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/ArithmeticUncontrolled.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/ArithmeticUncontrolled.expected @@ -42,8 +42,18 @@ edges | test.cpp:8:9:8:12 | Store | test.cpp:24:11:24:18 | call to get_rand | | test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store | | test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store | +| test.cpp:13:2:13:15 | Chi | test.cpp:30:13:30:14 | get_rand2 output argument | +| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi | +| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi | +| test.cpp:18:2:18:14 | Chi | test.cpp:36:13:36:13 | get_rand3 output argument | +| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi | +| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi | | test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r | | test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r | +| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r | +| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r | +| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r | +| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r | nodes | test.c:18:13:18:16 | call to rand | semmle.label | call to rand | | test.c:18:13:18:16 | call to rand | semmle.label | call to rand | @@ -96,10 +106,24 @@ nodes | test.cpp:8:9:8:12 | Store | semmle.label | Store | | test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand | | test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand | +| test.cpp:13:2:13:15 | Chi | semmle.label | Chi | +| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand | +| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand | +| test.cpp:18:2:18:14 | Chi | semmle.label | Chi | +| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand | +| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand | | test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand | | test.cpp:25:7:25:7 | r | semmle.label | r | | test.cpp:25:7:25:7 | r | semmle.label | r | | test.cpp:25:7:25:7 | r | semmle.label | r | +| test.cpp:30:13:30:14 | get_rand2 output argument | semmle.label | get_rand2 output argument | +| test.cpp:31:7:31:7 | r | semmle.label | r | +| test.cpp:31:7:31:7 | r | semmle.label | r | +| test.cpp:31:7:31:7 | r | semmle.label | r | +| test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument | +| test.cpp:37:7:37:7 | r | semmle.label | r | +| test.cpp:37:7:37:7 | r | semmle.label | r | +| test.cpp:37:7:37:7 | r | semmle.label | r | #select | test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value | | test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | Uncontrolled value | @@ -110,3 +134,5 @@ nodes | test.c:77:9:77:9 | r | test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | ... ^ ... | Uncontrolled value | | test.c:100:5:100:5 | r | test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:99:14:99:19 | call to rand | Uncontrolled value | | test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | Uncontrolled value | +| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | Uncontrolled value | +| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | Uncontrolled value | diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index fc9d0758125f..38216872f2b8 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -525,7 +525,7 @@ class ReturnValueInstruction extends ReturnInstruction { final Instruction getReturnValue() { result = getReturnValueOperand().getDef() } } -class ReturnIndirectionInstruction extends Instruction { +class ReturnIndirectionInstruction extends VariableInstruction { ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection } final SideEffectOperand getSideEffectOperand() { result = getAnOperand() } @@ -535,6 +535,12 @@ class ReturnIndirectionInstruction extends Instruction { final AddressOperand getSourceAddressOperand() { result = getAnOperand() } final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() } + + /** + * Gets the parameter for which this instruction reads the final pointed-to value within the + * function. + */ + final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } } class CopyInstruction extends Instruction { diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index fc9d0758125f..38216872f2b8 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -525,7 +525,7 @@ class ReturnValueInstruction extends ReturnInstruction { final Instruction getReturnValue() { result = getReturnValueOperand().getDef() } } -class ReturnIndirectionInstruction extends Instruction { +class ReturnIndirectionInstruction extends VariableInstruction { ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection } final SideEffectOperand getSideEffectOperand() { result = getAnOperand() } @@ -535,6 +535,12 @@ class ReturnIndirectionInstruction extends Instruction { final AddressOperand getSourceAddressOperand() { result = getAnOperand() } final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() } + + /** + * Gets the parameter for which this instruction reads the final pointed-to value within the + * function. + */ + final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() } } class CopyInstruction extends Instruction {