[analyzer/ffi] Fix analyzer crash
TEST=tests/ffi/static_checks/regress_62716_test.dart Fixes: https://github.com/dart-lang/sdk/issues/62716 Change-Id: I8abc006cd1e7274089ea618c970aacd0bc2267e4 Cq-Include-Trybots: luci.dart.try:analyzer-linux-release-try,analyzer-mac-release-try,analyzer-win-release-try,front-end-linux-release-x64-try,front-end-nnbd-linux-release-x64-try,front-end-nnbd-mac-release-x64-try,front-end-nnbd-win-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483241 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com> Auto-Submit: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
committed by
Commit Queue
parent
33e6df1fe9
commit
8852aa5c19
@@ -674,8 +674,13 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
|
||||
// Receiver can only be Pointer if the class extends
|
||||
// NativeFieldWrapperClass1.
|
||||
if (ffiSignature.normalParameterTypes[0].isPointer) {
|
||||
var cls = declarationElement.enclosingElement as InterfaceElement;
|
||||
if (!_extendsNativeFieldWrapperClass1(cls.thisType)) {
|
||||
var enclosingElement = declarationElement.enclosingElement;
|
||||
var receiverType = switch (enclosingElement) {
|
||||
InterfaceElement() => enclosingElement.thisType,
|
||||
ExtensionElement(extendedType: InterfaceType type) => type,
|
||||
_ => null,
|
||||
};
|
||||
if (!_extendsNativeFieldWrapperClass1(receiverType)) {
|
||||
_diagnosticReporter.report(
|
||||
diag.ffiNativeOnlyClassesExtendingNativefieldwrapperclass1CanBePointer
|
||||
.at(errorToken),
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Regression test for https://github.com/dart-lang/sdk/issues/62716
|
||||
|
||||
import 'dart:ffi';
|
||||
import 'dart:nativewrappers';
|
||||
|
||||
extension on int {
|
||||
@Native<Void Function(Pointer<Void>)>(symbol: 'x')
|
||||
// [error column 4]
|
||||
// [cfe] Only classes extending NativeFieldWrapperClass1 can be passed as Pointer.
|
||||
external void x();
|
||||
// ^
|
||||
// [analyzer] COMPILE_TIME_ERROR.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER
|
||||
}
|
||||
|
||||
extension on dynamic {
|
||||
@Native<Void Function(Pointer<Void>)>(symbol: 'z')
|
||||
external void z();
|
||||
// ^
|
||||
// [analyzer] COMPILE_TIME_ERROR.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER
|
||||
// [cfe] Expected type 'void Function(dynamic)' to be 'void Function(Pointer<Void>)', which is the Dart type corresponding to 'NativeFunction<Void Function(Pointer<Void>)>'.
|
||||
}
|
||||
|
||||
extension on void Function() {
|
||||
@Native<Void Function(Pointer<Void>)>(symbol: 'f')
|
||||
external void f();
|
||||
// ^
|
||||
// [analyzer] COMPILE_TIME_ERROR.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER
|
||||
// [cfe] Expected type 'void Function(void Function())' to be 'void Function(Pointer<Void>)', which is the Dart type corresponding to 'NativeFunction<Void Function(Pointer<Void>)>'.
|
||||
|
||||
@Native<Void Function(Handle)>(symbol: 'f2')
|
||||
external void f2();
|
||||
}
|
||||
|
||||
extension on NativeFieldWrapperClass1 {
|
||||
@Native<Void Function(Pointer<Void>)>(symbol: 'y')
|
||||
external void y();
|
||||
}
|
||||
|
||||
void main() {}
|
||||
Reference in New Issue
Block a user