================
@@ -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@-1{{TRUE}}
- // expected-note@-2{{Assuming 'arr1' is
not equal to 'obj'}}
- // expected-warning@-3{{FALSE}}
- // expected-note@-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'}}
----------------
haoNoQ wrote:
Hmm this looks like a regression. In this test, on the "cast succeeds" branch,
`arr1` should be known to be the same as `obj`.
In this case `OSDynamicCast()` is a macro that implements custom RTTI in XNU.
It is defined as:
```c++
13 #define OSDynamicCast(type, inst) \
14 ((type *) OSMetaClassBase::safeMetaCast(inst, type::metaClass))
```
where `safeMetaCast()` is a function without visible definition that returns an
`OSMetaClassBase *` (the most base class in the `OSObject` hierarchy).
Then the checker models `safeMetaCast()` to split the state and either "pass
through" the value or return 0. But the subsequent C-style cast is technically
a base-to-derived class (because `safeMetaCast()` doesn't return the actual
type, but a base type). So it's likely that we've somehow regressed when we
started actively modeling that cast.
We probably shouldn't have regressed though. Our desired behavior is the same
as the old behavior: fully trust the cast.
https://github.com/llvm/llvm-project/pull/69057
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits