================
@@ -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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to