Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 93d5c4e

Browse files
Clement Skaucommit-bot@chromium.org
authored andcommitted
[VM] Adds error for leaf FfiNative w. Handle
This adds an analyzer compile-time error for using Handles with leaf call FfiNatives. This same error already exists in the transforms. (See `_ensureLeafCallDoesNotUseHandles(..)`) Bug: dart-lang/sdk#46625 Change-Id: Iec52d5df6dd346a25ef2976e552cf1cb58c17ff6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207460 Reviewed-by: Tess Strickland <sstrickl@google.com> Commit-Queue: Clement Skau <cskau@google.com>
1 parent 8674c7d commit 93d5c4e

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

pkg/analyzer/lib/src/generated/ffi_verifier.dart

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,26 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
277277

278278
for (Annotation annotation in annotations) {
279279
if (annotation.name.name == _ffiNativeName) {
280+
// All FFI Natives must be static.
280281
final isStatic = (node is FunctionDeclaration) ||
281282
((node is MethodDeclaration) && node.isStatic);
282283
if (!isStatic) {
283284
_errorReporter.reportErrorForNode(
284285
FfiCode.FFI_NATIVE_ONLY_STATIC, node);
285286
}
287+
// Leaf call FFI Natives can't use Handles.
288+
ArgumentList? argumentList = annotation.arguments;
289+
if (argumentList != null) {
290+
NodeList<Expression> arguments = argumentList.arguments;
291+
TypeArgumentList? typeArgumentList = annotation.typeArguments;
292+
if (typeArgumentList != null) {
293+
NodeList<TypeAnnotation> typeArguments = typeArgumentList.arguments;
294+
if (typeArguments.isNotEmpty && typeArguments[0].type != null) {
295+
_validateFfiLeafCallUsesNoHandles(
296+
arguments, typeArguments[0].type!, node);
297+
}
298+
}
299+
}
286300
}
287301
}
288302
}
@@ -530,7 +544,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
530544
_errorReporter.reportErrorForNode(
531545
FfiCode.MUST_BE_A_SUBTYPE, node, [TPrime, F, 'asFunction']);
532546
}
533-
_validateFfiLeafCallUsesNoHandles(node, TPrime, node);
547+
_validateFfiLeafCallUsesNoHandles(node.argumentList.arguments, TPrime,
548+
node);
534549
}
535550
_validateIsLeafIsConst(node);
536551
}
@@ -622,9 +637,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
622637
}
623638
}
624639

625-
void _validateFfiLeafCallUsesNoHandles(
626-
MethodInvocation node, DartType nativeType, AstNode errorNode) {
627-
final args = node.argumentList.arguments;
640+
void _validateFfiLeafCallUsesNoHandles(NodeList<Expression> args,
641+
DartType nativeType, AstNode errorNode) {
628642
if (args.isNotEmpty) {
629643
for (final arg in args) {
630644
if (arg is NamedExpression) {
@@ -817,7 +831,8 @@ class FfiVerifier extends RecursiveAstVisitor<void> {
817831
FfiCode.MUST_BE_A_SUBTYPE, errorNode, [S, F, 'lookupFunction']);
818832
}
819833
_validateIsLeafIsConst(node);
820-
_validateFfiLeafCallUsesNoHandles(node, S, typeArguments![0]);
834+
_validateFfiLeafCallUsesNoHandles(node.argumentList.arguments, S,
835+
typeArguments![0]);
821836
}
822837

823838
/// Validate that none of the [annotations] are from `dart:ffi`.

pkg/analyzer/test/src/diagnostics/ffi_native_test.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,32 @@ class K {
2626
error(FfiCode.FFI_NATIVE_ONLY_STATIC, 31, 75),
2727
]);
2828
}
29+
30+
test_FfiNativeCanUseHandles() async {
31+
await assertErrorsInCode(r'''
32+
import 'dart:ffi';
33+
@FfiNative<Handle Function(Handle)>('DoesntMatter')
34+
external Object doesntMatter(Object);
35+
''', []);
36+
}
37+
38+
test_FfiNativeLeafMustNotReturnHandle() async {
39+
await assertErrorsInCode(r'''
40+
import 'dart:ffi';
41+
@FfiNative<Handle Function()>('DoesntMatter', isLeaf:true)
42+
external Object doesntMatter();
43+
''', [
44+
error(FfiCode.LEAF_CALL_MUST_NOT_RETURN_HANDLE, 19, 90),
45+
]);
46+
}
47+
48+
test_FfiNativeLeafMustNotTakeHandles() async {
49+
await assertErrorsInCode(r'''
50+
import 'dart:ffi';
51+
@FfiNative<Void Function(Handle)>('DoesntMatter', isLeaf:true)
52+
external void doesntMatter(Object o);
53+
''', [
54+
error(FfiCode.LEAF_CALL_MUST_NOT_TAKE_HANDLE, 19, 100),
55+
]);
56+
}
2957
}

0 commit comments

Comments
 (0)