From 928b0c50d28f2a51130999bbe0ffeb4d59b9fdd2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jan 2020 17:26:23 +0100 Subject: [PATCH 1/4] C++: Add test demonstrating false negative when using dynamic_cast --- .../defaulttainttracking.cpp | 39 ++++++++++++++ .../DefaultTaintTracking/tainted.expected | 54 +++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp index 8958616c0d32..747f71f90d46 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp @@ -39,3 +39,42 @@ void test_indirect_arg_to_model() { inet_addr_retval a = inet_addr((const char *)&env_pointer); sink(a); } + +class B { + public: + virtual void f(const char*) = 0; +}; + +class D1 : public B {}; + +class D2 : public D1 { + public: + void f(const char* p) override {} +}; + +class D3 : public D2 { + public: + void f(const char* p) override { + sink(p); + } +}; + +void test_dynamic_cast() { + B* b = new D3(); + b->f(getenv("VAR")); // tainted + + ((D2*)b)->f(getenv("VAR")); // tainted + static_cast(b)->f(getenv("VAR")); // tainted + dynamic_cast(b)->f(getenv("VAR")); // tainted [NOT DETECTED] + reinterpret_cast(b)->f(getenv("VAR")); // tainted + + B* b2 = new D2(); + b2->f(getenv("VAR")); + + ((D2*)b2)->f(getenv("VAR")); + static_cast(b2)->f(getenv("VAR")); + dynamic_cast(b2)->f(getenv("VAR")); + reinterpret_cast(b2)->f(getenv("VAR")); + + dynamic_cast(b2)->f(getenv("VAR")); +} \ 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 d2b48f25bf9d..eed97407faa0 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected @@ -30,6 +30,60 @@ | defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:26:39:34 | call to inet_addr | | defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:50:39:61 | & ... | | defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:40:10:40:10 | a | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:45:20:45:29 | p#0 | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:58:14:58:14 | p | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:64:10:64:15 | call to getenv | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:64:10:64:22 | (const char *)... | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | defaulttainttracking.cpp:58:14:58:14 | p | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | defaulttainttracking.cpp:66:17:66:22 | call to getenv | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | defaulttainttracking.cpp:66:17:66:29 | (const char *)... | +| defaulttainttracking.cpp:66:17:66:22 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:58:14:58:14 | p | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:67:28:67:33 | call to getenv | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:67:28:67:40 | (const char *)... | +| defaulttainttracking.cpp:67:28:67:33 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:68:29:68:34 | call to getenv | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:68:29:68:41 | (const char *)... | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:58:14:58:14 | p | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:69:33:69:38 | call to getenv | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:69:33:69:45 | (const char *)... | +| defaulttainttracking.cpp:69:33:69:38 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| defaulttainttracking.cpp:72:11:72:16 | call to getenv | defaulttainttracking.cpp:45:20:45:29 | p#0 | +| defaulttainttracking.cpp:72:11:72:16 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:72:11:72:16 | call to getenv | defaulttainttracking.cpp:72:11:72:16 | call to getenv | +| defaulttainttracking.cpp:72:11:72:16 | call to getenv | defaulttainttracking.cpp:72:11:72:23 | (const char *)... | +| defaulttainttracking.cpp:74:18:74:23 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:74:18:74:23 | call to getenv | defaulttainttracking.cpp:74:18:74:23 | call to getenv | +| defaulttainttracking.cpp:74:18:74:23 | call to getenv | defaulttainttracking.cpp:74:18:74:30 | (const char *)... | +| defaulttainttracking.cpp:75:29:75:34 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:75:29:75:34 | call to getenv | defaulttainttracking.cpp:75:29:75:34 | call to getenv | +| defaulttainttracking.cpp:75:29:75:34 | call to getenv | defaulttainttracking.cpp:75:29:75:41 | (const char *)... | +| defaulttainttracking.cpp:76:30:76:35 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:76:30:76:35 | call to getenv | defaulttainttracking.cpp:76:30:76:35 | call to getenv | +| defaulttainttracking.cpp:76:30:76:35 | call to getenv | defaulttainttracking.cpp:76:30:76:42 | (const char *)... | +| defaulttainttracking.cpp:77:34:77:39 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:77:34:77:39 | call to getenv | defaulttainttracking.cpp:77:34:77:39 | call to getenv | +| defaulttainttracking.cpp:77:34:77:39 | call to getenv | defaulttainttracking.cpp:77:34:77:46 | (const char *)... | +| defaulttainttracking.cpp:79:30:79:35 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| defaulttainttracking.cpp:79:30:79:35 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | +| defaulttainttracking.cpp:79:30:79:35 | call to getenv | defaulttainttracking.cpp:58:14:58:14 | p | +| defaulttainttracking.cpp:79:30:79:35 | call to getenv | defaulttainttracking.cpp:79:30:79:35 | call to getenv | +| defaulttainttracking.cpp:79:30:79:35 | call to getenv | defaulttainttracking.cpp:79:30:79:42 | (const char *)... | +| defaulttainttracking.cpp:79:30:79:35 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | | test_diff.cpp:92:10:92:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | | test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:1:11:1:20 | p#0 | | test_diff.cpp:92:10:92:13 | argv | test_diff.cpp:92:10:92:13 | argv | From 46ce228bce52689295cca77fca53cd286d2b702d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jan 2020 17:36:17 +0100 Subject: [PATCH 2/4] C++: Add instruction for CheckedConvertOrNull and handle it in alias analysis and data flow --- .../src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 1 + .../code/cpp/ir/implementation/aliased_ssa/Instruction.qll | 4 ++++ .../ir/implementation/aliased_ssa/internal/AliasAnalysis.qll | 4 ++++ .../src/semmle/code/cpp/ir/implementation/raw/Instruction.qll | 4 ++++ .../code/cpp/ir/implementation/unaliased_ssa/Instruction.qll | 4 ++++ .../implementation/unaliased_ssa/internal/AliasAnalysis.qll | 4 ++++ 6 files changed, 21 insertions(+) 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 24598bdaf12c..30b26b59ad9e 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 7514f580813e..4f4b0eafe62e 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 99f6b545806b..6fe55c49d8f6 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 7514f580813e..4f4b0eafe62e 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 7514f580813e..4f4b0eafe62e 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 99f6b545806b..6fe55c49d8f6 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 From c1091a03d016856c1d45530709c67e55763056da Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jan 2020 17:38:35 +0100 Subject: [PATCH 3/4] C++: Accept output --- .../DefaultTaintTracking/defaulttainttracking.cpp | 4 ++-- .../dataflow/DefaultTaintTracking/tainted.expected | 8 ++++++++ .../dataflow/DefaultTaintTracking/test_diff.expected | 5 +---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp index 747f71f90d46..d4137762dcb0 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/defaulttainttracking.cpp @@ -65,7 +65,7 @@ void test_dynamic_cast() { ((D2*)b)->f(getenv("VAR")); // tainted static_cast(b)->f(getenv("VAR")); // tainted - dynamic_cast(b)->f(getenv("VAR")); // tainted [NOT DETECTED] + dynamic_cast(b)->f(getenv("VAR")); // tainted reinterpret_cast(b)->f(getenv("VAR")); // tainted B* b2 = new D2(); @@ -76,5 +76,5 @@ void test_dynamic_cast() { dynamic_cast(b2)->f(getenv("VAR")); reinterpret_cast(b2)->f(getenv("VAR")); - dynamic_cast(b2)->f(getenv("VAR")); + dynamic_cast(b2)->f(getenv("VAR")); // tainted [FALSE POSITIVE] } \ 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 eed97407faa0..5c9655fe7485 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected @@ -52,9 +52,13 @@ | defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:67:28:67:33 | call to getenv | | defaulttainttracking.cpp:67:28:67:33 | call to getenv | defaulttainttracking.cpp:67:28:67:40 | (const char *)... | | defaulttainttracking.cpp:67:28:67:33 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | | defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:58:14:58:14 | p | | defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:68:29:68:34 | call to getenv | | defaulttainttracking.cpp:68:29:68:34 | call to getenv | defaulttainttracking.cpp:68:29:68:41 | (const char *)... | +| defaulttainttracking.cpp:68:29:68:34 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | | defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 | | defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | | defaulttainttracking.cpp:69:33:69:38 | call to getenv | defaulttainttracking.cpp:57:24:57:24 | p | @@ -177,7 +181,11 @@ | test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:126:43:126:46 | argv | | test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:126:43:126:49 | (const char *)... | | test_diff.cpp:126:43:126:46 | argv | test_diff.cpp:126:43:126:49 | access to array | +| test_diff.cpp:128:44:128:47 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | +| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:1:11:1:20 | p#0 | | test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:76:24:76:24 | p | +| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:81:24:81:24 | p | +| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:82:14:82:14 | p | | test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:128:44:128:47 | argv | | test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:128:44:128:50 | (const char *)... | | test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:128:44:128:50 | access to array | 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 04c0498a6171..209ce48e6e46 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected @@ -9,6 +9,7 @@ | defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:31:40:31:53 | dotted_address | AST only | | defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:36:39:61 | (const char *)... | AST only | | defaulttainttracking.cpp:38:25:38:30 | call to getenv | defaulttainttracking.cpp:39:51:39:61 | env_pointer | AST only | +| defaulttainttracking.cpp:64:10:64:15 | call to getenv | defaulttainttracking.cpp:52:24:52:24 | p | IR only | | test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only | | test_diff.cpp:108:10:108:13 | argv | test_diff.cpp:36:24:36:24 | p | AST only | | test_diff.cpp:111:10:111:13 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | AST only | @@ -16,7 +17,3 @@ | test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:29:24:29:24 | p | AST only | | test_diff.cpp:111:10:111:13 | argv | test_diff.cpp:30:14:30:14 | p | AST only | | test_diff.cpp:124:19:124:22 | argv | test_diff.cpp:76:24:76:24 | p | IR only | -| test_diff.cpp:128:44:128:47 | argv | defaulttainttracking.cpp:9:11:9:20 | p#0 | AST only | -| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:1:11:1:20 | p#0 | AST only | -| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:81:24:81:24 | p | AST only | -| test_diff.cpp:128:44:128:47 | argv | test_diff.cpp:82:14:82:14 | p | AST only | From 67d29e31ccf05e335aff6352fae34bcc3ae85d49 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jan 2020 17:52:45 +0100 Subject: [PATCH 4/4] C#: Sync identical files --- .../semmle/code/csharp/ir/implementation/raw/Instruction.qll | 4 ++++ .../csharp/ir/implementation/unaliased_ssa/Instruction.qll | 4 ++++ 2 files changed, 8 insertions(+) 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 7514f580813e..4f4b0eafe62e 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 @@ -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/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 7514f580813e..4f4b0eafe62e 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 @@ -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.