[vm/ffi] Array dimensions non-positive check in CFE
Bug: https://github.com/dart-lang/sdk/issues/45540
Closes: https://github.com/dart-lang/sdk/pull/45785
TEST=tests/ffi/vmspecific_static_checks_test.dart
GitOrigin-RevId: e4c091a617acf36f60de7ddfc957a58323663813
Change-Id: I393e1dbbf34aa9f72e2e942c3a40c2f37c90e0c4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196246
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index b1cb812..eed68f4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -7277,6 +7277,15 @@
r"""Try removing the other directives, or moving them to the library for which this is a part.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeNonPositiveArrayDimensions =
+ messageNonPositiveArrayDimensions;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageNonPositiveArrayDimensions = const MessageCode(
+ "NonPositiveArrayDimensions",
+ message: r"""Array dimensions must be positive numbers.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
templateNonSimpleBoundViaReference =
const Template<Message Function(String name)>(
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index bf01283..b2250cf 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -53,6 +53,7 @@
messageFfiExceptionalReturnNull,
messageFfiExpectedConstant,
messageFfiPackedAnnotationAlignment,
+ messageNonPositiveArrayDimensions,
noLength,
templateFfiDartTypeMismatch,
templateFfiEmptyStruct,
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 23e753f..9c7263d 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -606,6 +606,7 @@
NonNullableOptOutImplicit/example: Fail
NonPartOfDirectiveInPart/part_wrapped_script1: Fail
NonPartOfDirectiveInPart/script1: Fail
+NonPositiveArrayDimensions/analyzerCode: Fail
NotAConstantExpression/example: Fail
NotAType/example: Fail
NotAnLvalue/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index e5d851a..82ad1a1 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -4646,6 +4646,11 @@
<int>[...null];
}
+NonPositiveArrayDimensions:
+ # Used by dart:ffi
+ template: "Array dimensions must be positive numbers."
+ external: test/ffi_test.dart
+
InvalidTypeVariableInSupertype:
template: "Can't use implicitly 'out' variable '#name' in an '#string2' position in supertype '#name2'."
script: >
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 6dc8a46..beed450 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -9,6 +9,7 @@
import 'package:front_end/src/api_unstable/vm.dart'
show
messageFfiPackedAnnotationAlignment,
+ messageNonPositiveArrayDimensions,
templateFfiEmptyStruct,
templateFfiFieldAnnotation,
templateFfiFieldNull,
@@ -323,7 +324,8 @@
compoundClassDependencies[node].add(clazz);
_checkPacking(node, packing, clazz, f);
}
- if (arrayDimensions(type) != sizeAnnotations.single.length) {
+ final dimensions = sizeAnnotations.single;
+ if (arrayDimensions(type) != dimensions.length) {
diagnosticReporter.report(
templateFfiSizeAnnotationDimensions
.withArguments(f.name.text),
@@ -331,6 +333,15 @@
f.name.text.length,
f.fileUri);
}
+ for (var dimension in dimensions) {
+ if (dimension < 0) {
+ diagnosticReporter.report(
+ messageNonPositiveArrayDimensions, f.fileOffset,
+ f.name.text.length,
+ f.fileUri);
+ success = false;
+ }
+ }
} else {
diagnosticReporter.report(
templateFfiSizeAnnotation.withArguments(f.name.text),
@@ -478,8 +489,8 @@
final sizeAnnotations = _getArraySizeAnnotations(m).toList();
if (sizeAnnotations.length == 1) {
final arrayDimensions = sizeAnnotations.single;
- type = NativeTypeCfe(this, dartType,
- compoundCache: compoundCache, arrayDimensions: arrayDimensions);
+ type = NativeTypeCfe(this, dartType, compoundCache: compoundCache,
+ arrayDimensions: arrayDimensions);
}
} else if (isPointerType(dartType) || isCompoundSubtype(dartType)) {
type = NativeTypeCfe(this, dartType, compoundCache: compoundCache);
@@ -749,7 +760,7 @@
abstract class NativeTypeCfe {
factory NativeTypeCfe(FfiTransformer transformer, DartType dartType,
{List<int> arrayDimensions,
- Map<Class, CompoundNativeTypeCfe> compoundCache = const {}}) {
+ Map<Class, CompoundNativeTypeCfe> compoundCache = const {}}) {
if (transformer.isPrimitiveType(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
final nativeType = transformer.getType(clazz);
@@ -772,7 +783,7 @@
}
final elementType = transformer.arraySingleElementType(dartType);
final elementCfeType =
- NativeTypeCfe(transformer, elementType, compoundCache: compoundCache);
+ NativeTypeCfe(transformer, elementType, compoundCache: compoundCache);
return ArrayNativeTypeCfe.multi(elementCfeType, arrayDimensions);
}
throw "Invalid type $dartType";
@@ -1135,8 +1146,8 @@
ArrayNativeTypeCfe(this.elementType, this.length);
- factory ArrayNativeTypeCfe.multi(
- NativeTypeCfe elementType, List<int> dimensions) {
+ factory ArrayNativeTypeCfe.multi(NativeTypeCfe elementType,
+ List<int> dimensions) {
if (dimensions.length == 1) {
return ArrayNativeTypeCfe(elementType, dimensions.single);
}
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index 72636d8..4998b31 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -760,3 +760,24 @@
external Array<TestStruct1604> //# 1606: compile-time error
nestedLooselyPacked; //# 1606: compile-time error
}
+
+class TestStruct1800 extends Struct {
+ external Pointer<Uint8> notEmpty;
+
+ @Array(-1) //# 1800: compile-time error
+ external Array<Uint8> inlineArray; //# 1800: compile-time error
+}
+
+class TestStruct1801 extends Struct {
+ external Pointer<Uint8> notEmpty;
+
+ @Array(1, -1) //# 1801: compile-time error
+ external Array<Uint8> inlineArray; //# 1801: compile-time error
+}
+
+class TestStruct1802 extends Struct {
+ external Pointer<Uint8> notEmpty;
+
+ @Array.multi([2, 2, 2, 2, 2, 2, -1]) //# 1802: compile-time error
+ external Array<Uint8> inlineArray; //# 1802: compile-time error
+}
\ No newline at end of file
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index 48e85b8..a81e206 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -759,3 +759,24 @@
@Array(2) //# 1606: compile-time error
Array<TestStruct1604> nestedLooselyPacked; //# 1606: compile-time error
}
+
+class TestStruct1800 extends Struct {
+ Pointer<Uint8> notEmpty;
+
+ @Array(-1) //# 1800: compile-time error
+ Array<Uint8> inlineArray; //# 1800: compile-time error
+}
+
+class TestStruct1801 extends Struct {
+ Pointer<Uint8> notEmpty;
+
+ @Array(1, -1) //# 1801: compile-time error
+ Array<Uint8> inlineArray; //# 1801: compile-time error
+}
+
+class TestStruct1802 extends Struct {
+ Pointer<Uint8> notEmpty;
+
+ @Array.multi([2, 2, 2, 2, 2, 2, -1]) //# 1802: compile-time error
+ Array<Uint8> inlineArray; //# 1802: compile-time error
+}
\ No newline at end of file