[clang] [analyzer] Trust base to derived casts for dynamic types (PR #69057)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 6 06:12:55 PST 2023
================
@@ -492,11 +492,13 @@ void check_required_cast() {
void check_cast_behavior(OSObject *obj) {
OSArray *arr1 = OSDynamicCast(OSArray, obj);
- clang_analyzer_eval(arr1 == obj); // expected-warning{{TRUE}}
- // expected-note at -1{{TRUE}}
- // expected-note at -2{{Assuming 'arr1' is not equal to 'obj'}}
- // expected-warning at -3{{FALSE}}
- // expected-note at -4 {{FALSE}}
+ clang_analyzer_eval(arr1 == obj); // #check_cast_behavior_1
+ // expected-warning@#check_cast_behavior_1 {{TRUE}}
+ // expected-note@#check_cast_behavior_1 {{TRUE}}
+ // expected-note@#check_cast_behavior_1{{Assuming 'arr1' is equal to 'obj'}}
----------------
steakhal wrote:
I've looked at the exploded-graph before and after the patch, and the values and the branches are all the same. There is only one difference: in the new graph, after the `(OSArray *)` cast in init-expr of the decl, we have the type info bound: `Dynamic Types`:
```
SymRegion{reg_$0<OSObject * obj>} -> OSArray (or a sub-class)
```
Later, when we load for the analyzer_eval, we can see that on the branch where the `safeMetaCast` succeeds, `arr1` and `obj` refers to the same lvalue, thus already proven to be equal.
![image](https://github.com/llvm/llvm-project/assets/6280485/2d2ee01e-b356-43fd-aa24-62b69d08b145)
BTW if I change the test into this, it would pass on both the old and new versions:
```c++
void check_cast_behavior(OSObject *obj) {
OSArray *arr1 = OSDynamicCast(OSArray, obj);
if (!arr1) return;
// expected-note at -1 {{'arr1' is non-null}} expected-note at -1 {{Taking false branch}}
// expected-note at -2 {{'arr1' is non-null}} expected-note at -2 {{Taking false branch}}
clang_analyzer_eval(arr1 == obj); // expected-warning{{TRUE}} expected-note{{TRUE}}
OSArray *arr2 = OSRequiredCast(OSArray, obj);
clang_analyzer_eval(arr2 == obj); // expected-warning{{TRUE}} expected-note{{TRUE}}
}
```
I think this test would describe the behavior for the "cast-succeeds" branch, aka. the branch where `arr1` is non-null. Consequently, I believe this PR would not regress this.
https://github.com/llvm/llvm-project/pull/69057
More information about the cfe-commits
mailing list