================ @@ -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