C++: Add two more tests to 'unsafe use of this'. First, test that post-dominance removes some results. Second, that a cast to the pure virtual function's defining class (skipping past a derived class that overrides the function) followed by a call to the function still results in an alert. This is also undefined behavior.

This commit is contained in:
Mathias Vorreiter Pedersen
2020-11-12 15:51:04 +01:00
parent 896dee5fb7
commit f417831a23
2 changed files with 43 additions and 25 deletions

View File

@@ -1,23 +1,26 @@
edges
| test.cpp:7:2:7:2 | InitializeParameter: B | test.cpp:8:10:8:13 | Load: this |
| test.cpp:8:10:8:13 | Load: this | test.cpp:30:16:30:16 | InitializeParameter: x |
| test.cpp:8:10:8:13 | Load: this | test.cpp:34:16:34:16 | InitializeParameter: x |
| test.cpp:11:10:11:10 | InitializeParameter: b | test.cpp:12:9:12:9 | Load: b |
| test.cpp:12:9:12:9 | CopyValue: (reference dereference) | test.cpp:12:9:12:9 | ConvertToNonVirtualBase: (A)... |
| test.cpp:12:9:12:9 | Load: b | test.cpp:12:9:12:9 | CopyValue: (reference dereference) |
| test.cpp:15:2:15:3 | InitializeParameter: ~B | test.cpp:16:3:16:3 | Load: this |
| test.cpp:16:3:16:3 | Load: this | file://:0:0:0:0 | ConvertToNonVirtualBase: (A *)... |
| test.cpp:21:2:21:2 | InitializeParameter: C | test.cpp:21:6:21:6 | ConvertToNonVirtualBase: call to B |
| test.cpp:21:2:21:2 | InitializeParameter: C | test.cpp:21:12:21:12 | ConvertToNonVirtualBase: call to B |
| test.cpp:21:2:21:2 | InitializeParameter: C | test.cpp:22:10:22:13 | Load: this |
| test.cpp:21:6:21:6 | ConvertToNonVirtualBase: call to B | test.cpp:7:2:7:2 | InitializeParameter: B |
| test.cpp:22:10:22:13 | ConvertToNonVirtualBase: (B *)... | test.cpp:30:16:30:16 | InitializeParameter: x |
| test.cpp:21:12:21:12 | ConvertToNonVirtualBase: call to B | test.cpp:7:2:7:2 | InitializeParameter: B |
| test.cpp:22:10:22:13 | ConvertToNonVirtualBase: (B *)... | test.cpp:34:16:34:16 | InitializeParameter: x |
| test.cpp:22:10:22:13 | Load: this | test.cpp:22:10:22:13 | ConvertToNonVirtualBase: (B *)... |
| test.cpp:27:5:27:5 | InitializeParameter: D | test.cpp:27:14:27:17 | Load: this |
| test.cpp:27:13:27:17 | ConvertToNonVirtualBase: (B)... | test.cpp:27:13:27:17 | CopyValue: (reference to) |
| test.cpp:27:13:27:17 | CopyValue: (reference to) | test.cpp:11:10:11:10 | InitializeParameter: b |
| test.cpp:27:13:27:17 | CopyValue: * ... | test.cpp:27:13:27:17 | ConvertToNonVirtualBase: (B)... |
| test.cpp:27:14:27:17 | Load: this | test.cpp:27:13:27:17 | CopyValue: * ... |
| test.cpp:30:16:30:16 | InitializeParameter: x | test.cpp:31:2:31:2 | Load: x |
| test.cpp:31:2:31:2 | Load: x | test.cpp:31:2:31:2 | ConvertToNonVirtualBase: (A *)... |
| test.cpp:31:5:31:5 | InitializeParameter: D | test.cpp:31:14:31:17 | Load: this |
| test.cpp:31:13:31:17 | ConvertToNonVirtualBase: (B)... | test.cpp:31:13:31:17 | CopyValue: (reference to) |
| test.cpp:31:13:31:17 | CopyValue: (reference to) | test.cpp:11:10:11:10 | InitializeParameter: b |
| test.cpp:31:13:31:17 | CopyValue: * ... | test.cpp:31:13:31:17 | ConvertToNonVirtualBase: (B)... |
| test.cpp:31:14:31:17 | Load: this | test.cpp:31:13:31:17 | CopyValue: * ... |
| test.cpp:34:16:34:16 | InitializeParameter: x | test.cpp:35:2:35:2 | Load: x |
| test.cpp:35:2:35:2 | Load: x | test.cpp:35:2:35:2 | ConvertToNonVirtualBase: (A *)... |
| test.cpp:47:2:47:2 | InitializeParameter: F | test.cpp:48:8:48:11 | Load: this |
| test.cpp:48:8:48:11 | ConvertToNonVirtualBase: (E *)... | test.cpp:48:4:48:11 | ConvertToNonVirtualBase: (A *)... |
| test.cpp:48:8:48:11 | Load: this | test.cpp:48:8:48:11 | ConvertToNonVirtualBase: (E *)... |
nodes
| file://:0:0:0:0 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... |
| test.cpp:7:2:7:2 | InitializeParameter: B | semmle.label | InitializeParameter: B |
@@ -29,19 +32,24 @@ nodes
| test.cpp:15:2:15:3 | InitializeParameter: ~B | semmle.label | InitializeParameter: ~B |
| test.cpp:16:3:16:3 | Load: this | semmle.label | Load: this |
| test.cpp:21:2:21:2 | InitializeParameter: C | semmle.label | InitializeParameter: C |
| test.cpp:21:6:21:6 | ConvertToNonVirtualBase: call to B | semmle.label | ConvertToNonVirtualBase: call to B |
| test.cpp:21:12:21:12 | ConvertToNonVirtualBase: call to B | semmle.label | ConvertToNonVirtualBase: call to B |
| test.cpp:22:10:22:13 | ConvertToNonVirtualBase: (B *)... | semmle.label | ConvertToNonVirtualBase: (B *)... |
| test.cpp:22:10:22:13 | Load: this | semmle.label | Load: this |
| test.cpp:27:5:27:5 | InitializeParameter: D | semmle.label | InitializeParameter: D |
| test.cpp:27:13:27:17 | ConvertToNonVirtualBase: (B)... | semmle.label | ConvertToNonVirtualBase: (B)... |
| test.cpp:27:13:27:17 | CopyValue: (reference to) | semmle.label | CopyValue: (reference to) |
| test.cpp:27:13:27:17 | CopyValue: * ... | semmle.label | CopyValue: * ... |
| test.cpp:27:14:27:17 | Load: this | semmle.label | Load: this |
| test.cpp:30:16:30:16 | InitializeParameter: x | semmle.label | InitializeParameter: x |
| test.cpp:31:2:31:2 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... |
| test.cpp:31:2:31:2 | Load: x | semmle.label | Load: x |
| test.cpp:31:5:31:5 | InitializeParameter: D | semmle.label | InitializeParameter: D |
| test.cpp:31:13:31:17 | ConvertToNonVirtualBase: (B)... | semmle.label | ConvertToNonVirtualBase: (B)... |
| test.cpp:31:13:31:17 | CopyValue: (reference to) | semmle.label | CopyValue: (reference to) |
| test.cpp:31:13:31:17 | CopyValue: * ... | semmle.label | CopyValue: * ... |
| test.cpp:31:14:31:17 | Load: this | semmle.label | Load: this |
| test.cpp:34:16:34:16 | InitializeParameter: x | semmle.label | InitializeParameter: x |
| test.cpp:35:2:35:2 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... |
| test.cpp:35:2:35:2 | Load: x | semmle.label | Load: x |
| test.cpp:47:2:47:2 | InitializeParameter: F | semmle.label | InitializeParameter: F |
| test.cpp:48:4:48:11 | ConvertToNonVirtualBase: (A *)... | semmle.label | ConvertToNonVirtualBase: (A *)... |
| test.cpp:48:8:48:11 | ConvertToNonVirtualBase: (E *)... | semmle.label | ConvertToNonVirtualBase: (E *)... |
| test.cpp:48:8:48:11 | Load: this | semmle.label | Load: this |
#select
| test.cpp:12:11:12:11 | call to f | test.cpp:27:5:27:5 | InitializeParameter: D | test.cpp:12:9:12:9 | ConvertToNonVirtualBase: (A)... | Call to pure virtual function during construction |
| test.cpp:12:11:12:11 | call to f | test.cpp:31:5:31:5 | InitializeParameter: D | test.cpp:12:9:12:9 | ConvertToNonVirtualBase: (A)... | Call to pure virtual function during construction |
| test.cpp:16:3:16:3 | call to f | test.cpp:15:2:15:3 | InitializeParameter: ~B | file://:0:0:0:0 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during destruction |
| test.cpp:31:5:31:5 | call to f | test.cpp:7:2:7:2 | InitializeParameter: B | test.cpp:31:2:31:2 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction |
| test.cpp:31:5:31:5 | call to f | test.cpp:21:2:21:2 | InitializeParameter: C | test.cpp:31:2:31:2 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction |
| test.cpp:35:5:35:5 | call to f | test.cpp:7:2:7:2 | InitializeParameter: B | test.cpp:35:2:35:2 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction |
| test.cpp:35:5:35:5 | call to f | test.cpp:21:2:21:2 | InitializeParameter: C | test.cpp:35:2:35:2 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction |
| test.cpp:48:15:48:15 | call to f | test.cpp:47:2:47:2 | InitializeParameter: F | test.cpp:48:4:48:11 | ConvertToNonVirtualBase: (A *)... | Call to pure virtual function during construction |

View File

@@ -18,8 +18,12 @@ struct B : public A {
};
struct C : public B {
C() {
C(bool b) {
call_f(this);
if(b) {
this->f(); // GOOD: Not a 'must' flow
}
}
};
@@ -37,4 +41,10 @@ struct E : public A {
}
void f() override {}
};
};
struct F : public E {
F() {
((A*)this)->f(); // BAD: undefined behavior
}
};